Spring Boot2错误处理
一、错误处理底层组件分析
Spring Boot 2 错误处理的核心组件包括:
- ErrorMvcAutoConfiguration
自动配置类,初始化错误处理基础设施 - BasicErrorController
处理/error
请求的默认控制器,根据请求类型返回JSON或错误视图 - DefaultErrorAttributes
收集错误信息(状态码、异常、时间戳等) - ErrorPageCustomizer
注册错误页面(如404重定向到/error
) - DefaultErrorViewResolver
解析错误视图模板(如error/404.html
)
二、异常处理流程分析
graph TD
A[请求进入DispatcherServlet] --> B[执行Controller]
B --> C{是否抛出异常?}
C -->|是| D[遍历HandlerExceptionResolver]
C -->|否| E[正常响应]
D --> F{找到匹配解析器?}
F -->|是| G[解析器处理异常]
F -->|否| H[异常传递到Servlet容器]
H --> I[ErrorPageCustomizer重定向到/error]
I --> J[BasicErrorController处理]
J --> K[返回错误响应]
三、全局异常处理(@ControllerAdvice)
@ControllerAdvice
public class GlobalExceptionHandler {// 处理特定异常@ExceptionHandler(CustomException.class)public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) {ErrorResponse response = new ErrorResponse(ex.getCode(), ex.getMessage());return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);}// 处理所有未捕获异常@ExceptionHandler(Exception.class)public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex) {ErrorResponse response = new ErrorResponse("GLOBAL_001", "系统异常");return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);}
}
四、自定义异常实现
// 业务异常基类
public abstract class BusinessException extends RuntimeException {private final String errorCode;public BusinessException(String errorCode, String message) {super(message);this.errorCode = errorCode;}public String getErrorCode() {return errorCode;}
}// 具体业务异常
public class OrderNotFoundException extends BusinessException {public OrderNotFoundException(Long orderId) {super("ORDER_404", "订单不存在: " + orderId);}
}// 使用示例
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {return orderRepository.findById(id).orElseThrow(() -> new OrderNotFoundException(id));
}
五、自定义异常处理解释器分析
通过实现HandlerExceptionResolver
接口深度定制:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public class CustomExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {// 1. 识别异常类型if (ex instanceof BusinessException) {BusinessException bex = (BusinessException) ex;// 2. 构建统一响应体ErrorResult result = new ErrorResult(bex.getErrorCode(),bex.getMessage(),Instant.now());// 3. 设置HTTP状态码response.setStatus(HttpStatus.BAD_REQUEST.value());// 4. 返回JSON响应try {response.getWriter().write(new ObjectMapper().writeValueAsString(result));return new ModelAndView(); // 返回空视图表示已处理} catch (IOException e) {return null; // 继续其他解析器处理}}return null; // 其他异常由后续解析器处理}
}
关键机制对比
处理方式 | 适用场景 | 执行优先级 |
---|---|---|
@ExceptionHandler | 控制器内局部异常处理 | 最高 |
@ControllerAdvice | 全局异常处理 | 高 |
HandlerExceptionResolver | 底层定制化处理 | 中 |
BasicErrorController | 默认错误端点 | 最低 |
最佳实践建议:
- 业务异常使用自定义异常体系
- 全局处理使用
@ControllerAdvice
覆盖常见异常- 通过
HandlerExceptionResolver
处理特殊协议响应- 在
application.yml
中配置:server:error:include-exception: true # 响应中包含异常信息include-stacktrace: never # 生产环境关闭堆栈