Spring Boot自定义@ControllerAdvice的Exception.class全局异常处理器不生效问题
问题原因
该问题是多个配置错误和Spring MVC异常处理机制的特性共同导致的:
- 优先级未生效:你代码中的
@Order(Ordered.HIGHEST_PRECEDENCE)处于注释状态,自定义异常处理器的优先级低于Spring默认的DefaultHandlerExceptionResolver,部分异常会被默认处理器抢先处理。 - 继承
ResponseEntityExceptionHandler的冲突:父类ResponseEntityExceptionHandler本身已经内置了十几种Spring MVC标准异常的专属处理方法(比如请求方法不匹配的HttpRequestMethodNotSupportedException、参数缺失异常等),按照Spring异常处理器的匹配规则,具体异常类型的处理器优先级远高于泛用的Exception类型处理器,因此这些标准异常会直接走父类的处理逻辑,根本不会进入你写的handleAll方法。 handleAll方法实现错误:方法内调用的super.handleException(ex, request)对于父类未覆盖的异常(比如你主动抛出的NullPointerException)会直接抛出原异常,同时你的handleAll方法声明了throws Exception,会被Spring判定为该处理器执行失败,直接降级到默认异常处理器处理。- 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
相关产品推荐
相关产品推荐

