使用@ControllerAdvice和@ExceptionHandler实现全局异常处理,通过定义ErrorResponse统一响应格式,结合自定义BusinessException抛出业务异常,实现空指针、业务及未捕获异常的拦截与规范返回,提升系统稳定性和前后端交互一致性。

在Java开发中,尤其是使用Spring或Spring Boot框架时,实现全局异常拦截机制可以统一处理程序中抛出的异常,避免重复的try-catch代码,同时提升接口返回的规范性和用户体验。核心方式是使用 @ControllerAdvice 和 @ExceptionHandler 注解来实现全局异常处理。
1. 使用@ControllerAdvice实现全局异常处理器
注意:@ControllerAdvice 是一个特殊的@Component,能够作用于所有 @Controller 标记的类,配合 @ExceptionHandler 可以捕获控制器中抛出的异常。
创建一个全局异常处理类:
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理空指针异常
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public ResponseEntity handleNullPointer(NullPointerException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("发生空指针异常:" + e.getMessage());
}
// 处理自定义业务异常
@ExceptionHandler(BusinessException.class)
@ResponseBody
public ResponseEntity handleBusinessException(BusinessException e) {
ErrorResponse error = new ErrorResponse(e.getCode(), e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
// 处理所有未被捕获的异常
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity handleGeneralException(Exception e) {
ErrorResponse error = new ErrorResponse("500", "系统内部错误");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
2. 定义统一的错误响应格式
为了前后端交互更清晰,建议封装一个通用的错误响应体:
立即学习“Java免费学习笔记(深入)”;
public class ErrorResponse {
private String code;
private String message;
public ErrorResponse(String code, String message) {
this.code = code;
this.message = message;
}
// getter 和 setter 省略
}
3. 自定义业务异常类
便于在业务逻辑中主动抛出有意义的异常:
public class BusinessException extends RuntimeException {
private String code;
public BusinessException(String code, String message) {
super(message);
this.code = code;
}
// getter 方法
public String getCode() {
return code;
}
}
在服务中使用:
if (user == null) {
throw new BusinessException("USER_NOT_FOUND", "用户不存在");
}
4. 注意事项与扩展
- @ControllerAdvice 默认扫描所有控制器,也可通过 basePackages 指定作用范围
- 若返回JSON数据,推荐使用 @RestControllerAdvice(相当于 @ControllerAdvice + @ResponseBody)
- 可结合日志框架(如Logback)记录异常堆栈,便于排查问题
- 对于非Controller层抛出的异常(如过滤器),需配合其他机制如Servlet容器错误页或WebFlux异常处理










