在做項目中,使用了spring boot 的文件上傳功能,但當(dāng)上傳的文件超出指定大小時,報以下錯誤.
2019-04-23 22:08:33.930 [XNIO-2 task-10] ERROR [ExceptionHandlerAdvice:66] - 文件上傳超出大小
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: io.undertow.server.RequestTooBigException: UT000020: Connection terminated as request was larger than 20971520
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.handleParseFailure(StandardMultipartHttpServletRequest.java:122) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:113) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:86) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:91) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1128) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:960) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) [undertow-servlet-1.4.25.Final.jar:1.4.25.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) [undertow-servlet-1.4.25.Final.jar:1.4.25.Final]
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) [shiro-core-1.4.0.jar:1.4.0]
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) [shiro-core-1.4.0.jar:1.4.0]
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387) [shiro-core-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) [shiro-web-1.4.0.jar:1.4.0]
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) [shiro-web-1.4.0.jar:1.4.0]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) [undertow-servlet-1.4.25.Final.jar:1.4.25.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.4.25.Final.jar:1.4.25.Final]
此時,后臺異常,但前臺報錯,沒辦法捕捉到相關(guān)異常.
但系統(tǒng)已經(jīng)有了一個全局的異常捕捉,代碼有進(jìn)入,但沒有正常返回給前端.
@ExceptionHandler(MultipartException.class)
@ResponseBody
public ErrorResponseData handleAll(MultipartException t){
logger.error("文件上傳超出大小", t);
return ErrorResponseData.newInstance(HttpCode.PRECONDITION_FAILED, "文件超過指定大小");
}
經(jīng)測試,出錯時,進(jìn)入了該異常處理兩次,導(dǎo)致無法正常返回給前端.
解決辦法需要調(diào)整相關(guān)配置,max-request-size不允許為空,且需要遠(yuǎn)大于max-file-size的配置
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 1000MB
調(diào)整配置后,上傳正常,當(dāng)超出大小時,前端有正常的返回值.當(dāng)然,如果附件超過 1000MB,還是存在原來的問題.
別提醒一下,該方法適用于spring boot 2.0并使用undertow,如果使用spring boot 1.5及tomcat的,上述方法不頂用,具體解決辦法,下篇繼續(xù).