背景
项目重构,将boot从2.x升级到了3.x。
但是某些content-type=multipart/form-data的请求在后台报错:org.springframework.web.multipart.MultipartException
其他的post/get请求都正常。
解决流程
现象分析
Spring MVC 的核心处理器尝试解析文件前,请求的输入流(InputStream)已经被提前读取或关闭了。
推测1:由业务过滤器书写不当导致
升级前 (Spring Boot 2.x): 框架默认启用了一个叫 HiddenHttpMethodFilter 的过滤器。这个过滤器的作用是让表单支持 PUT、DELETE 等请求。为了实现这一点,它会在请求处理的早期阶段就去调用 request.getParameter()。
这个调用恰好带来一个**“无心插柳”的好处**:它会强制 Tomcat 提前解析 multipart/form-data 请求,并将文件部分安全地缓存起来。
正因为如此,即便后续的自定义过滤器和拦截器再去读取请求,也不会引发问题,因为文件部分已经被框架安全地预处理了。HiddenHttpMethodFilter 像一把“保护伞”,无意中掩盖了应用中其他组件对请求流的不当处理。
升级后 (Spring Boot 3.x): 从 Spring Boot 2.2.0 开始,为了与现代 RESTful API 的实践保持一致,HiddenHttpMethodFilter 默认被禁用了。这把“保护伞”消失了。
这里的解决方案是,将原来的过滤器打开:
spring:
mvc:
hiddenmethod:
filter:
enabled: true
很遗憾,没有生效。
推测2:由tomcat导致
tomcat某个版本升级后看,官方为避免恶意攻击请求,将 maxPartCount 默认值由 1000 变更为了 10,导致请求参数过多时,会抛出上述异常。
解决办法:
# 增加配置项
server:
tomcat:
max-part-count: 200
生效了!

2215

被折叠的 条评论
为什么被折叠?



