Java全局异常处理需用@RestControllerAdvice(或@ControllerAdvice+@ResponseBody)统一捕获Controller异常,按MethodArgumentNotValidException、运行时异常、Exception顺序分层处理,结合BusinessException区分业务与系统错误,响应必须统一为Result格式。

Java 中通过全局异常处理器统一拦截并响应系统错误,核心是用 @RestControllerAdvice 集中捕获 Controller 层抛出的异常,并返回结构一致的 JSON 响应,避免错误信息泄露、重复 try-catch 和响应格式混乱。
必须用 @RestControllerAdvice(或 @ControllerAdvice + @ResponseBody)
只加 @ControllerAdvice 不够——Spring 会默认尝试走视图解析(比如跳转 error.html),导致 Circular view path 错误。正确做法是:
- 直接使用 @RestControllerAdvice(推荐),它自动携带 @ResponseBody,专为 REST 接口设计
- 或组合写法:@ControllerAdvice + @ResponseBody 注解在方法上
按异常类型分层捕获,别只抓 Exception.class
宽泛捕获 Exception 容易掩盖真实问题,应从细到粗排列处理顺序:
-
参数校验异常:如
MethodArgumentNotValidException,提取字段名和提示语,返回 400 + 字段级错误信息 -
系统运行时异常:如
NullPointerException、NumberFormatException、SQLException,分别映射不同错误码与用户友好提示 -
兜底捕获:最后用
@ExceptionHandler(Exception.class)记录完整日志,返回通用服务异常(如 code=500, msg="系统繁忙,请稍后再试")
配合自定义业务异常,区分“技术问题”和“业务规则不满足”
系统异常反映代码缺陷,业务异常体现合法但失败的业务场景(如“库存不足”“手机号已注册”)。建议:
立即学习“Java免费学习笔记(深入)”;
- 定义 BusinessException extends RuntimeException,带
code和msg构造参数 - 在 Service 层主动抛出:
throw new BusinessException(4001, "库存不足") - 在全局处理器中单独捕获:
@ExceptionHandler(BusinessException.class),直接转为Result.fail(e.getCode(), e.getMessage())
确保响应结构与正常接口完全一致
前端只认一种格式,异常响应不能是 Map、String 或 ModelAndView。必须统一使用项目约定的响应体,例如:
- 成功时返回:
Result.success(data) - 失败时返回:
Result.fail(code, msg)(不是 new Result(...), 也不是 ResponseEntity) - 若用了 Lombok 的
@Data,记得给Result加无参构造,否则 Jackson 反序列化可能失败


















