上传文件方面:

一、前端

使用的是jQuery框架来上传图片,参考的是harttle大神博客:http://harttle.com/2016/07/04/jquery-file-upload.html,利用formdata来封装图片传到后台,代码如下:

$('button').click(function(){
var files = $('#avatar').prop('files'); var data = new FormData();
data.append('avatar', files[0]); $.ajax({
url: '/api/upload',
type: 'POST',
data: data,
cache: false,
processData: false,
contentType: false
});
});

二、后端

采用的是SpringMVC框架,在读取这个formdata时比较头疼,不知道怎么读,通过搜索发现有人用了MultipartHttpServletRequest这样一样请求类来读上传的formdata内容,不禁感慨这么多类我要用到什么时候才能熟练掌握,参考链接:

http://www.tuicool.com/articles/2EnMBz

@RequestMapping(value = "/upload")
public@ResponseBody String upload(MultipartHttpServletRequest request) throws Exception {
Iterator<String> itr = request.getFileNames();
MultipartFile mpf = request.getFile(itr.next()); ufile = new UploadedFile(mpf.getBytes(), mpf.getOriginalFilename(), mpf.getContentType(),
mpf.getBytes().length);
String name = "default";
String type = "jpg";
if (ufile.name.contains(".")) {
String[] names = ufile.name.split("\\.");
name = names[0];
type = names[1];
}
String imagePath = "http://" + request.getServerName() + ":" + request.getServerPort() + "/user/image/" +
name + "/" + type;
return imagePath;
}

其中这个UploadedFile是自己定义的一个封装内部类,代码:

    private class UploadedFile {
byte[] bytes;
int length;
String type;
String name; public UploadedFile() {
} public UploadedFile(byte[] bytes, String name, String type, int length) {
this.bytes = bytes;
this.name = name;
this.type = type;
this.length = length;
File file = new File(Constant.IMGDIR + name);
if (file.exists()) {
file.delete();
}
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(this.bytes, 0, this.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

MultipartHttpServletRequest这个类可以获取上传文件的字节流getBytes(),文件名getOriginalFilename(),文件类型getContentType()等信息。

本来想将图片文件名作为参数返回到链接中,但是发现在读取时会从"."分割,所以自己就想办法把图片的文件名分成两部分,在以"."分割时还报了个错,原因是java以"."分割时要写成split("\\.")。

读取图片方面

本来想偷懒直接用之前写过的代码:http://www.cnblogs.com/puyangsky/p/5390263.html

初始代码如下:

 @RequestMapping(value = "/image/{name}/{type}", method = RequestMethod.GET)
public void getImage(@PathVariable String name,
@PathVariable String type,
HttpServletResponse response) throws IOException{ InputStream inputStream = null;
OutputStream out = null;
try {
File file = new File("D:\\image\\" + name + "." + type);
inputStream = new FileInputStream(file);
out = response.getOutputStream();
// pic size = 1M
byte[] bytes = new byte[5 * 1024 * 1024];
int len = 0;
while ((len = inputStream.read(bytes)) > 0) {
out.write(bytes, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null)
inputStream.close();
if (out != null)
out.close();
}
}

直接利用java IO来读取图片,并将字节流写到response的outputstream中。

在windows上测试完美通过,但是放到linux服务器上之后每次读取图片都会报错,错误是java.net.socketexception:broken pipe,错误定位就在这个getImage方法中。

果断懵逼,没遇过这样的问题,一番搜索后,看到这样一个帖子:http://bbs.csdn.net/topics/390360405

在里面有人说要用java的NIO来实现,继续懵逼,NIO又是什么,无所谓先把bug解决了再好好了解,继续搜索发现有一个ImageIO的包是使用了NIO实现的,修改代码,完美解决问题,最后的getImage方法的代码如下:

    @RequestMapping(value = "/image/{name}/{type}", method = RequestMethod.GET)
public void getImage(@PathVariable String name,
@PathVariable String type,
HttpServletResponse response) throws IOException{
OutputStream out = null;
BufferedImage image = null;
try {
File file = new File(Constant.IMGDIR + name + "." + type); image = ImageIO.read(file);
out = response.getOutputStream();
ImageIO.write(image, type, out); } catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null)
out.close();
}
}

而且ImageIO的方法封装的非常好,直接三行把图片输出到response的输出流中。

感想

java中的细节太多,一方面是需要慢慢积累,另一方面基础知识也要打好,感觉自己连java IO都没弄熟悉,碰到什么NIO就更一脸蒙蔽了,之后也会写一些记录学习IO和NIO的博客。

【java NIO】服务器端读写图片的一次排错经历的更多相关文章

  1. Java NIO服务器端开发

    一.NIO类库简介 1.缓冲区Buffer Buffer是一个对象,包含一些要写入和读出的数据. 在NIO中,所有的数据都是用缓冲区处理的,读取数据时,它是从通道(Channel)直接读到缓冲区中,在 ...

  2. java中快速读写图片到BufferedImage对象

    java7读取文件到BufferedImage对象 BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get( ...

  3. java nio 缓冲区读写数据(图形详解)

    Position 您可以回想一下,缓冲区实际上就是美化了的数组.在从通道读取时,您将所读取的数据放到底层的数组中. position 变量跟踪已经写了多少数据.更准确地说,它指定了下一个字节将放到数组 ...

  4. 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射

    内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileC ...

  5. java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射

    java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果文件超大的话,更快的方式是采用MappedByteBuffer. Mapped ...

  6. Java NIO浅析

    NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接 ...

  7. Java Se : Java NIO(服务端)与BIO(客户端)通信

    Java目前有三种IO相关的API了,下面简单的说一下: BIO,阻塞IO,最常用的Java IO API,提供一般的流的读写功能.相信学习Java的人,都用过. NIO,非阻塞IO,在JDK1.4中 ...

  8. JAVA:NIO初步了解

    简介: Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式. Java NIO: Ch ...

  9. Java NIO教程 前言

    阅读本文前,建议你先了解 旧I/O NIO 是 New I/O 的缩写,要了解它真正的内涵,需要掌握的知识还是比较多的.我努力在这几篇笔记里,勾勒出整个io的面貌.为大家的深入学习铺路. I/O简史 ...

随机推荐

  1. CSS hack浏览器兼容一览表

    CSS hack是指我们为了兼容各浏览器,而使用的特别的css定义技巧.这是国外摘来的一张CSS hack列表,显示了各浏览器对css hack的支持程度,对我们制作兼容网页非常有帮助.

  2. 【BZOJ】1598: [Usaco2008 Mar]牛跑步

    [题意]给定有向图,边严格从大编号指向小编号,求前k短路.n<=1000,m<=10000,k<=100. [算法]归并+拓扑排序||A*求第k短路 [题解]因为此题自带拓扑序的特殊 ...

  3. Spring的使用优点

    spring事物配置,声明式事务管理和基于@Transactional注解的使用 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务管理使用TransactionTemplate或者 ...

  4. UITableView---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址  //转载请注明出处--本文永久链接:http://www.cnblogs.com/C ...

  5. Spring归纳小结(山东数漫江湖)

    前言 如果说有什么框架是Java程序员必然会学习.使用到的,那么Spring肯定是其中之一.本篇博客,将根据博主在日常工作中对Spring的使用做一个系统的归纳小结. Spring的一些概念和思想 S ...

  6. HDU 1234 开门人和关门人 (模拟)

    题目链接 Problem Description 每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签  到.签离记录,请根据记录找出当天开门和关门的人.    Input ...

  7. vs调试 配置IISExpress允许局域网内部访问

    内网可访问后,本机不能使用localhost   1.找到IISExpress的配置文件,位于 <文档>/IISExpress/config文件夹下,打开applicationhost.c ...

  8. hdu 1070 Milk(贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1070 Milk Time Limit: 2000/1000 MS (Java/Others)    M ...

  9. O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素(转)

    题目要求:定义栈的数据结构,添加min().max()函数(动态获取当前状态栈中的最小元素.最大元素),要求push().pop().min().max()的时间复杂度都是O(1). 思路解析:根据栈 ...

  10. 【shell】shell中各种括号的作用()、(())、[]、[[]]、{}

    一.小括号,圆括号() 1.单小括号 ()    ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有 ...