web-dev-qa-db-fra.com

Spring Boot: exception à la classe lors de la configuration de maxUploadSize de CommonMultipartResolver

J'utilise Spring Boot pour mon application Web et j'essaie de configurer le maxUploadSize de CommonMultipartResolver de Spring. Actuellement, il semble être limité par une taille par défaut Spring (?) De 1 Mo. Le téléchargement s'effectue via une interface REST, et la signature de la méthode se présente comme suit:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public void uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request)

Chaque fois que j'essaie de télécharger un fichier plus volumineux, une exception FileSizeLimitExceededException est levée:

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)

Choses que j'ai essayées mais qui n'ont pas fonctionné

Définition des propriétés de Tomcat

Étant donné que mon application Web est exécutée sur Tomcat (et non sur la version intégrée, mais sur une application externe distincte), j'ai essayé de configurer la taille en modifiant la configuration de Tomcat de la manière décrite ici . Malheureusement, cela n’a aucun effet, car la taille maximale du téléchargement reste de 1 Mo.

Configuration de CommonMultipartResolver de Spring par annotation

Comme la valeur de 1 Mo semble provenir du CommonMultipartResolver (je peux voir que la valeur de 1 Mo est définie lors du débogage), j'ai essayé de configurer Spring via une annotation comme ceci:

@Configuration 
public class CoreConfig {

    @Bean
    public CommonsMultipartResolver commonsMultipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(50 * 1024 * 1024);
    return multipartResolver;
    }

}

Mais lorsque je lance Tomcat, l'exception suivante est levée:

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)

Configuration via XML

Au lieu d'une configuration basée sur les annotations, j'ai essayé une configuration via XML similaire à this posting , mais j'obtiens la même exception ClassNotFoundException que ci-dessus.

Information additionnelle

Spring Boot Starter 1.1.9

Tomcat 7.0.54

Pom.xml du serveur

<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>
    <artifactId>myapp.server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.1.9.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>17.0</version>
        </dependency>
        <dependency>
            <groupId>org.ini4j</groupId>
            <artifactId>ini4j</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <start-class>myapp.server.Application</start-class>
    </properties>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>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>
12
Jim Holden

Vous faites le chemin à complexe.

Il suffit d’ajouter spring.http.multipart.maxFileSize à votre fichier application.properties et le tour est joué. Pas besoin d'utiliser xml ou de définir explicitement une MultipartResolver.

spring.http.multipart.maxFileSize=10MB   

Ceci est expliqué dans la section sur les téléchargements de fichiers dans le Guide de référence du démarrage du printemps .

Pour toutes les propriétés, vérifiez la classe MultipartProperties . Les autres propriétés prises en charge sont spring.http.multipart.location, spring.http.multipart.maxRequestSize et spring.http.multipart.fileSizeThreshold.

La variable ClassNotFoundException est due au fait que Spring Boot utilise la prise en charge par défaut de Servlet 3.0 pour les téléchargements de fichiers, PAS NOT commons-fileupload. Donc, si vous voulez utiliser cela, vous devrez ajouter explicitement la dépendance. Et bien sûr, les propriétés spring.http.multipart.* ne fonctionnent plus dans ce cas.

53
M. Deinum
@Bean
MultipartConfigElement multipartConfigElement() {
    MultipartConfigFactory factory = new MultipartConfigFactory();
    factory.setMaxFileSize("5120MB");
    factory.setMaxRequestSize("5120MB");
    return factory.createMultipartConfig();
}

Essayez d’ajouter ceci dans la classe où vous définissez les haricots.

3
Ashutosh Jha

Avec spring-boot 1.5.3, vous devez utiliser le code suivant dans application.yml

spring:
 http:
  multipart:
   max-file-size: 10MB
   max-request-size: 10MB
1
Teebo

pour Spring Boot 2.0+, utilisez spring.servlet au lieu de spring.http

spring.servlet.multipart.max-file-size=30MB
spring.servlet.multipart.max-request-size=30MB
0
mayank12001