controller类:
@RequestMapping(path = "/file", method = RequestMethod.POST) public UploadMsg uploadFile(@RequestParam("uploadFile") MultipartFile file, String userCode) throws Exception { String fileId = genFileId(); saveFileToSystem(file, fileId); UploadMsg uploadMsg = getUploadMsg(userCode, fileId, file.getSize()); return uploadMsg; } @ExceptionHandler(MaxUploadSizeExceededException.class) public ResponseEntity<String> handleException(MaxUploadSizeExceededException ex) { System.out.println("=====================" + ex.getClass().getName()); return ResponseEntity.ok("ok"); }
spring配置文件配置文件大小不能超过1M
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <property name="maxUploadSize" value="#{1*1024*1024}"/> <property name="resolveLazily" value="true"/> </bean>
下面是我用小于1M的文件访问时的情况
这是上传失败的情况
下面是我的日志打印情况
扫描二维码关注公众号,回复:
445189 查看本文章
22:40:28,569 DEBUG http-apr-8080-exec-5 support.DefaultListableBeanFactory:251 - Returning cached instance of singleton bean 'uploadFileController' =====================org.springframework.web.multipart.MaxUploadSizeExceededException 22:40:28,574 WARN http-apr-8080-exec-5 commons.CommonsMultipartResolver:194 - Failed to perform multipart cleanup for servlet request org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 1048576 bytes exceeded; nested exception is org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (6145455) exceeds the configured maximum (1048576) at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:162) at org.springframework.web.multipart.commons.CommonsMultipartResolver$1.initializeMultipart(CommonsMultipartResolver.java:134) at org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest.getMultipartFiles(AbstractMultipartHttpServletRequest.java:126) at org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest.getMultiFileMap(AbstractMultipartHttpServletRequest.java:106) at org.springframework.web.multipart.commons.CommonsMultipartResolver.cleanupMultipart(CommonsMultipartResolver.java:191) at org.springframework.web.servlet.DispatcherServlet.cleanupMultipart(DispatcherServlet.java:1107) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869) at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:106) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:141) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) Caused by: org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (6145455) exceeds the configured maximum (1048576) at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:968) at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310) at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:334) at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115) at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:158) ... 35 more
=====================org.springframework.web.multipart.MaxUploadSizeExceededException
这句是我在@ExceptionHandler(MaxUploadSizeExceededException.class)注解的方法中打印的。
解决方案:
当看到这文章的时候相信你现在应该遇到这样的问题了,我也是自己遇到了后来找到解决方案了记录下来,如果下次遇到就可以直接解决了。
至于为什么会出现这样的情况,可以看这篇文章:https://bz.apache.org/bugzilla/show_bug.cgi?id=57438
在文章中说明了这可能是tomcat服务器的bug问题,而非Spring MVC框架问题,如果使用tomcat7.0.39版本的话,这个问题就不存在了。
所以针对Spring MVC文件上传大小限制出现的这个问题,可以换用tomcat7.0.39版本的tomcat服务器;或者使用另一种思路:
首先,把maxUploadSize 设置大一点,让它不会抛异常出来,配置如下:
<!-- 多部分文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大上传大小,不能超过40M @see #FileUploadInterceptor -->
<property name="maxUploadSize" value="41943040"/>
<property name="maxInMemorySize" value="4096"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
或者不使用Spring MVC提供的文件上传大小限制属性<property name="maxUploadSize" value="5242880" /> 配置如下:
<!-- 配置文件上传类型解析器 multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
然后创建一个拦截器控制上传大小,然后抛出同样的异常出来,或者也可以直接在拦截器中处理异常。
public class FileUploadInterceptor implements HandlerInterceptor { private long maxSize; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(request!=null && ServletFileUpload.isMultipartContent(request)) { ServletRequestContext ctx = new ServletRequestContext(request); long requestSize = ctx.contentLength(); if (requestSize > maxSize) { throw new MaxUploadSizeExceededException(maxSize); } } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } public void setMaxSize(long maxSize) { this.maxSize = maxSize; } }
然后在spring-mvc.xml中配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.lvrounet.peiniang.interceptor.FileUploadInterceptor">
<property name="maxSize" value="4194304"/>
</bean>
<mvc:interceptor>
</mvc:interceptors>
这样就可以完成在Spring MVC环境下文件上传大小的限制以及异常正确捕获了。
在Controller类中进行异常捕捉或定义全局异常捕捉(略):
@ExceptionHandler public ModelAndView handleException(Exception ex, HttpServletRequest request, HttpServletResponse response) throws IOException { // 处理文件上传过大异常 if (ex instanceof MaxUploadSizeExceededException) { ex.printStackTrace(); long maxSize = ((MaxUploadSizeExceededException) ex).getMaxUploadSize(); logger.error("File size can’t exceed " + maxSize / (1024*1024) + "M", ex); CommonResult result = new CommonResult(); result.setResult(2); result.setErrormsg("File size can’t exceed " + maxSize / (1024*1024) + "M"); response.setHeader("Content-type", "text/html;charset=UTF-8"); response.getWriter().write(result.toString()); } return null; }