在Spring Boot中实现统一异常处理主要通过@ControllerAdvice和@ExceptionHandler注解组合完成。这种方式能集中处理控制器层抛出的异常,避免在每个方法中重复编写异常处理代码。
基础实现步骤
创建全局异常处理类并添加@ControllerAdvice注解。这个类可以包含多个异常处理方法:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleException(Exception ex) { ErrorResponse error = new ErrorResponse( HttpStatus.INTERNAL_SERVER_ERROR.value(), "Internal Server Error", ex.getMessage() ); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); } }定义统一的错误响应体结构:
@Data @AllArgsConstructor public class ErrorResponse { private int status; private String error; private String message; private String timestamp = LocalDateTime.now().toString(); }处理特定异常类型
针对不同的异常类型定义具体的处理方法:
@ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleResourceNotFound( ResourceNotFoundException ex) { ErrorResponse error = new ErrorResponse( HttpStatus.NOT_FOUND.value(), "Resource Not Found", ex.getMessage() ); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ErrorResponse> handleValidationExceptions( MethodArgumentNotValidException ex) { List<String> errors = ex.getBindingResult() .getFieldErrors() .stream() .map(FieldError::getDefaultMessage) .collect(Collectors.toList()); ErrorResponse error = new ErrorResponse( HttpStatus.BAD_REQUEST.value(), "Validation Error", errors.toString() ); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); }自定义异常类
创建业务特定的异常类型:
public class BusinessException extends RuntimeException { private final ErrorCode errorCode; public BusinessException(ErrorCode errorCode, String message) { super(message); this.errorCode = errorCode; } public ErrorCode getErrorCode() { return errorCode; } }对应的异常处理:
@ExceptionHandler(BusinessException.class) public ResponseEntity<ErrorResponse> handleBusinessException( BusinessException ex) { ErrorResponse error = new ErrorResponse( ex.getErrorCode().getCode(), ex.getErrorCode().name(), ex.getMessage() ); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); }响应内容协商支持
确保异常处理支持多种响应格式(JSON/XML等):
@ControllerAdvice @RequestMapping(produces = {"application/json", "application/xml"}) public class GlobalExceptionHandler { // 处理方法保持不变 }日志记录集成
在异常处理中加入日志记录:
@ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleException(Exception ex) { logger.error("Unexpected error occurred", ex); // 其余处理逻辑 }测试验证方法
编写测试用例验证异常处理:
@SpringBootTest @AutoConfigureMockMvc class ExceptionHandlerTest { @Autowired private MockMvc mockMvc; @Test void testResourceNotFound() throws Exception { mockMvc.perform(get("/api/resource/999")) .andExpect(status().isNotFound()) .andExpect(jsonPath("$.error").value("Resource Not Found")); } }这种实现方式提供了清晰的异常处理结构,使业务代码保持整洁,同时为客户端返回标准化的错误响应。根据项目需求可以进一步扩展,如添加多语言支持、更详细的错误分类等。