Spring Boot 3.2.1大文件上传限制配置不生效,报FileSizeLimitExceededException
问题场景
将Java应用从旧版Spring Boot升级至3.2.1版本后,文件上传至S3的功能出现异常:上传小于1MB的文件正常,但上传更大文件时触发422错误,错误信息如下:
message : "Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes."
已做的无效尝试:
- 配置
application.yml并验证运行时配置生效:
spring: servlet: multipart: enabled: true max-file-size: 10MB max-request-size: 10MB server: tomcat: max-swallow-size: -1 max-http-form-post-size: -1
- 添加
MultipartConfigElementBean并确认启动时执行:
@Bean MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize(DataSize.ofBytes(512000000L)); factory.setMaxRequestSize(DataSize.ofBytes(512000000L)); return factory.createMultipartConfig(); }
- 查阅资料尝试配置
MultipartResolver,但CommonsMultipartResolver在Spring Boot 3.x中已移除,无法编译。
环境细节:
- Spring Boot 3.2.1,依赖包括
spring-boot-starter、spring-boot-starter-actuator、spring-boot-starter-hateoas、spring-boot-starter-data-jpa、spring-boot-starter-data-rest - 内嵌Tomcat 10.1.17
调试现象:
上传小于1MB的文件时,Request.parseParts()和FileUploadBase.setSizeMax()断点命中,且最大文件大小为配置值;上传更大文件时,这些断点未命中,说明存在提前限制文件大小的逻辑。
解决方案
1. 排查Filter/Interceptor提前拦截请求
自定义Filter或第三方组件(如安全框架)可能在Spring解析Multipart请求前就读取了请求体,触发Tomcat默认1MB限制:
- 检查所有自定义Filter(实现
javax.servlet.Filter或org.springframework.web.filter.OncePerRequestFilter),确认是否有提前解析request body的逻辑。 - 若使用Spring Security,调整
MultipartFilter顺序,确保其在Security Filter之前执行:
@Bean public FilterRegistrationBean<MultipartFilter> multipartFilter() { FilterRegistrationBean<MultipartFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MultipartFilter()); registrationBean.setOrder(SecurityProperties.DEFAULT_FILTER_ORDER - 1); return registrationBean; }
2. 检查Tomcat Connector配置
排查是否有代码直接修改Tomcat Connector的上传限制参数:
@Bean public TomcatServletWebServerFactory tomcatServletWebServerFactory() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.addConnectorCustomizers(connector -> { connector.setMaxHttpFormPostSize(-1); // 禁用表单POST大小限制 }); return factory; }
3. 配置Spring Data Rest的Multipart限制
因使用spring-boot-starter-data-rest,需单独配置Data Rest的上传限制:
spring: data: rest: multipart: max-file-size: 10MB max-request-size: 10MB
4. 检查Controller注解的大小限制
确认Controller方法是否通过注解设置了局部文件大小限制,比如:
// 移除或修改maxSize属性 @PostMapping("/upload") public ResponseEntity<?> uploadFile(@RequestPart(value = "file", maxSize = "1MB") MultipartFile file) { // 处理逻辑 }
5. 修复@EnableWebMvc导致的自动配置失效
若使用@EnableWebMvc,Spring Boot的Multipart自动配置会被禁用,需手动配置MultipartResolver:
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Bean public MultipartResolver multipartResolver() { StandardServletMultipartResolver resolver = new StandardServletMultipartResolver(); return resolver; } }
同时确保MultipartConfigElement Bean正常生效。
内容的提问来源于stack exchange,提问作者Mark

