这两天在用spring进行上传上遇到问题,今天进行了问题的排查,这个过程也增长了我看spring源码的兴趣!仍是颇有收获的!html
首先先给A组提供了上传接口,并无在spring的配置文件进行multipartResolver的配置,后台Controller的java的获取为:java
/**web
*Saves temporary files to the servlet container's temporary directory. Needs to be initialized either by an application context or via the constructor that takes a ServletContext (for standalone usage).一个是Spring容器(Servlet容器的子容器),另外一个是Servlet容器spring
*/app
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile file = multipartRequest.getFile("file");
String a1 = multipartRequest.getParameter("a1");测试
将request请求的上下文转换为MultipartResolver,而后转换为MultipartHttpServletRequest请求,经过multi请求就能够获取对应的file文件信息,这样的方法没有问题,后台能获取到相应的参数;spa
稍后组里另外一个同事也用到上传,基于网上查的资料,认为应该把配置文件给加上去了,因而问题出来了,也形成了我记录该博客的缘由:code
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- set the max upload size100MB -->
<property name="maxUploadSize">
<value>10485760000</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>htm
进行该配置后,我在后台的该方法获取file为空形成了上传错误,刚开始我也纳闷,按道理spring的上传应该须要这样的配置,同事也是以为我大意了没有进行配置好心给我进行了修改,可是反而形成了bug,线下环境测试将该配置去除功能ok。好了,作了这么多年开发,不能由于fixed bug而不进行原理的问题查看,这样的修改连本身都过不去。blog
搜了资料,作了测试,有了如下的总结,有问题欢迎你们拍砖!
最后上传问题的方案:
(一):
一、在spring-config配置了<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 以后
后台的获取有两种方法:
一、指定@RequestParam MultipartFile file 例如:public Map<String, Object> logsUpload(@RequestParam MultipartFile file,@RequestParam(value="key") String key)参数;
二、将request转化为MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)(request);
原理是:使用spring的CommosMultipartResolver 配置MultipartResolver 用于文件上传,DispatcherServlet 将调用 MultipartResolver 的 isMultipart(request) 方法检查当前 Web 请求是否为 multipart类型。若是是,DispatcherServlet 将调用 MultipartResolver 的 resolveMultipart(request) 方法,对原始 request 进行装饰,并返回一个 MultipartHttpServletRequest 供后继处理流程使用(最初的 HttpServletRequest 被偷梁换柱成了 MultipartHttpServletRequest),不然,直接返回最初的 HttpServletRequest。也就是说请求一旦被 MultipartResolver 接手,它就会解析请求中的文件,而没必要等待后续 controller 主动从 MultipartRequest 中 getFile,因此在配置了MultipartResolver后,再经过这样的方法
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
是获取不到file的,由于控制器已经帮咱们进行了转换 直接获取便可。
若是你使用该方法发觉获取没有问题,你能够看看给这个方法是否是配置了servlet,若是配置了servlet是不走这个 MultipartResolver控制,是能获取成功的。
(二)
无需进行spring-config的配置,直接在后台获取进行转换便可,也就是我最初的写法。
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile file = multipartRequest.getFile("file");
String key = multipartRequest.getParameter("key");
而后项目具体须要什么样的修改,本身结合业务斟酌便可。
本身讲的不深,看了不少文章资料,也是这篇给的启迪最大:
http://exceptioneye.iteye.com/blog/1314958