복붙노트

[SPRING] Spring 부트 : CommonMultipartResolver의 maxUploadSize를 구성 할 때 ClassNotFoundException이 발생합니다.

SPRING

Spring 부트 : CommonMultipartResolver의 maxUploadSize를 구성 할 때 ClassNotFoundException이 발생합니다.

내 웹 응용 프로그램 용 Spring Boot를 사용하고 있으며 Spring의 CommonMultipartResolver의 maxUploadSize를 구성하려고합니다. 현재는 1MB의 기본 크기 인 Spring (?)에 의해 제한되는 것으로 보입니다. 업로드는 REST 인터페이스를 통해 수행되며 메소드 서명은 다음과 같습니다.

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

더 큰 파일을 업로드하려고 할 때마다 FileSizeLimitExceededException이 발생합니다.

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 (포함 된 것이 아니라 별도의 외부 웹)에서 실행되기 때문에 여기에서 설명한대로 Tomcat 구성을 변경하여 크기를 구성하려고 시도했습니다. 최대 업로드 크기가 여전히 1MB로 남아 있기 때문에 불행하게도 이것은 아무런 효과가 없습니다.

1MB의 값은 CommonMultipartResolver에서 나온 것 같습니다 (디버깅 할 때 1MB의 값이 설정되었음을 알 수 있습니다). 다음과 같이 주석을 통해 Spring을 구성 해 보았습니다.

@Configuration 
public class CoreConfig {

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

}

하지만 Tomcat을 시작하면 다음 예외가 throw됩니다.

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을 통해 구성을 시도했지만 위와 같은 ClassNotFoundException을 얻고 있습니다.

봄 부팅 시동기 1.1.9

Tomcat 7.0.54

서버의 Pom.xml

<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>

해결법

  1. ==============================

    1.당신은 복잡한 방향으로 나아가고 있습니다.

    당신은 복잡한 방향으로 나아가고 있습니다.

    spring.http.multipart.maxFileSize를 application.properties 파일에 추가하면된다. xml을 사용하거나 MultipartResolver를 명시 적으로 정의 할 필요가 없습니다.

    spring.http.multipart.maxFileSize=10MB   
    

    이것은 Spring Boot Reference Guide에서 파일 업로드에 관한 섹션에서 설명합니다.

    모든 속성에 대해 MultipartProperties 클래스를 확인하십시오. 지원되는 다른 속성은 spring.http.multipart.location, spring.http.multipart.maxRequestSize 및 spring.http.multipart.fileSizeThreshold입니다.

    ClassNotFoundException은 스프링 부트가 commons-fileupload가 아닌 파일 업로드에 대한 기본 Servlet 3.0 지원을 사용하기 때문에 발생합니다. 따라서이를 사용하려면 명시 적으로 종속성을 추가해야합니다. 그리고 당연히 spring.http.multipart. * 속성은 더 이상 작동하지 않습니다.

  2. ==============================

    2.

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

    빈을 정의하는 클래스에서 이것을 추가하십시오.

  3. ==============================

    3.스프링 부트 1.5.3을 사용하면 application.yml에서 다음 코드를 사용해야합니다.

    스프링 부트 1.5.3을 사용하면 application.yml에서 다음 코드를 사용해야합니다.

    spring:
     http:
      multipart:
       max-file-size: 10MB
       max-request-size: 10MB
    
  4. ==============================

    4.스프링 부트 2.0+ 용 spring.http 대신 spring.servlet 사용

    스프링 부트 2.0+ 용 spring.http 대신 spring.servlet 사용

    spring.servlet.multipart.max-file-size=30MB
    spring.servlet.multipart.max-request-size=30MB
    
  5. from https://stackoverflow.com/questions/27061209/spring-boot-classnotfoundexception-when-configuring-maxuploadsize-of-commonmult by cc-by-sa and MIT license