使用泛型result类及配套静态工厂方法可统一接口返回结构:含code、message、泛型data和timestamp,支持自动类型推断与分层扩展(如pageresult),结合responsebodyadvice实现零侵入式自动包装。

直接用泛型类定义 Result<t></t>,再配一套泛型静态方法,就能让所有接口返回值自动带状态码、提示和类型安全的数据体,不用为每个业务对象写单独的结果类。
泛型类是骨架:定义 Result 的不可变结构
Wrapper 的核心是一个参数化类,T 代表任意业务数据类型,比如 User、List<order></order>、Void。字段全部声明为 final,确保构造即完成、线程安全、语义清晰:
-
private final int code;—— 业务状态码(非 HTTP 状态码),整数便于前端 switch 判断 -
private final String message;—— 用户或开发者可见的提示,空时可忽略输出 -
private final T data;—— 泛型承载真实数据,支持 null、对象、集合、甚至 void -
private final long timestamp;—— 推荐带上,毫秒级时间戳,利于排障与缓存控制
不提供 public setter,禁用 @Data;推荐用 @Value + 全参构造器,或搭配 @Builder 支持分步构建。
泛型方法是灵魂:让 success/fail 自动适配调用处类型
静态工厂方法必须是泛型的,否则会掉进 Result<object></object> 和 Result<user></user> 类型不兼容的坑:
-
public static <t> Result<t> success(T data)</t></t>→ code=200, message="OK" -
public static <t> Result<t> success()</t></t>→ data=null,适合删除、提交等无返回体操作 -
public static <t> Result<t> fail(int code, String message)</t></t>→ data=null -
public static <t> Result<t> fail(ResultCodeEnum enum)</t></t>→ 从枚举取 code/message,集中管理、支持国际化 -
public static <t> Result<t> of(int code, String message, T data)</t></t>→ 兜底全参方法
这样写接口时完全自然:return Result.success(user); → 推断为 Result<user></user>return Result.fail(404, "用户不存在"); → 推断为 Result<user></user>(data 为 null,但类型一致)
分层扩展不臃肿:BaseResult + 场景子类
一个 Wrapper 打天下容易失控。推荐分两级设计:
-
BaseResult<t></t>:最简抽象,含 code/message/data/timestamp,作为所有响应的顶层父类 -
PageResult<t></t>:继承BaseResult<list>></list>,额外封装total、pageNo、pageSize、list字段,专用于分页 -
ValidateResult:不带泛型,内含List<fielderror></fielderror>,比单条 message 更利于前端表单精准标红
Controller 可按需返回:Result<user></user>、Result<pageresult>></pageresult>、ValidateResult,各司其职,不污染主干。
自动包装靠 Spring:@ResponseBodyAdvice 是关键粘合剂
真正实现“写啥返回啥”,靠的是 Spring 的响应体增强机制:
- 实现
ResponseBodyAdvice<object></object>,重写supports()跳过已返回Result子类的接口(防套娃) - 在
beforeBodyWrite()中判断原返回值:
✓ 是null或void→ 包装成Result.success()
✓ 是普通对象(如User、List)→ 包装成Result.success(data)
✓ 是Result子类 → 直接放行 - 配合
@ControllerAdvice拦截异常:捕获BizException并转为Result.fail(ex.getCode(), ex.getMsg()),系统异常兜底为 500
从此 Controller 方法只管业务逻辑,不再手动 new Result,也不拼 map 或 json。











