@restcontrolleradvice 配合 @exceptionhandler 可集中统一处理异常,替代 controller 中散乱的 try-catch;通过定义全局异常处理器、多类型 @exceptionhandler 方法、统一响应格式、自定义业务异常及日志监控联动,实现逻辑清晰、职责单一、易于排查与监控。

用 @RestControllerAdvice 配合 @ExceptionHandler,就能把散落在各 Controller 里的 try-catch 全部收走,让异常处理逻辑集中、清晰、可维护。
统一拦截器怎么写
定义一个全局异常处理器类,加上 @RestControllerAdvice 注解,它会自动生效于所有 Controller。里面用多个 @ExceptionHandler 方法分别捕获不同异常类型:
- 捕获
Exception处理兜底错误,返回通用系统错误码 - 单独捕获
UserNotFoundException,返回 404 和友好提示 - 再写一个处理
IllegalArgumentException的方法,用于参数校验失败场景
每个方法都返回统一格式的响应对象(如 CommonResult.error(...)),前端始终收到结构一致的 JSON。
为什么比 try-catch 更干净
原来 Controller 里可能这样写:
@GetMapping("/user/{id}")
public ResponseEntity<user> getUser(@PathVariable Long id) {
try {
User user = userService.findById(id);
return ResponseEntity.ok(user);
} catch (UserNotFoundException e) {
log.error("用户不存在", e);
return ResponseEntity.status(404).body(null);
}
}</user>
现在 Controller 只保留核心逻辑:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id); // 异常直接抛出
}
业务代码不再掺杂日志、状态码、响应体包装等横切关注点,职责更单一。
配合自定义业务异常效果更好
提前定义几个语义明确的异常类,比如:
-
UserNotExistException(继承RuntimeException) InsufficientBalanceException
在 service 层直接 throw new UserNotExistException("用户ID: " + id)。拦截器中对应写一个 @ExceptionHandler(UserNotExistException.class) 方法,就能精准返回 404 + 自定义消息,不需要在 Controller 判断 if-else 或做字符串匹配。
别忘了日志和监控联动
在拦截器的方法里,统一记录 ERROR 级别日志,并带上异常堆栈和请求上下文(如 traceId、URL、参数):
- 用 SLF4J 的
logger.error("请求异常: {}", e.getMessage(), e),确保堆栈不丢失 - 调用监控 SDK 上报异常类型和频次,便于及时发现线上问题
- 对某些关键异常(如数据库连接失败),还可触发告警
所有异常出口一致,排查、统计、告警都变得简单可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










