springmvc 4.3 的项目升级到springboot2.6 自定义字段解密Filter导致文件上传可能失败的问题解决

文章来源原创   作者:临窗旋墨   发布时间:2025-08-26   阅读:26   标签:spring,springboot 分类:spring 专题:解决方案

springmvc 4.3 的项目升级到springboot2.6 自定义字段解密Filter导致文件上传可能失败的问题解决

20250826

问题背景

  • springmvc 4.3 的项目升级到springboot2.6
  • 文件解析器用的是:CommonsMultipartResolver, 不过是继承自 CommonsMultipartResolver 做了一些缓存 和匹配过程
  • 写了个filter 用户解密前端的字段中的加密部分 然后在这个filter中判断是文件数上传的时候 就 先执行文件解析器的动作 获取的Multipart request 做requesWrapper (这里做的字段解密工作)
  • 这个filter在原来的项目中是能工作的 升级后 当是文件上传的时候 在controller就接收不到这个文件字段了 报错了
  • 当前项目CommonsMultipartResolver 指定的name为MultipartFilter.DEFAULT_MULTIPART_RESOLVER_BEAN_NAME=”filterMultipartResolver”;

springboot升级造成的 一些变化

1. CommonsMultipartResolver vs StandardServletMultipartResolver 的区别

  • CommonsMultipartResolver
    • 依赖 Apache Commons FileUpload 库。
    • 通过 Commons 的解析逻辑将 HttpServletRequest 包装成 MultipartHttpServletRequest
    • SpringMVC 时代(Spring 3.x、4.x),这是常见方案。
  • StandardServletMultipartResolver
    • 基于 Servlet 3.0+ 标准 API (javax.servlet.http.Part)。
    • 不依赖 Commons-FileUpload,直接利用容器(Tomcat/Jetty)的 multipart-config
    • Spring Boot 里默认使用这个(除非你主动注册 CommonsMultipartResolver)。

升级到 Spring Boot 2.6 后,默认不再用 CommonsMultipartResolver,而是走 StandardServletMultipartResolver。这会影响 Filter 的执行顺序、Request 包装时机

2. Spring Boot 2.6 的文件上传处理模式

Spring Boot 的设计目标是 零配置、依赖 Servlet 3.0+

  • 默认不再用 MultipartFilter,而是完全走 DispatcherServlet 模式
  • Spring Boot 自动配置了一个 StandardServletMultipartResolver,利用 Servlet 3.0 标准 API (request.getParts()) 解析上传。
  • 所以:
    • 默认的 Bean 名是 multipartResolver
    • 类型是 StandardServletMultipartResolver(不是 Commons)。

这样就完全不需要再配 MultipartFilter 了。

升级后失效的原因

文件流重复解析:
我认为主要是启用了MultipartFilter, 导致文件解析提前,导致原来的字段解密Filter中的手动调用文件解析器再次解析无法获取到文件流 从而最终进入controller的时候为null.

修改方案

方案一: 禁用MultipartFilter (当前采用)

  • 去掉MultipartFilter
  • 修改文件解析器的bean name 修改为DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME

验证成功

方案二: 不禁用MultipartFilter,保证文件解析器只处理一次

  • 考虑让MultipartFilter 先执行
  • 在自定义Filter中不判断已经解析,则强转MultipartHttpServletRequest后再Wrapper解密

尚未验证


发表评论

目录