java - Spring MultipartFile 参数不尊重配置的 maxFileSize
问题描述
我有一个文件上传控制器。我正在尝试使最大文件大小可配置,但我无法弄清楚为什么记录的配置(https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/# howto-multipart-file-upload-configuration)没有被应用。
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;
}
}
我希望 multipartConfigElement.getMaxFileSize() 应该防止较大的文件走这么远,并自动返回 400 或其他类型的异常。
但是 maxFileSize 似乎被完全忽略了。
解决方案
所以事实证明限制确实有效,并且会自动抛出异常。
当我使用 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"
}
我没有看到的原因是因为我正在使用 MockMVC 进行测试(下面的片段)。由于某种原因,MockMVC 似乎没有触发异常——可能是因为它没有在兼容的 Web 服务器上运行。可能与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());
}
}
推荐阅读
- c# - 使用 puppeteer-sharp将文本抓取到一个类中
- c - MPLAB XC8 编译器错误:“声明中没有标识符”
- c# - EF Core 3.1 - 如何使用 InMemory Provider 检测客户端评估错误?
- angular - 无法使用 ng 执行 Angular 应用程序
- node.js - 我想通过 SendGrid 将邮件发送到我从 sequelize 查询中获得的特定 id,但邮件无法发送到从表中获取的邮件
- oracle11g - 与 Insert 语句一起使用时,有效的选择查询返回 Not a group by expression 错误
- django - 从 Django 中的多个页面调用视图
- javascript - 如何在 nuxt 中使用 Axios 模块和 vuejs 设置标头
- laravel - 如何使用 laravel 急切加载条件
- javascript - 获取 id 值并将其设置为反应状态