开发日常之《你的字段太暴露了》
- 产品经理:用户列表接口里怎么能返回用户余额字段?!
- 后端:这是给管理员的...
- 测试:普通用户调用接口居然看到同事的工资条了!
- 运维:这周第三次数据库泄露警告了...
- 你:(抱头)我只是想少写点代码啊!
此时,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() {...}
五、最佳实践:老司机的导航路线
- 视图层级设计:建议采用金字塔结构
PublicView → InternalView → AdminView - 组合使用技巧:
@JsonView(View.Admin.class) @JsonIgnoreProperties("password") // 双重保险 public class User {...} - 文档规范:在视图接口添加详细注释
/** * 包含用户敏感信息 * @apiNote 仅限管理员接口使用 */ public interface AdminView {...}
六、面试考点精讲
高频题1:JsonView与DTO如何选择?
✨ 参考话术:
"DTO适合需要完全重塑数据结构的场景,比如组合多个领域对象的数据。而JsonView更适用于同一对象在不同场景需要展示不同字段的情况,能有效减少类爆炸问题。从维护成本考虑,简单的字段控制优先考虑JsonView。"
高频题2:为什么我的@JsonView注解不生效?
✨ 排查清单:
- 检查是否启用
@EnableWebMvc - 确认Controller方法添加了@JsonView
- 验证视图接口继承关系
- 确保Jackson版本≥2.8
七、总结:选择你的武器
JsonView就像智能窗帘:
- ✅ 简单权限场景的首选
- ✅ 减少重复DTO的利器
- ❌ 不适合需要复杂转换的场景
最后送大家一句改编名言:"不要问应该返回什么字段,而要让JsonView帮你决定!"
(本文代码示例已通过Spring Boot 3.1.x测试,食用前记得检查你的依赖版本哦~)