Spring Boot 动态字段过滤有三类方式:①@JsonView 静态视图,适合固定字段组合;②自定义注解+JsonSerializer,支持URL参数动态控制;③Filter/网关层JSON裁剪,零侵入旧系统。

Spring Boot 中 REST 接口实现动态字段过滤,核心目标是:**同一接口、不同场景下返回不同字段组合,不改实体、不写多个 DTO、不引入 GraphQL 全栈**。实际落地有三类主流方式,按侵入性由低到高、适用性由稳到活排列。
@JsonView 注解驱动的静态视图控制
适合字段组合固定、角色/端侧明确的场景(如「APP 简版用户」vs「管理后台全量用户」)。它基于 Jackson 内置机制,零额外依赖,启动快、调试直观。
- 在实体类中定义嵌套接口作为“视图标识”,例如:public interface PublicView {}、public interface AdminView extends PublicView {}
- 用 @JsonView 标注字段,比如 @JsonView(PublicView.class) private String username;,@JsonView(AdminView.class) private String lastLoginIp;
- Controller 方法直接加 @JsonView(PublicView.class),返回对象时 Jackson 自动裁剪
自定义注解 + JsonSerializer 动态拦截
适合需要运行时传参控制字段(如 URL 参数 ?fields=id,name,email),且对灵活性要求高、但不想动网关或前端调用逻辑的项目。
- 定义一个 @JsonFieldFilter 注解,支持接收字段白名单字符串数组
- 编写继承 JsonSerializer<Object> 的序列化器,在 serialize() 中根据当前线程绑定的字段列表,跳过未授权字段
- 通过 @ControllerAdvice 或 AOP 在进入 Controller 前解析请求参数,将字段列表存入 ThreadLocal,供序列化器读取
网关层或 Filter 统一 JSON 裁剪
适合已有大量旧接口、无法修改 Controller 层代码,或希望统一治理响应格式的中大型系统。把字段过滤逻辑下沉到请求生命周期靠前的位置,对业务代码零侵入。
- 写一个 OncePerRequestFilter,在 doFilterInternal() 中拦截响应体流
- 使用 Jackson ObjectMapper 反序列化原始 JSON 为 JsonNode,再按规则递归删除不需要的字段(例如匹配 fields=id,profile.avatar 参数)
- 重写响应输出流,把裁剪后的 JSON 写回客户端;注意处理 Content-Length 和字符编码
三种方式不是互斥的。小项目用 @JsonView 就够用;中台服务常组合自定义注解 + Filter 做兜底;若已用 Spring Cloud Gateway,也可在网关里用 Groovy 或 Java Filter 实现字段投影。关键不在技术多炫,而在选准边界——字段谁来决定(前端传?后端配置?角色驱动?)、裁剪时机(序列化前?响应后?)、以及是否接受轻微性能开销。


















