Spring Boot无法识别Multipart参数抛出MissingServletRequestParameterException
问题背景
为单个接口自定义MultipartResolver以支持大文件上传,其余接口均使用application.properties中配置的默认max-file-size大小限制,自定义解析器实现代码如下:
public class CustomMultipartResolver extends CommonsMultipartResolver { private static final Logger log = LoggerFactory.getLogger(PortalMultipartResolver.class); @Autowired private MultipartProperties multipartProperties; @Override public MultipartHttpServletRequest resolveMultipart(HttpServletRequest httpServletRequest) { log.info("Multipart resolver path : {}", httpServletRequest.getRequestURL()); if (httpServletRequest.getRequestURL().toString().contains("bulkUpload")) { super.setMaxUploadSize(-1); super.setMaxUploadSizePerFile(-1); MultipartHttpServletRequest multipartHttpServletRequest = super.resolveMultipart(httpServletRequest); if(multipartProperties != null) { super.setMaxUploadSize(parseSize(this.multipartProperties.getMaxFileSize())); super.setMaxUploadSizePerFile(parseSize(this.multipartProperties.getMaxRequestSize())); } else { super.setMaxUploadSize(parseSize("10MB")); super.setMaxUploadSizePerFile(parseSize("10MB")); } return multipartHttpServletRequest; } return super.resolveMultipart(httpServletRequest); } }
异常表现
接口调用过程中抛出如下异常,提示必填的MultipartFile参数file不存在,已确认请求载荷携带完整参数信息:
Exception : Required MultipartFile parameter 'file' is not present for URL org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251) at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96) at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
根因说明
该问题核心由自定义解析器的实现逻辑缺陷导致:
- Spring中默认注册的
MultipartResolver是单例Bean,代码中在请求处理流程里动态修改父类的全局大小配置(maxUploadSize、maxUploadSizePerFile是父类成员变量,所有请求共享),属于典型的线程不安全操作。并发场景下不同请求的配置会互相覆盖,导致大文件上传请求解析过程中大小限制被其他线程改回默认值,解析提前终止、请求输入流被消费但未解析出完整文件参数,最终触发参数不存在的报错。 - 路径匹配逻辑不严谨:使用
getRequestURL()做关键字匹配容易受域名、部署上下文影响,关键字模糊匹配也可能出现误判。 - 配置赋值错误:重置默认配置时,总请求大小限制和单文件大小限制的取值完全颠倒,会进一步加剧配置错乱问题。
- 可能存在Bean冲突:如果未关闭Spring Boot默认自动配置的MultipartResolver,两个解析器同时生效会导致请求输入流被提前读取,后续解析拿不到参数。
排查解决步骤
- 修复单例线程安全问题:不要在解析流程中修改父类的全局配置属性。判断到是大文件上传路径时,单独创建一个配置为无大小限制的
CommonsMultipartResolver实例解析当前请求,其余请求直接走父类默认配置逻辑,完全避免多请求配置互相覆盖的问题。示例修正逻辑:@Override public MultipartHttpServletRequest resolveMultipart(HttpServletRequest httpServletRequest) { // 用getRequestURI做精确路径匹配,避免域名、关键字误判 String requestUri = httpServletRequest.getRequestURI(); if (requestUri.endsWith("/bulkUpload")) { // 新建临时解析器,不修改全局单例的配置 CommonsMultipartResolver bulkUploadResolver = new CommonsMultipartResolver(); bulkUploadResolver.setMaxUploadSize(-1); bulkUploadResolver.setMaxUploadSizePerFile(-1); bulkUploadResolver.setDefaultEncoding(StandardCharsets.UTF_8.name()); return bulkUploadResolver.resolveMultipart(httpServletRequest); } return super.resolveMultipart(httpServletRequest); } - 修正Bean注册配置:将自定义解析器注册为名称为
multipartResolver的Spring Bean,同时在配置文件中添加spring.servlet.multipart.enabled=false,关闭Spring Boot默认的Multipart自动配置,避免多解析器冲突导致请求流被重复消费。 - 检查前置组件:如果项目中引入了Spring Security、日志切面、自定义Filter等组件,确认没有组件在MultipartResolver执行前提前读取请求输入流,输入流被读取一次后无法重复解析,会直接导致后续拿不到文件参数。
- 字段一致性校验:在解析逻辑中添加日志,打印解析完成后得到的文件参数Map的key集合,确认上传时文件字段的name属性确实为
file,不存在拼写、大小写偏差。
内容的提问来源于stack exchange,提问作者Reynadess
相关产品推荐
相关产品推荐

