文件上传超限异常应在请求进入业务前拦截,优先通过配置与前端校验双保险防止;实际异常分三类:maxuploadsizeexceededexception(spring前置抛出)、sizelimitexceededexception(tomcat底层runtimeexception)、filesizelimitexceededexception(apache commons手动解析触发);需全局@controlleradvice兜底捕获并返回413响应,高可靠场景应加自定义filter前置拦截。

文件上传超限异常不是业务逻辑分支,而是配置或前端校验失效的信号。它不该靠 Controller 层 try-catch 捕获,而应在请求进入业务前就拦截、响应、记录——既保证用户体验,又避免资源浪费和堆栈泄露。
明确你要处理的真实异常类型
Java 中没有统一的 “SizeLimitException”。实际遇到的多是以下三类,来源和拦截时机完全不同:
-
MaxUploadSizeExceededException:Spring 自带异常,由
StandardServletMultipartResolver在 DispatcherServlet 前置阶段抛出,根本不会到达你的 @Controller 方法 -
SizeLimitExceededException(Tomcat 底层):属于
org.apache.tomcat.util.http.fileupload.impl,是 RuntimeException 子类,但常被容器提前吞掉 -
FileSizeLimitExceededException(Apache Commons FileUpload):需手动调用
ServletFileUpload.parseRequest()才会触发,适用于自定义解析场景
优先用配置 + 前端校验双保险
拦截异常不如防止异常发生。配置是第一道防线,且必须前后端一致:
- 在
application.yml中显式设置(别依赖默认 1MB):
spring.servlet.multipart.max-file-size: 50MB
spring.servlet.multipart.max-request-size: 50MB - 若用嵌入式 Tomcat,检查
server.tomcat.max-http-form-post-size或max-swallow-size(单位字节),设为52428800或-1 - 前端上传前用 JS 读取
file.size,超限时直接提示并阻止提交,不发无效请求
全局统一拦截并返回结构化响应
即使配置到位,仍可能因解析中断、恶意构造等触发未捕获异常。推荐用 @ControllerAdvice 兜底:
- 捕获
MaxUploadSizeExceededException和RuntimeException子类(如FileSizeLimitExceededException) - 响应状态码设为
413 Payload Too Large,而非 400 或 500 - 返回 JSON 如:
{"code":"UPLOAD_SIZE_EXCEEDED","message":"文件大小超出限制,请上传不超过50MB的文件"} - 日志中记录请求 ID、IP、原始 Content-Length,但不打印堆栈或原始异常消息,防信息泄露
自定义 Filter 拦截(高可靠场景必选)
当项目使用了非标准 multipart 解析器,或需要更早介入(比如记录原始请求头、做 IP 级限流),建议写一个前置 Filter:
- 只对
POST且Content-Type含multipart/form-data的请求生效 - 在
chain.doFilter()前,用ServletFileUpload.parseRequest()尝试解析 - catch
SizeLimitException后立即设置response.setStatus(413)、写入 JSON 提示,并return中断链 - 注意:不要重复解析;捕获后禁止再调用
chain.doFilter(),否则可能 NPE 或二次解析失败
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











