spring boot全局异常处理器通过@restcontrolleradvice和@exceptionhandler配置:前者定义全局增强类,后者指定异常处理方法,可分别处理nullpointerexception、自定义业务异常及兜底exception,返回统一json格式响应。

在 Spring Boot 或 Spring MVC 中,@ExceptionHandler 是处理控制器层异常的核心注解,它能让你针对特定异常类型(如 NullPointerException、自定义业务异常等)编写专门的响应逻辑,避免异常堆栈暴露给前端,同时统一返回结构化错误信息。
一、基础用法:在 Controller 内处理本类抛出的异常
最简单的用法是把 @ExceptionHandler 方法写在某个 @Controller 或 @RestController 类中,只捕获该控制器内抛出的指定异常:
- 方法参数可以是异常类型(如
IllegalArgumentException e),Spring 会自动注入;也可加HttpServletRequest、HttpServletResponse等上下文对象 - 返回值通常是
ResponseEntity>或普通对象(由@ResponseBody自动序列化),推荐用ResponseEntity精确控制状态码和 body - 一个方法可声明多个异常类型,用逗号分隔:
@ExceptionHandler({IOException.class, SQLException.class})
示例:
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
if (id handleIllegalArgument(IllegalArgumentException e) {
ErrorResponse error = new ErrorResponse("BAD_REQUEST", e.getMessage());
return ResponseEntity.badRequest().body(error);
}
}
二、全局异常处理:用 @ControllerAdvice + @ExceptionHandler
如果希望一套异常处理逻辑覆盖整个应用(所有 Controller),应使用 @ControllerAdvice 配合 @ExceptionHandler。它本质是一个“增强的控制器通知”,会在所有 @RequestMapping 方法执行后、返回前介入异常流程。
-
@ControllerAdvice类默认作用于所有@Controller,也可通过basePackages或annotations属性限定范围 - 支持
@ResponseBody,所以常与@RestControllerAdvice(即@ControllerAdvice + @ResponseBody)一起使用,直接返回 JSON - 可配合
@Order控制多个@ControllerAdvice的优先级(数值越小优先级越高)
示例:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<errorresponse> handleUserNotFound(UserNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("USER_NOT_FOUND", e.getMessage()));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<errorresponse> handleValidation(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.findFirst().orElse("Validation failed");
return ResponseEntity.badRequest().body(new ErrorResponse("VALIDATION_ERROR", message));
}
}</errorresponse></errorresponse>
三、处理多种异常并统一响应结构
实际项目中建议定义统一错误响应体(如 ErrorResponse),并在不同 @ExceptionHandler 方法中填充对应 code、message 和 timestamp,保持 API 错误格式一致:
public class ErrorResponse {
private String code;
private String message;
private long timestamp;
public ErrorResponse(String code, String message) {
this.code = code;
this.message = message;
this.timestamp = System.currentTimeMillis();
}
// getter/setter 略
}
- 对系统级异常(如
NullPointerException)建议记录日志并返回通用错误码(如"INTERNAL_ERROR"),不暴露内部细节 - 对已知业务异常(如
UserAlreadyExistsException),应返回明确业务码和用户友好的提示 - 可结合
@ResponseStatus注解简化状态码设置(但不如ResponseEntity灵活)
四、注意事项与常见问题
异常继承关系会影响匹配:若你捕获 RuntimeException,那么它的子类(如 IllegalArgumentException)也会被该处理器捕获——除非有更具体的 @ExceptionHandler 方法优先匹配(Spring 按异常类型精确度从高到低选择)。
- 确保自定义异常类没有被其他全局处理器意外吞掉;可通过日志或调试确认哪个
@ExceptionHandler被触发 - 不要在
@ExceptionHandler方法里再抛异常,否则可能进入无限循环或 fallback 到默认错误页 - 若用了 Spring Security,注意未认证/未授权异常(如
AuthenticationException)通常由 Security 的过滤器链处理,不在@ExceptionHandler范围内,需配置AuthenticationEntryPoint或AccessDeniedHandler
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











