spring mvc上传文件超过设定大小异常处理客户端无响应:请求的连接被重置

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;

	}




猜你喜欢

转载自blog.csdn.net/w47_csdn/article/details/76422357