使用泛型Wrapper统一包装接口返回值,通过不可变设计和静态工厂方法(如success/fail)封装状态码、消息及泛型数据;结合@ControllerAdvice与@ResponseBodyAdvice自动包装非Wrapper返回值,并统一拦截异常转为Wrapper响应,支持分页等扩展场景。
用泛型 wrapper 包装接口返回值,配合合理设计的数据结构,能自然实现统一状态码、消息、数据体的装配,避免每个接口手动组装 json 或重复写 success/fail 逻辑。
定义泛型响应 Wrapper 类
核心是封装一个可指定数据类型的响应结构,包含状态码、提示信息、业务数据等字段。推荐使用不可变设计(final 字段 + 构造器),并提供常用静态工厂方法:
- code:int 类型状态码(如 200、400、500)
- message:String 提示语(成功时可为 "OK",失败时带具体原因)
- data:泛型 T,表示真实业务返回对象(可为 null,如删除接口无需返回实体)
- 提供 success(T data)、fail(int code, String msg)、fail(BizException e) 等便捷构造方式
与 Spring Web 集成:全局统一响应包装
借助 Spring 的 @ControllerAdvice + @ResponseBodyAdvice,自动将控制器方法的返回值(非 Wrapper 类型)包装成 Wrapper:
- 实现
ResponseBodyAdvice<Object>,重写supports()过滤掉已返回 Wrapper 的接口(避免套娃) - 在
beforeBodyWrite()中判断原返回值是否为 void / null / Wrapper 子类,跳过包装;否则用Wrapper.success(result)封装 - 这样所有
@GetMapping("/user") public User getUser()自动变成Wrapper<User>响应
异常统一拦截并转为 Wrapper 响应
定义业务异常(如 BizException extends RuntimeException),并在 @ControllerAdvice 中统一处理:
- 捕获
BizException,提取其 code 和 message,调用Wrapper.fail(ex.getCode(), ex.getMessage()) - 对
NullPointerException、IllegalArgumentException等预设默认错误码(如 400)和提示 - 未捕获异常兜底为 500,并记录日志,不暴露堆栈给前端
支持分页、列表等常见结构的泛型扩展
单一 Wrapper<T> 不足以覆盖分页场景。可补充:
-
PageWrapper<T>:继承 Wrapper,额外含total、pages、list: List<T>字段 - 或保持 Wrapper 单一职责,让 controller 返回
Wrapper<PageResult<User>>,其中PageResult是独立分页数据结构 - 关键点:Wrapper 泛型参数支持任意类型,包括自定义 VO、DTO、嵌套泛型(如
Wrapper<List<User>>),无需额外适配

















