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

Spring Boot自定义@ControllerAdvice的Exception.class全局异常处理器不生效问题

问题原因

该问题是多个配置错误和Spring MVC异常处理机制的特性共同导致的:

  1. 优先级未生效:你代码中的@Order(Ordered.HIGHEST_PRECEDENCE)处于注释状态,自定义异常处理器的优先级低于Spring默认的DefaultHandlerExceptionResolver,部分异常会被默认处理器抢先处理。
  2. 继承ResponseEntityExceptionHandler的冲突:父类ResponseEntityExceptionHandler本身已经内置了十几种Spring MVC标准异常的专属处理方法(比如请求方法不匹配的HttpRequestMethodNotSupportedException、参数缺失异常等),按照Spring异常处理器的匹配规则,具体异常类型的处理器优先级远高于泛用的Exception类型处理器,因此这些标准异常会直接走父类的处理逻辑,根本不会进入你写的handleAll方法。
  3. handleAll方法实现错误:方法内调用的super.handleException(ex, request)对于父类未覆盖的异常(比如你主动抛出的NullPointerException)会直接抛出原异常,同时你的handleAll方法声明了throws Exception,会被Spring判定为该处理器执行失败,直接降级到默认异常处理器处理。
  4. 404路径异常默认不抛出:Spring Boot默认不会将路径不匹配的NoHandlerFoundException抛出给ControllerAdvice,而是直接走内置的/error端点返回默认错误信息,需要额外配置才能捕获该类异常。

解决方案

1. 修正异常处理器配置

最简单的方案是去掉ResponseEntityExceptionHandler继承,避免父类内置处理器的干扰,同时开启最高优先级:

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ErrorControllerAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ErrorControllerAdvice.class);

    @ExceptionHandler({ ConstraintViolationException.class })
    public ResponseEntity<Object> handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
        ApiResponse apiResponse = ApiResponse.builder()
                .timestamp(new Date())
                .status(HttpStatus.BAD_REQUEST)
                .message(ex.getLocalizedMessage())
                .path(((ServletWebRequest) request).getRequest().getRequestURI())
                .build();
        return new ResponseEntity<>(apiResponse, new HttpHeaders(), apiResponse.getStatus());
    }

    @ExceptionHandler({ Exception.class })
    public ResponseEntity<Object> handleAll(Exception ex, WebRequest request) {
        // 根据异常类型自定义状态码
        HttpStatus status;
        if (ex instanceof HttpRequestMethodNotSupportedException) {
            status = HttpStatus.METHOD_NOT_ALLOWED;
        } else if (ex instanceof NoHandlerFoundException) {
            status = HttpStatus.NOT_FOUND;
        } else if (ex instanceof IllegalArgumentException) {
            status = HttpStatus.BAD_REQUEST;
        } else {
            status = HttpStatus.INTERNAL_SERVER_ERROR;
        }
        ApiResponse apiResponse = ApiResponse.builder()
                .timestamp(new Date())
                .status(status)
                .message(ex.getLocalizedMessage())
                .path(((ServletWebRequest) request).getRequest().getRequestURI())
                .build();
        return new ResponseEntity<>(apiResponse, new HttpHeaders(), status);
    }
}

2. 配置捕获404异常

如果需要处理路径不匹配的场景,在application.properties中添加以下配置:

# 找不到处理器时抛出异常
spring.mvc.throw-exception-if-no-handler-found=true
# 禁用默认静态资源映射(如果项目有静态资源需要自行配置映射规则)
spring.web.resources.add-mappings=false

修改完成后所有异常都会进入自定义处理器处理,不会再走默认的错误响应。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:09:02