wrapper 应为不可变结果载体,含 final 枚举 code、泛型 data、语义化静态工厂;分 baseresult、pageresult、validateresult 三层;支持 traceid、extra 扩展及 json 友好序列化。

设计一个通用、标准、可复用的面向对象统一返回值 Wrapper 对象,核心是**解耦业务逻辑与响应结构**,同时兼顾**类型安全、可扩展性、序列化友好和团队协作一致性**。它不该只是简单套个 code/msg/data 三层壳,而应体现明确的契约意识和分层职责。
明确 Wrapper 的核心契约与不可变性
Wrapper 应代表一次请求的完整响应语义,不是数据容器,而是“结果载体”。因此:
- 所有字段必须为 final,构造即完成,禁止 setter(避免状态污染和并发问题)
- 提供全参构造器 + 静态工厂方法(如 success() / fail() / of()),强制使用语义化创建路径
- code 应为枚举(如 ResultCode.SUCCESS、ResultCode.VALIDATE_ERROR),而非 magic number 或字符串,便于 IDE 提示、校验和国际化扩展
- data 字段泛型化(T),支持任意业务实体,且保留原始类型信息(利于 Jackson/Gson 正确反序列化)
分层设计:基础 Wrapper + 业务场景子类(按需)
不强求“一个 Wrapper 打天下”。推荐分两级:
-
BaseResult
:最简抽象,含 code、message、data、timestamp(可选)。作为所有返回值的顶层父类,供全局统一拦截器/过滤器识别 -
PageResult
:继承 BaseResult - >,额外封装 page、size、total、list 字段,专用于分页场景
-
ValidateResult:不带泛型,专用于参数校验失败,内含 List
,比笼统的 msg 更利于前端精准提示
这样既保持主干简洁,又让特殊场景有清晰归属,避免 BaseResult 膨胀成“上帝对象”。
深度集成 JSON 序列化与反序列化
Wrapper 必须对主流序列化框架(Jackson / Gson)透明友好:
- 为 code 枚举添加 @JsonValue 注解,确保序列化输出为数字码(非枚举名)
- 为 message 字段加 @JsonInclude(JsonInclude.Include.NON_EMPTY),空消息不输出,减小响应体积
- 若用 Lombok,禁用 @Data(会生成 setter),改用 @Value + @Builder(仅 builder 模式支持不可变构建)
- 在 Spring Boot 中,通过 @ControllerAdvice + ResponseEntity> 全局统一封装,避免每个 Controller 手动 new Wrapper
预留扩展点:上下文与元数据支持
生产级 Wrapper 需考虑诊断与灰度能力:
- 增加 traceId(String) 字段,从 MDC 或网关透传,方便全链路日志追踪
- 增加 extra(Map
) 字段(标注 @JsonAnyGetter/@JsonAnySetter),允许临时注入调试信息、灰度标识、降级原因等,不影响主结构 - 所有字段命名采用小驼峰(如 resultCode → code),与前端 JS 变量习惯一致,避免下划线转驼峰的序列化配置
不复杂但容易忽略











