统一响应封装与错误码设计

zjc 于 2026-08-05 发布

后端接口如果没有统一响应结构,前端就要面对各种形状的数据:有的直接返回对象,有的返回字符串,出错时可能返回默认错误页。这个项目的做法是所有 REST 接口都返回 ApiResponse<T>

一、响应结构

{
  "success": true,
  "code": 0,
  "message": "操作成功",
  "data": {},
  "timestamp": 1723017600000
}

字段含义很直接:

二、错误码分段

0      成功
-1     通用失败
100    参数校验失败
101    请求体格式错误
102    资源不存在
401    未认证
403    无权限
500    服务内部错误
503    服务不可用

这个分段刻意和 HTTP 状态语义接近,但不是简单等同。业务服务内部失败时 HTTP 可以是 200,响应体里的 code 再表达具体业务结果。

三、用接口承接自定义错误码

标准错误码放在 ApiResponseEnum 中。业务模块要扩展自己的错误码时,不需要改公共枚举,只要实现 ErrorCode

public interface ErrorCode {
    int code();
    String message();
}

https://github.com/springvortex/spring-cloud-alibaba/blob/main/service-common/src/main/java/com/zjc/common/constant/ErrorCode.java

然后业务异常可以直接接收这个接口:

throw new BusinessException(ApiResponseEnum.USER_NOT_FOUND);

https://github.com/springvortex/spring-cloud-alibaba/blob/main/service-common/src/main/java/com/zjc/common/exception/BusinessException.java

这样公共模块只依赖抽象,不需要知道每个业务模块有哪些错误码。

四、静态工厂让调用侧更清楚

ApiResponse 提供了这些入口:

ApiResponse.success(data);
ApiResponse.successMessage("操作成功");
ApiResponse.failureMessage("参数非法");
ApiResponse.failure(ApiResponseEnum.NOT_FOUND);

https://github.com/springvortex/spring-cloud-alibaba/blob/main/service-common/src/main/java/com/zjc/common/web/ApiResponse.java

这里有个小设计点:successMessagefailureMessage 显式带 Message,避免当 T=String 时和 success(Object)failure(Object) 产生重载歧义。

五、避坑点

  1. 不要把数据库实体字段直接塞进错误提示。
  2. 未预期异常不要把完整堆栈返回给前端。
  3. success 字段判断要防 null,所以内部使用 Boolean.TRUE.equals(success)
  4. 前端不能只判断 HTTP 200,还要读取 successcode