spring boot全局异常处理三步法:一定义统一响应体(含code、message、data、timestamp及静态工厂方法);二用@restcontrolleradvice捕获各类异常并返回result;三配套自定义业务异常、参数校验处理与带traceid的error日志。

直接上手,别绕弯——Spring Boot 全局异常处理的学习路径,核心就三步:先定义清楚“返回什么”,再写好“捕获谁、怎么回”,最后补上“业务怎么抛、日志怎么记”。不靠死记硬背,靠结构化实践。
第一步:定好统一响应体(Result 或 ApiResponse)
这是所有异常处理的基石。没有它,后面再花哨也没用。前端要的是稳定格式,不是每次都要猜字段名。
- 必须包含三个字段:code(业务码,不是HTTP状态码)、message(给用户或前端看的提示)、data(成功时带数据,失败时为 null)
- 加一个 timestamp 字段,线上排查问题时能快速对齐时间点
- 提供静态工厂方法:
success()和error(code, msg),Controller里直接调用,不 new 对象 - 避免用 Map 做返回体,类型不安全,IDE 不提示,后期加字段容易漏改
第二步:写全局异常处理器(@RestControllerAdvice)
它就像一个守门员,所有 Controller 抛出的异常都会被它拦下,按类型分发处理。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用
@RestControllerAdvice标记类,不用@ControllerAdvice + @ResponseBody拆开写 - 每个
@ExceptionHandler方法只处理一种异常类型,比如:@ExceptionHandler(BusinessException.class)处理业务异常,@ExceptionHandler(MethodArgumentNotValidException.class)处理参数校验失败 - 系统异常(如 NullPointerException)建议兜底处理,但不要直接返回堆栈信息,可记录日志后返回通用错误码(如 50001)和模糊提示(如“系统繁忙,请稍后再试”)
- 方法返回值统一用你第一步定义的 Result 类型,保持前后端契约一致
第三步:补全配套能力(自定义异常 + 日志 + 校验)
光有处理器不够,得让整个链路跑得顺、查得清、改得快。
- 业务异常不要直接 throw new RuntimeException("xxx"),而是封装成
BusinessException(40001, "用户名已存在"),code 可对应枚举,便于统一维护 - 参数校验失败(@Valid + 实体类注解)默认抛
MethodArgumentNotValidException,需单独捕获,提取BindingResult中的首个错误消息,避免返回一长串校验详情 - 每条异常日志必须带 traceId(用 MDC),否则分布式环境下根本没法串联请求;建议在异常处理器里统一打 ERROR 级别日志,含异常类型、code、message、完整堆栈
- 测试时用 Postman 或 curl 主动触发各种异常场景,比如传空字符串、超长字段、非法邮箱,验证返回是否符合预期
学完这三步,你就已经覆盖了 90% 的真实项目需求。后续优化可以围绕异常码分级、国际化提示、告警联动做,但基础框架已经立住了。










