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

Spring Boot中@ControllerAdvice无法捕获自定义文件上传异常

文件上传大小超限异常无法被自定义处理器捕获的问题

我使用@RestControllerAdvice实现了全局异常处理器,能够正常捕获NoSuchElementFoundException等自定义异常,未捕获的错误会被handleAllUncaughtException方法捕获。但我创建了MaxUploadSizeExceededException和FileSizeLimitExceededException两个自定义异常类及对应的处理方法,却无法捕获文件上传大小超限的错误,该错误仍被handleAllUncaughtException捕获。

相关代码示例

@RestControllerAdvice
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {    

    // 处理NoSuchElementFoundException
    @ExceptionHandler(NoSuchElementFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<Object> handleNoSuchElementFoundException(NoSuchElementFoundException ex, 
                                  WebRequest request) {
        log.error(FAILED_TO_FIND_ELEMENT, ex);
        return buildErrorResponse(ex, HttpStatus.NOT_FOUND, request);
    }


    // 尝试捕获自定义文件大小超限异常的方法
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
    public ResponseEntity<Object> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, 
                                     WebRequest request) {
        return buildErrorResponse(ex, HttpStatus.PAYLOAD_TOO_LARGE, request);
    }

    @ExceptionHandler(FileSizeLimitExceededException.class)
    @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
    public ResponseEntity<Object> handleFileSizeLimitExceededException(FileSizeLimitExceededException ex, 
                                     WebRequest request) {
        return buildErrorResponse(ex, HttpStatus.PAYLOAD_TOO_LARGE, request);
    }


    // 兜底处理所有未捕获的异常
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<Object> handleAllUncaughtException(Exception ex, 
                                                             WebRequest request) {
        return buildErrorResponse(ex, UNKNOWN_ERROR, HttpStatus.INTERNAL_SERVER_ERROR, request);
    }

    // 省略其他代码
}

自定义异常类示例

public class MaxUploadSizeExceededException extends RuntimeException {

    public MaxUploadSizeExceededException(String message) {
        super(message);
    }
}

错误堆栈跟踪显示抛出的是org.springframework.web.multipart.MaxUploadSizeExceededException,针对问题解答如下:


1. 应使用哪种异常类型创建自定义类,并如何在自定义方法中捕获该错误?

你当前的自定义MaxUploadSizeExceededException与Spring内置的org.springframework.web.multipart.MaxUploadSizeExceededException是完全独立的两个类,所以你的异常处理器无法匹配到实际抛出的内置异常。有两种解决方式:

方式一:直接捕获Spring内置异常

无需自定义同名异常类,直接在@ExceptionHandler中指定Spring内置的异常类型即可:

@ExceptionHandler(org.springframework.web.multipart.MaxUploadSizeExceededException.class)
@ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
public ResponseEntity<Object> handleSpringMaxUploadSizeExceededException(org.springframework.web.multipart.MaxUploadSizeExceededException ex, 
                                                                 WebRequest request) {
    return buildErrorResponse(ex, HttpStatus.PAYLOAD_TOO_LARGE, request);
}

方式二:自定义异常并手动抛出

如果坚持使用自定义异常,需要在文件上传逻辑中捕获Spring内置异常,再手动抛出自己的自定义异常:

  1. 保留你已定义的MaxUploadSizeExceededException类
  2. 在文件上传的Controller方法中处理:
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
    try {
        // 执行文件上传逻辑
    } catch (org.springframework.web.multipart.MaxUploadSizeExceededException ex) {
        throw new MaxUploadSizeExceededException("文件大小超过限制");
    }
}

这样自定义异常处理器就能匹配到你手动抛出的异常了。


2. 使用HTTP状态码PAYLOAD_TOO_LARGE是否正确?

完全正确。HttpStatus.PAYLOAD_TOO_LARGE对应的是HTTP 413状态码,该状态码的语义就是请求体过大,完全契合文件上传大小超限的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:27:23