源码剖析CommonsMultipartResolver解释parseRequest无法获得FileItem
来源:互联网 发布:cad软件全称 编辑:程序博客网 时间:2024/06/06 23:53
相信在Javaweb做文件上传的时候大家都用到commons-fileupload这个组件,使用这个组件实现文件上传时都会用到这句代码List<FileItem> list = servletFileUpload.parseRequest(request);
,意思是解析从客户端发送到服务器的request请求(Form表单)得到一个FileItem的List集合,这样每个FileItem都可以简单地通过封装好的方法获得文件名,文件信息等。但是一旦处理不慎就会出现List.size()为0的问题,即解析后得不到FileItem。
琢磨了很久我才知道,之所以之前commons-fileupload能上传但后来又不能上传,是因为后来我在配置文件中注入了一个叫做CommonsMultipartResolver的组件。注入这个组件是因为在项目其他地方要用到MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
,只有注入了这个组件,request强制转换为MultipartHttpServletRequest才不会报错。
这样说来,没有引入CommonsMultipartResolver前,commons-fileupload通过servletFileUpload.parseRequest(request)将request解析了,能得到FileItem集合。引入CommonsMultipartResolver之后,进行同样的解析得不到FileItem集合了。那只有一个原因,就是前后request对象变了。下面就来debug查看前后request对象的区别:
没有引入CommonsMultipartResolver前:
引入CommonsMultipartResolver后:
对比前后可见,request对象确实不一样。那CommonsMultipartResolver究竟做了什么?
打开CommonsMultipartResolver源码:
protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { String encoding = this.determineEncoding(request); FileUpload fileUpload = this.prepareFileUpload(encoding); try { List ex = ((ServletFileUpload)fileUpload).parseRequest(request); return this.parseFileItems(ex, encoding); } catch (SizeLimitExceededException var5) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), var5); } catch (FileUploadException var6) { throw new MultipartException("Could not parse multipart servlet request", var6); } }
从源码可以看到:CommonsMultipartResolver本身就依赖于commons-fileupload这个包,自己也有一个叫做parseRequest的方法,这个方法调用了commons-fileupload包里FileUpload的parseRequest方法。
现在知道原因了,原来CommonsMultipartResolver这个组件会检测从客户端来的request,若是multipart/form-data数据就会自动将其用common-fileupload的parseRequest方法进行解析。因此引入这个组件后,想再通过List<FileItem> list = servletFileUpload.parseRequest(request);
解析得到FileItem是不可能的,此前已经解析过一次了,再解析当然为空。
解决方案:
不要再使用List<FileItem> list = servletFileUpload.parseRequest(request);
这个方法得到FileItem的List(之后遍历这个List获取Form表单的数据)。
既然CommonsMultipartResolver已经帮我们解析了,那就直接用:
if(!ServletFileUpload.isMultipartContent(request)){ //如果上传的数据不是表单原始的数据(经过编码),则直接返回。因为只有表单原始数据才会被接收 //http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean return; } MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; dynamicsText = multipartRequest.getParameter("dynamicsText");//获取表单文本部分 MultipartFile multipartFile = multipartRequest.getFile("dynamicsFile");//获取表单 String savePath = request.getSession().getServletContext().getRealPath("/") + "user_space/"+userId; File file = new File(savePath); if (!file.exists() && !file.isDirectory()) { file.mkdirs();//新建文件夹(多重) } dynamicsFile = multipartFile.getOriginalFilename(); multipartFile.transferTo(new File(savePath+"/"+dynamicsFile));
如有问题或补充,请大家在评论中尽管提,共同交流^~^。
- 源码剖析CommonsMultipartResolver解释parseRequest无法获得FileItem
- FileItem
- FileItem
- 《stl源码剖析》剖析
- FileItem类
- FileItem详解
- FileItem类
- FileItem类
- FileItem类
- FileItem类
- FileItem类
- FileItem类
- FileItem类
- FileItem类
- 关于FileItem
- FileItem类
- FileItem类
- FileItem类
- 戏说春秋一东施效颦
- File类中mkdir()和mkdirs()的区别
- mark~
- 利用vim查看日志,快速定位问题
- FreeRTOS 与 LWIP 开发笔记
- 源码剖析CommonsMultipartResolver解释parseRequest无法获得FileItem
- 项目初始化时执行的功能
- loadrunner运行时出现80端口被占用的问题
- 用集合框架实注册和登陆
- C语言习题整理
- Hive 脚本执行
- 《c和指针》(一)
- 附带文件操作的通讯录,可以实现链表到文件的写入以及文件到链表的读取
- 戏说春秋一大义灭亲