一、错误处理底层组件分析
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)
java
@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);
}
}
四、自定义异常实现
java
// 业务异常基类
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
接口深度定制:
java
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public 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
中配置:
yamlserver: error: include-exception: true # 响应中包含异常信息 include-stacktrace: never # 生产环境关闭堆栈