SpringMVC文件上传

本文介绍了如何通过不同的技术栈(如Servlet、SpringMVC)来判断HTTP请求中是否包含文件,并详细讲解了multipart/form-data编码格式及其实现原理。同时提供了手动解析文件流的方法和示例代码。

如何判断接收到的request中是否包含文件?

form表单的enctype属性指明在将数据发送给服务器之前使用何种方式对将要发送的数据编码。

application/x-www-form-urlencoded 是默认的编码方式

multipart/form-data 不对字符编码

text/plain 空格转换为 "+" 加号,但不对特殊字符编码

理解multipart/form-data数据格式

以这种格式提交数据时,浏览器会将字符串和文件当作一整个字节流发送到服务器

通过特定的标记分隔开

不同的input之间的数据有一个分隔符,此分割符不是固定的,请求头包含该分隔符的信息

一个input框中的数据,会以 ‘\r\n’分隔,如果input是text类型的,其中会包含name和具体的值

如果是file类型的会包含filename,文件格式的信息,之后就是文件的字节流信息;

混合表单提交是post提交演变而来的,参考博客https://www.cnblogs.com/tylerdonet/p/5722858.html

手动获取并解析客户端发送过来的数据流

参考:http://blog.youkuaiyun.com/Chengyajie521/article/details/40888903

通过request对象的getInputStream()方法获取数据流,以multipart/form-data格式提交的数据是无法直接使用getParameter()方法获取字符串参数的,除非已经使用其他工具对request解析过了,使用getParameter()方法成功后,也就无法通过getInputStream()获取数据流了。

InputStream.read()方法的返回类型是int,该方法一次读取一个字节,Java中

byte占一个字节,有正负,范围是[-128、127]

short占二个字节

char占二个字节,Java使用Unicode编码

int占四个字节

long占八个字节

而InputStream.read()方法返回的是一个unsigned byte [0 - 255],无法用byte接收

 

获取数据流的编码方式

在http://blog.youkuaiyun.com/Chengyajie521/article/details/40888903中的方法,无法读取中文文件名,

因该使用UTF-8的编码去解析字符串

如何获取request中的文本和文件?

1.servlet文件上传

//使用commons-fileupload组件
//需引入commons-fileupload.jar和commons-io.jar
//判断是否包含文件
ServletFileUpload.isMultipartContent(request);

 // 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 设置临时存储目录
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
 
ServletFileUpload upload = new ServletFileUpload(factory);
         
// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);
         
// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);

// 中文处理
upload.setHeaderEncoding("UTF-8"); 

//获取request中的文件
List<FileItem> formItems = upload.parseRequest(request);

2.SpringMVC文件上传

//将request转换成MultipartHttpServletRequest
//前提是必须是以混合表单形式提交,否则报错
//form表单设置属性enctype="multipart/form-data"
//异步提交可使用jQuery.form.js的ajaxSubmit()方法
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Iterator fileNames = multipartRequest.getFileNames();//可以上传一张也可以上传多张图片

//遍历获取文件
for (int i = 0; fileNames.hasNext(); ++i) {
     //form表单input标签name属性,表单中file框的name属性不能少,否则此处报错
     String name = (String) fileNames.next();
     MultipartFile myfile = multipartRequest.getFile(name);
     //原文件名
     String OriginalFileName = myfile.getOriginalFilename();
     //判断文件是否为空
     myfile.isEmpty();
     //获取输入流
     myfile.getInputStream();
}

SpringMVC文件上传注意事项:表单中file框的name属性不能少

判断request是否是MultipartHttpServletRequest

// 创建一个通用的多部分解析器.  
CommonsMultipartResolver commonsMultipartResolver = new 
    CommonsMultipartResolver(request.getSession().getServletContext());  
// 设置编码  
commonsMultipartResolver.setDefaultEncoding("utf-8");  
// 判断是否有文件上传  
if (commonsMultipartResolver.isMultipart(request)) {//有文件上传  

    //将request变成多部分request  
    MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;  
      
    //获取multiRequest 中所有的文件名  
    Iterator<String> iter=multiRequest.getFileNames();  
      
    while (iter.hasNext()) {  
        MultipartFile imageFile = multiRequest.getFile(iter.next().toString());
    }

 

转载于:https://my.oschina.net/u/3160411/blog/1510711

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值