Spring-boot: Auto-configured MultipartConfigElement prevents CommonsMultipartResolver from resolving request parts

Created on 23 Dec 2016  路  13Comments  路  Source: spring-projects/spring-boot

I used Spring Boot 1.2.6 before, So I want to upgrade Spring Boot to 1.4.2 and upgrade Spring Framework to 4.3.5, when I changed my maven pom, The Apache Commons FileUpload parseRequest() returning no items. Then I changed Spring Boot to 1.3.8 and Spring Framework to 4.2.8, the Apache Commons FileUpload can work. I don't know why. The following is my maven pom and my code.

Maven pom

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot</artifactId>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j</artifactId>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-ws</artifactId>
        <version>1.3.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.2.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.2.8.RELEASE</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
        <version>4.2.0.RELEASE</version>
      </dependency>

Code

   DiskFileItemFactory factory = new DiskFileItemFactory();
    factory.setSizeThreshold(1 * 1024 * 1024);
    File tmpDir = new File("tempfile");
    if (!tmpDir.exists()) {
      tmpDir.mkdir();
    }
    File uploadtmp = new File("uploadtmp");
    if (!uploadtmp.exists()) {
      uploadtmp.mkdir();
    }
    factory.setRepository(tmpDir);
    ServletFileUpload sfu = new ServletFileUpload(factory);
    sfu.setFileSizeMax(-1);
    sfu.setSizeMax(-1);
    sfu.setHeaderEncoding("UTF-8");
    List<FileItem> fileItems = (List<FileItem>) sfu.parseRequest(request);

When I use Spring Boot 1.4.2 and Spring Framework 4.3.5, the fileItems is empty.

bug

Most helpful comment

@martin-g That fixed it, thanks!

All 13 comments

The same to me. I had bean give up when try my best to debug.
I suggest try to remove Commons-FileUpload.

@qiuxiaoj or @peilongwu do either of you have a sample project that we can try?

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

@philwebb I'm having this same issue, and have an example application that reproduces the issue. Do you want to re-open this issue, or should I open a new one?

@TheSentinel454 thanks for the sample. Can you please explain how Swagger is relevant to the issue?

@TheSentinel454 Try with the following

@EnableAutoConfiguration(exclude = {
    MultipartAutoConfiguration.class  // excluded so that the application uses commons-fileupload instead of Servlet 3 Multipart support
})

in YourSpringBootApplication.
This will disable Servlet 3.x multipart support. Maybe the data has been read before commons-fileupload had a chance to do it.

@snicoll Swagger is not relevant (I'll remove it now). I was originally using that to do the upload, but decided to resort to using a rest client.

@martin-g That fixed it, thanks!

@snicoll Is it a good idea to not enable Servlet 3 Multipart auto configuration if commons-fileupload is on the classpath ?

@snicoll
here is a project which reproduces this issue with the current spring boot version 2.0.2.RELEASE:
https://github.com/ulrichwinter/gs-uploading-files/tree/master/complete

I also had this same issue within a project just after upgrade from 1.4.4.RELEASE to 1.5.12.RELEASE.
But unfortunately I was not able to reproduce it with 1.5.12 in the demo project.

(the demo is based on the fileupload guide project from spring boot).

Thanks for the sample, @ulrichwinter.

I think we need to make the auto-configuration of MultipartConfigElement back off when there's a CommonsFileUploadResolver bean available. If we don't, the use of the MultipartConfigElement prevents Commons File Upload from working. It needs to specifically be a CommonsFileUploadResolver bean that causes the auto-configuration to back off as doing so for any MultipartResolver would regress #2538.

But unfortunately I was not able to reproduce it with 1.5.12 in the demo project.

The problem doesn't occur with 1.5 as you have the following in application.properties:

spring.http.multipart.enabled=false

This has the same effect as excluding the auto-configuration. The equivalent property on 2.0 is spring.servlet.multipart.enabled=false.

Was this page helpful?
0 / 5 - 0 ratings