Spring Boot: ClassNotFoundException when configuring maxUploadSize of CommonMultipartResolver
我正在将Spring Boot用于我的Web应用程序,并且试图配置Spring的CommonMultipartResolver的maxUploadSize。当前,它似乎受Spring(?)默认大小1 MB的限制。上传是通过REST接口完成的,方法签名如下所示:
1 2 | @RequestMapping(value ="/upload", method = RequestMethod.POST) public void uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) |
每当我尝试上传更大的文件时,都会引发FileSizeLimitExceededException:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes. at org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl$FileItemStreamImpl$1.raiseError(FileUploadBase.java:637) at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.checkLimit(LimitedInputStream.java:76) at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:135) at java.io.FilterInputStream.read(FilterInputStream.java:107) at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:99) at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:68) at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:296) at org.apache.catalina.connector.Request.parseParts(Request.java:2737) at org.apache.catalina.connector.Request.parseParameters(Request.java:3096) at org.apache.catalina.connector.Request.getParameter(Request.java:1145) at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:382) at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:140) at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:140) at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:140) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:70) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:109) at org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:59) at org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:101) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:744) |
我尝试过但未成功的事情:
设置Tomcat属性
由于我的Web应用程序正在Tomcat上运行(不是嵌入式程序,而是单独的外部程序),因此我尝试通过更改Tomcat配置来配置大小,如此处所述。不幸的是,这没有效果,因为最大上传大小仍保持为1 MB。
通过注释配置Spring的CommonMultipartResolver
由于1MB的值似乎来自CommonMultipartResolver(我可以看到调试时设置了1MB的值),因此我尝试通过如下注释来配置Spring:
1 2 3 4 5 6 7 8 9 10 11 | @Configuration public class CoreConfig { @Bean public CommonsMultipartResolver commonsMultipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(50 * 1024 * 1024); return multipartResolver; } } |
但是,当我启动Tomcat时,会引发以下异常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Caused by: java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory at myapp.server.CoreConfig.commonsMulipartResolver(CoreConfig.java:40) at myapp.server.CoreConfig$$EnhancerBySpringCGLIB$$8b64a88.CGLIB$commonsMulipartResolver$3(<generated>) at myapp.server.CoreConfig$$EnhancerBySpringCGLIB$$8b64a88$$FastClassBySpringCGLIB$$ac8c6ee5.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312) at myapp.server.CoreConfig$$EnhancerBySpringCGLIB$$8b64a88.commonsMulipartResolver(<generated>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166) ... 27 common frames omitted Caused by: java.lang.ClassNotFoundException: org.apache.commons.fileupload.FileItemFactory at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571) |
通过XML进行配置
我没有通过注释驱动的配置,而是通过XML尝试了类似于此发布的配置,但是我得到了与上述相同的ClassNotFoundException。
附加信息
Spring Boot Starter 1.1.9
的Tomcat 7.0.54
服务器的Pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>mygroup</groupId> myapp.server</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <parent> <groupId>org.springframework.boot</groupId> spring-boot-starter-parent</artifactId> <version>1.1.9.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.google.guava</groupId> guava</artifactId> <version>17.0</version> </dependency> <dependency> <groupId>org.ini4j</groupId> ini4j</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> spring-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>joda-time</groupId> joda-time</artifactId> </dependency> </dependencies> <properties> <start-class>myapp.server.Application</start-class> </properties> <build> <plugins> <plugin> maven-compiler-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> maven-war-plugin</artifactId> </plugin> <plugin> <groupId>org.springframework.boot</groupId> spring-boot-maven-plugin</artifactId> </plugin> </plugins> <finalName>${artifactId}</finalName> </build> <repositories> <repository> <id>spring-releases</id> <url>http://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <url>http://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project> |
您正在使其变得复杂。
只需将
1 | spring.http.multipart.maxFileSize=10MB |
《 Spring Boot参考指南》中有关文件上传的部分对此进行了说明。
对于所有属性,请检查
1 2 3 4 5 6 7 | @Bean MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize("5120MB"); factory.setMaxRequestSize("5120MB"); return factory.createMultipartConfig(); } |
尝试将其添加到定义bean的类中。
对于spring-boot 1.5.3,您应该在application.yml中使用以下代码
1 2 3 4 5 | spring: http: multipart: max-file-size: 10MB max-request-size: 10MB |
对于Spring Boot 2.0+,请使用spring.servlet而不是spring.http
1 2 | spring.servlet.multipart.max-file-size=30MB spring.servlet.multipart.max-request-size=30MB |