Files
rui-docs/standards/Result统一响应类.md
vifo 1324a52049 docs(standards): 补充 Result<T> 统一响应类文档,修正 API 设计规范响应格式
- 新增 Result统一响应类.md 完整文档
- 修正 API设计规范.md 中响应字段与实际代码不一致的问题
- 错误码规范表按实际 ResultCode 枚举对齐
2026-06-08 16:01:33 +08:00

9.0 KiB
Raw Permalink Blame History

Result 统一响应类规范

RUI 框架所有 API 接口的统一返回包装


一、类信息

属性
包路径 com.rui.common.core.result.Result
所在模块 rui-common-core
泛型参数 <T> — data 字段的具体类型
序列化 实现 Serializable
JSON 策略 @JsonInclude(NON_NULL) — 值为 null 的字段自动忽略

二、响应结构

2.1 字段定义

字段 类型 说明 成功时 失败时
error int 状态码(0 = 成功) 0 非 0
message String 提示信息 "操作成功" 具体错误描述
code String 业务错误码 null(不输出) "AUTH_UNAUTHORIZED"
data T 业务数据 实际数据 通常为 null(不输出)

2.2 成功响应示例

无数据返回:

{
  "error": 0,
  "message": "操作成功"
}

带数据返回:

{
  "error": 0,
  "message": "操作成功",
  "data": {
    "id": 1001,
    "username": "admin"
  }
}

分页数据:

{
  "error": 0,
  "message": "操作成功",
  "data": {
    "records": [],
    "total": 100,
    "size": 10,
    "current": 1,
    "pages": 10
  }
}

2.3 失败响应示例

通用失败:

{
  "error": 1,
  "message": "操作失败"
}

带业务错误码:

{
  "error": 401,
  "message": "未授权",
  "code": "AUTH_UNAUTHORIZED"
}

带数据(未找到场景):

{
  "error": 404,
  "message": "数据不存在",
  "code": "DATA_NOT_FOUND",
  "data": "dictCode_001"
}

data 字段在 failNotFound 场景下用于传递资源 key,便于前端做国际化模板替换。


三、静态工厂方法

3.1 成功系列

方法签名 说明 使用场景
Result.ok() 无数据成功 删除、更新等不需要返回数据的操作
Result.ok(T data) 带数据成功 查询详情、列表、新增返回实体

3.2 失败系列

方法签名 说明 使用场景
Result.fail() 通用失败 兜底异常、未知错误
Result.fail(String message) 自定义提示 需要特定提示信息的业务异常
Result.fail(ResultCode resultCode) 枚举驱动 标准业务错误,推荐使用
Result.fail(int error, String message) 自定义错误码+提示 非标准错误场景
Result.fail(int error, String message, String code) 完全自定义 需要同时指定三个字段
Result.fail(ResultCode resultCode, T data) 枚举+数据 失败时需携带部分数据
Result.failNotFound(ResultCode resultCode, String key) 404 未找到 数据不存在,key 放入 data

3.3 判断方法

方法 说明
result.isSuccess() 判断是否成功(error == 0
result.toJsonString() 序列化为 JSON 字符串

四、ResultCode 枚举

4.1 枚举结构

属性 类型 说明
error int HTTP 风格状态码,0 为成功
message String 默认提示文本
code String 业务错误码(大写蛇形,模块前缀)

4.2 枚举值一览

枚举值 error message code 说明
SUCCESS 0 操作成功 null 成功
FAILURE 1 操作失败 null 通用失败
UNAUTHORIZED 401 未授权 AUTH_UNAUTHORIZED 未登录
FORBIDDEN 403 无权限 AUTH_FORBIDDEN 无权限
NOT_FOUND 404 资源不存在 COMMON_NOT_FOUND 资源未找到
DATA_NOT_FOUND 404 数据不存在 DATA_NOT_FOUND 数据未找到
VALIDATE_FAILED 400 参数校验失败 COMMON_VALIDATE_FAILED 参数错误
TOKEN_EXPIRED 4001 Token 已过期 AUTH_TOKEN_EXPIRED Token 过期
TOKEN_INVALID 4002 Token 无效 AUTH_TOKEN_INVALID Token 无效
TENANT_NOT_FOUND 4003 租户不存在 AUTH_TENANT_NOT_FOUND 租户不存在
TENANT_DISABLED 4004 租户已禁用 AUTH_TENANT_DISABLED 租户禁用
USER_NOT_FOUND 4101 用户不存在 USER_INFO_NOT_FOUND 用户不存在
USERNAME_EXISTS 4102 用户名已存在 USER_INFO_USERNAME_EXISTS 用户名重复
LEVEL_CODE_EXISTS 4201 等级编码已存在 USER_LEVEL_CODE_EXISTS 等级编码重复

4.3 错误码规划规则

区间 模块 code 前缀
0 通用成功
1 通用失败
400-499 HTTP 标准错误 COMMON_* / AUTH_*
4000-4099 认证错误 AUTH_*
4100-4199 用户信息错误 USER_INFO_*
4200-4299 用户等级错误 USER_LEVEL_*
5000-5999 文件模块(预留) FILE_*
6000-6999 消息模块(预留) MSG_*

新增规则:新模块取 100 的整数倍区间,code 格式为 {模块}_{业务}_{具体}


五、Controller 使用示例

5.1 标准 CRUD

@RestController
@RequestMapping("/v1/system/roles")
@RequiredArgsConstructor
public class SysRoleController {

    private final SysRoleService roleService;

    @GetMapping
    public Result<IPage<SysRoleVO>> list(SysRoleQuery query) {
        return Result.ok(roleService.page(query));
    }

    @GetMapping("/{id}")
    public Result<SysRoleVO> getById(@PathVariable Long id) {
        SysRoleVO role = roleService.getById(id);
        if (role == null) {
            return Result.failNotFound(ResultCode.DATA_NOT_FOUND, String.valueOf(id));
        }
        return Result.ok(role);
    }

    @PostMapping
    public Result<SysRoleVO> create(@RequestBody @Valid SysRoleDTO dto) {
        return Result.ok(roleService.create(dto));
    }

    @PutMapping("/{id}")
    public Result<SysRoleVO> update(@PathVariable Long id, @RequestBody @Valid SysRoleDTO dto) {
        return Result.ok(roleService.update(id, dto));
    }

    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable Long id) {
        roleService.delete(id);
        return Result.ok();
    }
}

5.2 异常处理中返回

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BizException.class)
    public Result<Void> handleBizException(BizException e) {
        return Result.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleValidation(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldErrors().stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.joining(", "));
        return Result.fail(ResultCode.VALIDATE_FAILED.getError(), message, ResultCode.VALIDATE_FAILED.getCode());
    }
}

5.3 Feign 远程调用中处理 Result

@Service
@RequiredArgsConstructor
public class UserRemoteService {

    private final RemoteUserService remoteUserService;

    public UserVO getUserById(Long userId) {
        Result<UserVO> result = remoteUserService.getById(userId);
        if (result.isSuccess()) {
            return result.getData();
        }
        throw new BizException(result.getError(), result.getMessage());
    }
}

六、前端对接指南

6.1 判断成功

// response.data 为 Result<T> 结构
const isSuccess = response.data.error === 0;

6.2 错误处理

if (result.error !== 0) {
    // 优先用 code 做国际化
    if (result.code) {
        showI18nMessage(result.code, { key: result.data });
    } else {
        // 降级显示 message
        showMessage(result.message);
    }
}

6.3 TypeScript 类型定义

interface Result<T = any> {
    error: number;
    message: string;
    code?: string;       // 失败时存在
    data?: T;            // 成功时或 failNotFound 时存在
}

七、扩展指南

7.1 新增 ResultCode

ResultCode 枚举中添加新值,遵循以下规则:

  1. error 取值:按模块区间分配(见 4.3 节)
  2. code 命名{模块}_{业务}_{具体},全大写蛇形
  3. 向后兼容:禁止修改已有枚举值的 error 或 code
// 示例:文件模块新增
FILE_UPLOAD_FAILED(5001, "文件上传失败", "FILE_UPLOAD_FAILED"),
FILE_SIZE_EXCEEDED(5002, "文件大小超限", "FILE_SIZE_EXCEEDED"),

7.2 禁止事项

  • 不要在 Controller 中直接 new Result<>(),必须使用静态工厂方法
  • 不要修改 Result 类的字段名(error/message/code/data),影响序列化兼容
  • 不要用 error 字段传递 HTTP 状态码(它只是业务状态码,HTTP 状态码由框架控制)
  • 不要在 code 字段中使用小写或特殊字符

文档版本: v1.0 创建日期: 2026-06-08 源码位置: rui-common/rui-common-core/src/main/java/com/rui/common/core/result/ 适用范围: RUI 框架所有模块的 API 响应