简体   繁体   中英

Spring MultipartFile parameter not respecting configured maxFileSize

I have a file upload Controller. I'm trying to make the max file size configurable, but I'm not able to figure out why the configuration as documented ( https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-multipart-file-upload-configuration ) is not being applied.

plugins {
    id 'org.springframework.boot' version '2.1.4.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.MultipartConfigElement;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

@Controller
public class FileUploadController {

  private MultipartConfigElement multipartConfigElement;

  @Autowired
  public FileUploadController(MultipartConfigElement multipartConfigElement) {
    this.multipartConfigElement = multipartConfigElement;
  }

  @PostMapping("/upload")
  public void upload(@RequestParam("file") MultipartFile file) throws IOException {
    InputStream inputStream = new BufferedInputStream(file.getInputStream());
    // TODO something with inputStream

    long fileSize = file.getSize();
    boolean fileSizeLimitExceeded = fileSize > multipartConfigElement.getMaxFileSize();
    return;
  }
}


Debug screenshot

I expect the multipartConfigElement.getMaxFileSize() should prevent larger files getting this far and automatically return a 400 or some other type of exception.

But instead the maxFileSize seems to be completely ignored.

So it turns out that the limits do work, and do automatically throw Exceptions.

I saw this when I ran a request against my Controller using Postman.

{
  "timestamp": "2019-04-05T09:52:39.839+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1 bytes.",
  "path": "/upload"
}

The reason I wasn't seeing that was because I was testing with MockMVC (snippet below). MockMVC doesn't seem to trigger the exceptions for some reason – maybe because it is not running on a compatible web server. Probably related to https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#spring-mvc-test-vs-end-to-end-integration-tests .

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import java.io.FileInputStream;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
@AutoConfigureMockMvc
public class FileUploadTest {

  @Autowired
  private MockMvc mockMvc;

  @Test
  public void givenAFileThatExceedsTheLimit_whenUploaded_responseWith400Error() throws Exception {

    MockMultipartFile file =
        new MockMultipartFile("file", new FileInputStream(TestUtils.loadLargeFile()));

    this.mockMvc
        .perform(MockMvcRequestBuilders.multipart("/upload").file(file)
            .contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
        .andExpect(status().isBadRequest());
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM