JsonView:你的字段隐私管家

124 阅读3分钟

开发日常之《你的字段太暴露了》

  • 产品经理:用户列表接口里怎么能返回用户余额字段?!
  • 后端:这是给管理员的...
  • 测试:普通用户调用接口居然看到同事的工资条了!
  • 运维:这周第三次数据库泄露警告了...
  • 你:(抱头)我只是想少写点代码啊!

此时,JsonView就像你的瑞士军刀闪亮登场!接下来进入正题:


一、JsonView:你的字段隐私管家

1.1 基础人设

  • 官方定位:Spring对Jackson的视图渲染支持
  • 核心技能:同一对象在不同场景展示不同字段(如同一个用户对象,管理员可见薪资,普通用户只能看昵称)
  • 必杀技:无侵入式字段控制,无需DTO分身术

1.2 使用三连击

Step 1:定义视图接口(VIP会员卡等级)

public class UserView {
    public interface Basic {} // 普通卡
    public interface Admin extends Basic {} // 钻石卡
}

Step 2:实体类打标签(给字段发通行证)

public class User {
    @JsonView(UserView.Basic.class)
    private String username;
    
    @JsonView(UserView.Admin.class)
    private BigDecimal salary;
    
    // 没标签的字段默认不暴露
    private String securityQuestion;
}

Step 3:Controller指定视图(验票入场)

@GetMapping("/user/basic")
@JsonView(UserView.Basic.class)
public User getUserBasic() {
    return userService.findUser();
}

@GetMapping("/user/admin")
@JsonView(UserView.Admin.class) 
public User getUserAdmin() {
    return userService.findUser();
}

二、原理揭秘:JsonView的千层套路

2.1 执行流程图解

[你的Controller] 
  → (发射对象) 
    → [MappingJackson2HttpMessageConverter] 
      → (掏出小本本查@JsonView注解) 
        → (呼叫Jackson的序列化器) 
          → (按视图规则过滤字段) 
            → (生成定制版JSON)

2.2 关键技术点

  • 视图继承机制:子视图自动包含父视图字段(类似VIP等级叠加)
  • 空视图处理:不指定@JsonView时展示所有无视图限制的字段
  • 多重注解:支持在类/方法/字段多级声明

三、华山论剑:JsonView vs 其他方案

方案优点缺点适用场景
JsonView零重复代码学习曲线略高简单权限场景
DTO完全控制数据结构类爆炸风险复杂业务场景
@JsonIgnore简单粗暴全局生效不够灵活永久隐藏字段
JsonFilter动态过滤配置复杂需要运行时决策

四、避坑宝典:那些年我们掉过的坑

4.1 幽灵字段出没

现象:明明加了@JsonView,某些字段还是泄露了
真相:Controller方法忘记加@JsonView注解,导致视图未激活

4.2 继承失效之谜

错误示范

public interface Admin {} // 没有继承Basic

正确姿势

public interface Admin extends Basic {}

4.3 多视图叠加的灾难

@JsonView({ViewA.class, ViewB.class}) // 这会导致字段取并集!
public User getUser() {...}

五、最佳实践:老司机的导航路线

  1. 视图层级设计:建议采用金字塔结构
    PublicView → InternalView → AdminView
    
  2. 组合使用技巧
    @JsonView(View.Admin.class)
    @JsonIgnoreProperties("password") // 双重保险
    public class User {...}
    
  3. 文档规范:在视图接口添加详细注释
    /**
     * 包含用户敏感信息
     * @apiNote 仅限管理员接口使用
     */
    public interface AdminView {...}
    

六、面试考点精讲

高频题1:JsonView与DTO如何选择?
✨ 参考话术:
"DTO适合需要完全重塑数据结构的场景,比如组合多个领域对象的数据。而JsonView更适用于同一对象在不同场景需要展示不同字段的情况,能有效减少类爆炸问题。从维护成本考虑,简单的字段控制优先考虑JsonView。"

高频题2:为什么我的@JsonView注解不生效?
✨ 排查清单:

  1. 检查是否启用@EnableWebMvc
  2. 确认Controller方法添加了@JsonView
  3. 验证视图接口继承关系
  4. 确保Jackson版本≥2.8

七、总结:选择你的武器

JsonView就像智能窗帘:

  • ✅ 简单权限场景的首选
  • ✅ 减少重复DTO的利器
  • ❌ 不适合需要复杂转换的场景

最后送大家一句改编名言:"不要问应该返回什么字段,而要让JsonView帮你决定!"

(本文代码示例已通过Spring Boot 3.1.x测试,食用前记得检查你的依赖版本哦~)