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

向不存在的Servlet发送Multipart请求:JEE的Bug还是特性?

JEE中Multipart请求转发后参数丢失的原因及规范依据

现象

  • 当表单action指向不存在的Servlet URL,发送Multipart请求后,即使通过Filter转发到配置了@MultipartConfig的Servlet,该Servlet调用request.getParameterMap()返回空Map,request.getParts()返回空集合。

环境配置

  • 全局Filter拦截所有请求:
@WebFilter("/*")
public class Filter extends HttpFilter {
  • 两个配置@MultipartConfig的Servlet:
@WebServlet("/servA")
@MultipartConfig(
        fileSizeThreshold = 1024 * 1024 * 1,
        maxFileSize = 1024 * 1024 * 10,
        maxRequestSize = 1024 * 1024 * 50
        )
public class ServletA extends HttpServlet {
@WebServlet("/servB")
@MultipartConfig(
        fileSizeThreshold = 1024 * 1024 * 1,
        maxFileSize = 1024 * 1024 * 10,
        maxRequestSize = 1024 * 1024 * 50
        )
public class ServletB extends HttpServlet {

测试过程

  1. 通过chain.doFilter传递请求
    • 表单action指向存在的Servlet,Filter调用chain.doFilter,Servlet可正常获取参数和Parts;
    • 表单action指向不存在的Servlet,返回404,符合预期。
  2. 通过requestDispatcher.forward转发请求
    • 表单action指向存在的Servlet,Filter转发至任意配置了@MultipartConfig的Servlet,均可正常获取参数和Parts;
    • 表单action指向不存在的Servlet,Filter转发至/servA或/servB,两个Servlet均无法获取参数和Parts。

原因分析(基于Servlet 3.0+规范)

Servlet规范中,Multipart请求的解析时机由初始请求匹配的目标Servlet决定:

  • 容器接收到请求时,首先匹配请求URL对应的Servlet。如果该Servlet配置了@MultipartConfig,容器会自动将请求解析为Multipart格式,生成对应的Parts和参数;
  • 如果初始请求的URL没有匹配到任何Servlet(即404场景),容器不会触发Multipart解析逻辑,请求会被当作普通HTTP请求处理。此时即使后续通过Filter转发到配置了@MultipartConfig的Servlet,容器也不会重新解析请求体——因为请求输入流只能被读取一次,且解析时机已经错过,转发后的Servlet无法从已处理的请求中提取Parts和参数。

Tomcat、GlassFish等主流容器均严格遵循这一规范,因此该表现属于规范定义的预期行为,而非Bug。

临时解决方案

新增一个映射为/*的Servlet并配置@MultipartConfig(可禁止直接访问),确保所有初始请求都能匹配到启用Multipart解析的Servlet:

@WebServlet("/*")
@MultipartConfig(
        fileSizeThreshold = 1024 * 1024 * 1,
        maxFileSize = 1024 * 1024 * 10,
        maxRequestSize = 1024 * 1024 * 50
        )
public class ServletM extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 禁止直接访问,可转发到其他业务Servlet
        req.getRequestDispatcher("/servA").forward(req, resp);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:42:50