Spring Boot 3 全局异常处理采用 ErrorResponse 统一结构,通过 @RestControllerAdvice 分层捕获异常并返回 ResponseEntity<ErrorResponse>,确保状态码驱动、职责分离、不可变性及可观测性。

Spring Boot 3 中通过 ErrorResponse 实现全局异常处理,核心是“统一结构 + 状态驱动 + 职责分离”。不靠 try-catch 堆砌,也不用一个泛型类硬套所有场景,而是让成功响应和错误响应走各自清晰的路径,HTTP 状态码成为前端判断成败的第一依据。
定义清晰独立的 ErrorResponse 类
它只承载错误语义,不含业务数据字段,避免与成功响应混淆:
- 包含 status(HTTP 状态码数值)、message(用户友好提示)、errors(可选,如参数校验失败的具体字段列表) 和 timestamp(便于问题追踪)
- 不继承或复用 ApiResponse,不设 data 字段;否则前端解析时容易误判“500 错误体里居然有 data”,引发逻辑混乱
- 推荐使用 final 字段 + 构造器初始化,确保不可变性,避免运行时被意外修改
用 @RestControllerAdvice 搭建全局拦截入口
这是 Spring Boot 3 全局异常处理的“中枢”——它自动作用于所有 @RestController 方法,无需额外配置:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 必须加 @RestControllerAdvice(不是 @ControllerAdvice),才能默认返回 JSON,省去每个方法加 @ResponseBody
- 可配合 @Order(Ordered.HIGHEST_PRECEDENCE) 控制优先级,尤其在多模块共存时防止被其他 Advice 覆盖
- 类名建议为 GlobalExceptionHandler 或类似明确语义的名称,便于团队识别
按异常类型分层编写 @ExceptionHandler 方法
每个方法专注一类异常,返回 ResponseEntity<ErrorResponse>,并配对应 HTTP 状态码:
- 业务异常(如 BusinessException):用 400 或自定义 4xx 码,message 来自枚举或构造参数,code 字段可额外带业务错误码(如 "USER_NOT_FOUND")
- 参数校验异常(MethodArgumentNotValidException):提取 BindingResult 的第一个或全部 DefaultMessage,组装成 errors 列表,返回 400
- 资源未找到(EntityNotFoundException / ResourceNotFoundException):返回 404,message 可动态拼接资源名(如 "用户 ID=123 不存在")
- 兜底异常(Exception.class):记录完整堆栈日志(用 logger.error("Uncaught exception", ex)),返回 500,并 message 固定为"系统繁忙,请稍后重试",绝不暴露技术细节
配合统一日志与监控增强可观测性
异常处理不只是返回 JSON,更是问题定位的第一环:
- 每个 @ExceptionHandler 方法开头生成唯一 traceId(如 UUID),打到日志和 ErrorResponse 的扩展字段中,方便前后端联查
- 对 4xx 异常可降低日志级别(warn),5xx 必须 error 级别并触发告警(如接入 Prometheus Alertmanager)
- 在 ErrorResponse 中预留 detail 字段(仅开发/测试环境填充堆栈摘要),生产环境留空或填占位符,兼顾安全与调试

















