spring boot 统一错误响应需语义分离与协议驱动:定义专用errorresponse类,精简字段为status、message、errors,禁用timestamp/data/code等混淆字段;@restcontrolleradvice中精准映射异常至对应httpstatus,返回responseentity;前端依http状态码判断错误,而非解析body。

Spring Boot 中统一返回标准的错误响应,核心是**语义分离 + 协议驱动**:错误响应必须与成功响应结构隔离,且 HTTP 状态码要真实反映错误类型,不能靠响应体里的 code 字段“模拟”状态。
明确区分错误响应类
定义专用于异常场景的 ErrorResponse,不复用 ApiResponse:
- 字段精简:只保留 status(HTTP 状态码)、message(用户/运维可读提示)、errors(可选,用于参数校验等结构化错误)
- 避免堆叠字段:不加 timestamp、data、code 等混淆语义的字段;stackTrace 仅开发环境开启,生产环境禁用
- 构造逻辑清晰:每个构造器对应一类错误,比如
ErrorResponse.of(HttpStatus.BAD_REQUEST, "参数格式错误")
用 @RestControllerAdvice 统一捕获并转换
全局异常处理器不返回 ResponseEntity
- 对不同异常类型做精准映射:400 对应 MethodArgumentNotValidException,404 对应 EntityNotFoundException,500 对应 RuntimeException
- 状态码必须由 HttpStatus 枚举决定,不是硬编码数字;例如
ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(404, "资源不存在")) - 避免在异常处理器里再 throw 新异常,防止二次拦截导致状态码错乱
前端依据 status 判断,而非解析 body
这是 RESTful 的关键实践:
- 前端收到 4xx/5xx 响应时,直接读取 response.status 和 response.data.message,不尝试从 data 字段提取业务数据
- Swagger/OpenAPI 文档能自动生成准确的 error responses,便于契约协作
- 监控系统(如 Prometheus + Grafana)可通过 HTTP 状态码直观看错误分布,无需解析 JSON 内容
不推荐的常见误区
这些做法看似“统一”,实则破坏分层语义:
- 让所有接口(包括异常)都返回 ResponseEntity
,错误时把 data 设为 null、code 设为 400 —— 这违背 HTTP 协议,前端无法靠 status 拦截错误 - 在 ErrorResponse 里塞入 ApiResponse 相同的字段(如 timestamp、code),造成客户端需写两套解析逻辑
- 全局异常处理器中返回 200 状态码 + 错误 message —— 掩盖真实问题,日志和网关无法识别故障











