如何基于Jackson实现对象属性动态过滤(兼容高级特性)
基于Jackson实现动态属性过滤的优雅方案需求
以下是提取自框架的逻辑等价类Employee:
public class Employee { private String name; private boolean nameSpecified; private LocalDateTime birthday; private boolean birthdaySpecified; private String jobTitle; private boolean jobTitleSpecified; public String getName() { if (!nameSpecified) { throw new IllegalStateException("The property `name` is not specified"); } return name; } public void setName(String name) { this.name = name; this.nameSpecified = true; } public LocalDateTime getBirthday() { if (! birthdaySpecified) { throw new IllegalStateException("The property `birthday` is not specified"); } return birthday; } public void setBirthday(LocalDateTime name) { this.birthday = birthday; this.birthdaySpecified = true; } public String getJobTitle() { if (!jobTitleSpecified) { throw new IllegalStateException("The property `jobTitle` is not specified"); } return jobTitle; } public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; this.jobTitleSpecified = true; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Employee"); String separator = " {"; if (nameSpecified) { builder.append(separator).append("name=").append(name); separator = ", "; } if (birthdaySpecified) { builder.append(separator).append("birthday=").append(birthday); separator = ", "; } if (jobTitleSpecified) { builder.append(separator).append("jobTitle=").append(jobTitle); } return builder.append("}").toString(); } }
类设计特殊性
这个类并非标准POJO,属性未指定与设为null是完全不同的概念:
- 未指定:属性值未知,这是ORM中的常见设计(例如Hibernate 3起的延迟标量属性)
- Null:属性值已知但无实际数据
序列化/反序列化痛点
这种设计能在强类型语言中实现对象的动态性,但默认Jackson无法正确处理它——我们需要像toString()逻辑那样,跳过未指定的属性。这和@JsonFilter的需求高度相似,但过滤规则是每个对象独立的。
现有方案的缺陷
此前通过自定义Jackson Module注册Serializer和Deserializer解决问题,但该方案无法兼容@JsonAlias、@JsonView、继承、多态等Jackson高级特性。两年来不断收到用户反馈高级特性失效,急需一种优雅方案,既能实现每个对象的动态属性过滤,又不破坏任何高级特性。
内容的提问来源于stack exchange,提问作者Tao Chen
相关产品推荐
相关产品推荐

