Spring Boot 2.0下@ControllerAdvice未捕获404异常的排查要点咨询
我来帮你梳理下Spring Boot 2.0 + Spring 5.0环境下,让自定义异常处理器能正确捕获API错误的关键检查点,你可以逐一排查:
确认@ControllerAdvice的作用范围
默认情况下,@ControllerAdvice只会扫描当前类所在包及其子包下的控制器。如果你的CustomExceptionHandler和业务控制器不在同一个包层级,处理器可能无法生效。可以通过指定basePackages或basePackageClasses明确扫描范围,比如:@ControllerAdvice(basePackages = "com.yourproject.api.controllers") public class CustomExceptionHandler { // 异常处理方法 }接管容器级错误到Spring MVC链路
404这类“页面不存在”的错误默认是由Tomcat容器处理的,不会进入Spring的异常处理流程。你需要让Spring接管这些错误:- 在
application.properties中添加配置:server.error.include-exception=true server.error.path=/error - 或者自定义
ErrorController实现,将错误请求转发到Spring的处理链路,这样@ControllerAdvice才能捕获到对应的异常。
- 在
开启NoHandlerFoundException的抛出
Spring MVC默认不会抛出NoHandlerFoundException(对应404场景),需要手动开启:
在application.properties中添加:spring.mvc.throw-exception-if-no-handler-found=true spring.resources.add-mappings=false第二个配置是关闭静态资源的自动映射,确保只有API接口的404请求会抛出异常,避免静态资源的404干扰。
检查ExceptionHandler方法的正确性
确保你的异常处理方法签名符合要求:- 要正确接收异常对象(比如
Exception ex),可以搭配HttpServletRequest、HttpServletResponse等参数; - 避免返回导致循环的视图:如果返回视图名称(比如
"error"),而该视图对应的路径又触发错误,就会出现循环视图页面错误。建议改用ResponseEntity返回JSON格式的错误信息,示例:@ExceptionHandler(Exception.class) public ResponseEntity<Map<String, Object>> handleGlobalException(Exception ex) { Map<String, Object> errorDetails = new HashMap<>(); errorDetails.put("message", ex.getMessage()); errorDetails.put("timestamp", LocalDateTime.now()); return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR); }
- 要正确接收异常对象(比如
确保自定义处理器的优先级最高
如果项目中存在多个@ControllerAdvice处理器,优先级低的可能无法触发。可以给你的CustomExceptionHandler加上@Order(Ordered.HIGHEST_PRECEDENCE)注解,确保它优先处理异常:@ControllerAdvice @Order(Ordered.HIGHEST_PRECEDENCE) public class CustomExceptionHandler { // ... }排查循环视图错误的根源
日志中的“循环视图页面错误”通常是因为异常处理器返回的视图与错误路径冲突(比如返回"error",而Spring Boot默认错误路径是/error)。解决办法要么修改返回的视图名称,要么直接返回JSON数据而非视图,彻底避免循环。无需额外配置Tomcat钩子
在Spring Boot 2.0环境下,不需要额外配置Tomcat钩子,上述配置已经足够让错误请求进入Spring的异常处理链路。
内容的提问来源于stack exchange,提问作者Smart Developer

