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

如何让Spring在文件上传达到指定大小后立即中断并抛异常?

解决Spring文件上传超限制后才抛异常的问题

这个问题我之前也踩过坑!根源在于Spring默认的文件上传解析器逻辑:不管是CommonsMultipartResolver还是默认实现,都是先把整个文件完整写入临时存储,之后才会校验文件大小——这就是为啥你设了7MB限制,却要等文件全传完才会抛出MaxUploadSizeExceededException的原因。

要实现达到大小限制时立刻中断上传,给你两种实用方案:

方案一:基于commons-fileupload自定义进度监听(适合老项目)

如果你的项目还在依赖commons-fileupload包,那可以通过自定义进度监听器实时监控上传进度,一旦超限制就主动掐断请求:

  1. 先写一个进度监听器,实时检查已上传字节数:
import org.apache.commons.fileupload.ProgressListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SizeLimitProgressListener implements ProgressListener {
    private final long maxAllowedSize;
    private final HttpServletRequest request;
    private final HttpServletResponse response;

    public SizeLimitProgressListener(long maxSize, HttpServletRequest req, HttpServletResponse resp) {
        this.maxAllowedSize = maxSize;
        this.request = req;
        this.response = resp;
    }

    @Override
    public void update(long bytesRead, long contentLength, int items) {
        // 每上传一点就检查一次,超过限制直接中断
        if (bytesRead > maxAllowedSize) {
            try {
                request.getInputStream().close();
                response.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, "文件大小超出7MB限制");
            } catch (IOException e) {
                // 这里可以根据业务做异常日志记录
                e.printStackTrace();
            }
        }
    }
}
  1. 自定义MultipartResolver,把监听器注入进去:
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;

public class CustomMultipartResolver extends CommonsMultipartResolver {
    private long maxUploadSize;

    @Override
    public void setMaxUploadSize(long maxUploadSize) {
        super.setMaxUploadSize(maxUploadSize);
        this.maxUploadSize = maxUploadSize;
    }

    @Override
    protected ServletFileUpload newFileUpload(FileItemFactory fileItemFactory) {
        ServletFileUpload upload = new ServletFileUpload(fileItemFactory);
        upload.setSizeMax(this.maxUploadSize);
        return upload;
    }

    @Override
    protected ServletFileUpload prepareFileUpload(String encoding) {
        ServletFileUpload upload = (ServletFileUpload) super.prepareFileUpload(encoding);
        // 给上传器绑定自定义监听器
        upload.setProgressListener(new SizeLimitProgressListener(this.maxUploadSize, getRequest(), getResponse()));
        return upload;
    }
}
  1. 最后在dispatcher-servlet.xml里替换掉默认的Resolver:
<bean id="multipartResolver" class="com.yourproject.utils.CustomMultipartResolver">
    <property name="maxUploadSize" value="7340032"/> <!-- 7MB转换成字节:7*1024*1024=7340032 -->
    <property name="maxInMemorySize" value="4096"/> <!-- 小于4KB的文件存在内存里 -->
</bean>

方案二:用Servlet 3.0+的StandardServletMultipartResolver(推荐)

如果你的项目是基于Servlet 3.0及以上版本,强烈推荐这个方案——不需要写任何自定义类,配置就能搞定,而且是Servlet容器层面实时校验,超限制立刻中断。

  1. 先在dispatcher-servlet.xml里配置标准Resolver:
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
  1. 然后在web.xml里给DispatcherServlet加上传参数配置:
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </init-param>
    <!-- 重点是这个multipart-config块 -->
    <multipart-config>
        <max-file-size>7340032</max-file-size> <!-- 单个文件最大7MB -->
        <max-request-size>7340032</max-request-size> <!-- 整个请求的总大小限制 -->
        <file-size-threshold>4096</file-size-threshold> <!-- 超过4KB就写入临时文件 -->
    </multipart-config>
    <load-on-startup>1</load-on-startup>
</servlet>

要是你用的是Java Config来配置Servlet,那可以这么写:

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    // 省略其他重写的方法(比如getRootConfigClasses、getServletConfigClasses)

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        // 构建文件上传配置
        MultipartConfigElement multipartConfig = new MultipartConfigElement(
            null, // 临时文件存储路径,默认用容器的临时目录
            7340032, // 单个文件最大大小
            7340032, // 请求总大小
            4096     // 内存存储阈值
        );
        registration.setMultipartConfig(multipartConfig);
    }
}

配置完之后,当用户上传的文件超过7MB时,Servlet容器会在上传过程中直接中断请求,返回413 Request Entity Too Large,不用等文件传完。最后记得在全局异常处理器里捕获相关异常,给前端返回友好的提示哦~


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:30:10