@ControllerAdvice统一捕获Web异常需搭配@ResponseBody或直接用@RestControllerAdvice,按异常类型分层处理:先校验异常、再系统异常、最后兜底Exception,配合自定义BusinessException实现业务语义清晰,返回结构须与正常接口一致的Result.fail()。

用 @ControllerAdvice 统一捕获 Web 错误,核心是把所有控制器层抛出的异常集中拦截、格式化、返回标准响应,不侵入业务代码。
必须加 @ResponseBody 或用 @RestControllerAdvice
如果只写 @ControllerAdvice,Spring 默认尝试走视图解析(比如跳转 error.jsp),会报 Circular view path 错误。解决方式有两种:
-
@ControllerAdvice + @ResponseBody组合使用 - 直接用
@RestControllerAdvice(推荐),它等价于两者合体,自动返回 JSON
按异常类型分层处理,别只捕一个 Exception.class
捕获太宽泛的 Exception.class 容易掩盖具体问题,建议按优先级从细到粗排列:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 先处理参数校验异常:
@ExceptionHandler(MethodArgumentNotValidException.class),提取 BindingResult 中的错误字段和提示 - 再处理空指针、数字格式、SQL 等系统异常,分别返回不同 code 和 msg
- 最后兜底捕获
Exception.class,记录日志并返回通用服务异常
配合自定义业务异常,让错误语义更清晰
系统异常反映技术问题,业务异常反映逻辑规则不满足(如“余额不足”“用户已存在”)。定义一个继承 RuntimeException 的 BusinessException,带 code 和 msg 字段:
立即学习“Java免费学习笔记(深入)”;
- 在 service 层主动
throw new BusinessException(4001, "库存不足") - 在全局处理器里用
@ExceptionHandler(BusinessException.class)单独捕获,直接映射到 Result 的 code/msg
确保返回结构和正常接口完全一致
前端只认一种格式,异常响应必须和 success() 返回的 Result 结构对齐:
- 统一用
Result.fail(code, msg)构造失败响应 - 不要在异常处理器里返回 Map、String 或 ModelAndView(除非明确要跳转页面)
- 如果用了 Lombok 的
@Data,记得给Result加无参构造,避免 Jackson 反序列化失败

















