You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在额外Servlet Filter中解析multipart请求且不丢失上传内容

实现方案

问题梳理

  • 自定义Filter需要对multipart类型POST请求做前置校验,在请求抵达无修改权限的Jersey业务端点前,就要拦截拒绝不符合要求的请求。
  • 配置常规multipart解析参数后,可以解决报错:Unable to process parts as no multi-part configuration has been provided
  • 基础配置完成后,无论是自定义CommonsMultipartResolver还是系统内置解析器,运行时都不会再抛出上述错误,但会出现请求被解析后上传内容丢失的问题。
  • 现有参考方案需要自定义CommonsMultipartResolver处理内容丢失问题,实现较重,目标是仅新增Filter就满足需求,不需要做请求复制。

最简实现(无需复制请求/包装请求)

利用Servlet 3.0+规范自带的multipart解析缓存机制即可实现,不需要额外引入Commons FileUpload组件,也不需要自定义MultipartResolver。

  1. 首先完成multipart基础配置,Spring Boot环境可直接在配置文件添加:
spring:
  servlet:
    multipart:
      enabled: true
      # 根据业务需求调整大小限制
      max-file-size: 100MB
      max-request-size: 100MB

如果是非Spring Boot环境,需要给Servlet配置添加MultipartConfigElement,确保容器开启multipart解析能力。

  1. 编写自定义校验Filter,逻辑按如下顺序实现:
    • 首先判断请求Content-Type是否为multipart/form-data,非该类型请求直接放行
    • 针对multipart请求,直接调用标准Servlet接口request.getParts()获取所有请求分片,遍历分片的过程中完成自定义校验(比如文件后缀、大小、表单字段合法性等),校验不通过直接返回对应错误响应
    • 校验通过后直接放行请求即可,不需要做任何请求包装、流复制操作

关键注意点:整个Filter逻辑中不要手动调用request.getInputStream()或request.getReader()读取请求体,所有和multipart相关的操作都走getParts()/getPart(name)标准接口。容器解析完Part后会自动缓存解析结果,后续Jersey端点读取请求时会直接复用缓存内容,不会出现流被提前消费导致的上传内容丢失问题。

避坑说明

  • 不要在Filter中手动解析请求输入流:一旦手动把输入流读尽又没做完整缓存,后续链路必然拿不到上传内容。
  • 不需要额外自定义CommonsMultipartResolver:Servlet容器自带的解析能力已经支持结果复用,完全满足前置校验场景的需求,实现比自定义解析器简洁很多。

内容的提问来源于stack exchange,提问作者rob2universe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:01:11