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

如何在Spring Boot内嵌Tomcat中配置最大文件数量?

如何为Spring Boot内嵌Tomcat配置多文件上传的最大文件数量?

我们的微服务基于Spring Boot + Java开发,使用内嵌Tomcat服务器,原本可通过以下配置项控制文件上传大小:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

但针对Tomcat的相关CVE要求配置最大文件数量参数,以下是具体的解决思路和实现方案:

现状说明

  • Spring Boot官方的spring.servlet.multipart系列配置中无直接对应最大文件数量的参数;
  • 查看Tomcat 9.0.75版本的MultipartConfigElement,仅包含maxFileSize、maxRequestSize、fileSizeThreshold三个属性,无文件数量相关配置;
  • MultipartConfigFactory确实没有setMaxFileCount方法,无法通过该类直接配置。

可行解决方案

方案一:自定义MultipartResolver做业务层拦截

通过继承Spring的CommonsMultipartResolver(或StandardServletMultipartResolver),在解析请求时统计上传文件数量,超过阈值则抛出异常,实现方式如下:

1. 自定义MultipartResolver子类

import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

public class LimitedMultipartResolver extends CommonsMultipartResolver {

    private int maxFileCount = 10; // 默认限制10个文件

    public void setMaxFileCount(int maxFileCount) {
        this.maxFileCount = maxFileCount;
    }

    @Override
    protected MultipartHttpServletRequest doResolveMultipart(HttpServletRequest request) throws MultipartException {
        MultipartHttpServletRequest multipartRequest = super.doResolveMultipart(request);
        List<String> fileNames = multipartRequest.getFileNames();
        if (fileNames.size() > maxFileCount) {
            throw new MultipartException(String.format("上传文件数量超过限制,最多允许%d个文件", maxFileCount));
        }
        return multipartRequest;
    }
}

2. 配置自定义Resolver为Spring Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;

@Configuration
public class MultipartConfig {

    @Bean
    public MultipartResolver multipartResolver() {
        LimitedMultipartResolver resolver = new LimitedMultipartResolver();
        resolver.setMaxFileCount(10); // 设置最大文件数量
        // 同时配置文件大小限制,替代原spring.servlet.multipart配置
        resolver.setMaxUploadSize(124 * 1024 * 1024); // 对应max-request-size(124MB)
        resolver.setMaxUploadSizePerFile(124 * 1024 * 1024); // 对应max-file-size(124MB)
        return resolver;
    }
}

方案二:自定义Tomcat Valve做底层拦截

如果需要在Tomcat层面全局拦截所有multipart请求,可自定义Valve实现文件数量校验:

1. 自定义Tomcat Valve

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class MultipartFileCountValve extends ValveBase {

    private int maxFileCount = 10;

    public void setMaxFileCount(int maxFileCount) {
        this.maxFileCount = maxFileCount;
    }

    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        HttpServletRequest httpRequest = request.getRequest();
        if (httpRequest.getContentType() != null && httpRequest.getContentType().startsWith("multipart/")) {
            try {
                request.parseParts();
                // 统计文件类型的part数量
                int fileCount = (int) request.getParts().stream()
                        .filter(part -> part.getContentType() != null && !part.getSubmittedFileName().isBlank())
                        .count();
                if (fileCount > maxFileCount) {
                    response.sendError(400, String.format("上传文件数量超过限制,最多允许%d个文件", maxFileCount));
                    return;
                }
            } catch (Exception e) {
                response.sendError(400, "文件上传解析失败");
                return;
            }
        }
        getNext().invoke(request, response);
    }
}

2. 配置Tomcat加载自定义Valve

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatConfig {

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatMultipartValveCustomizer() {
        return factory -> {
            MultipartFileCountValve fileCountValve = new MultipartFileCountValve();
            fileCountValve.setMaxFileCount(10);
            factory.addEngineValves(fileCountValve);
        };
    }
}

方案选择建议

  • 方案一更贴合Spring Boot开发模式,对业务代码侵入小,无需关注Tomcat底层细节,推荐优先使用;
  • 方案二适合需要全局拦截所有multipart请求的场景,但需注意请求解析顺序,避免与Spring的MultipartResolver逻辑冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:57:40