如何为@JsonInclude的自定义过滤器传递属性上下文以实现可扩展的字段废弃逻辑
如何为@JsonInclude的自定义过滤器传递属性上下文以实现可扩展的字段废弃逻辑
这个需求我之前也遇到过——默认的@JsonInclude自定义过滤器确实没法直接拿到属性的上下文信息(比如字段名、所属父类),不过借助Jackson的ContextualFilter接口就能完美解决,而且完全符合你要的只注解目标字段、不依赖全局过滤器的要求,下面给你详细拆解实现步骤:
核心思路
Jackson提供了ContextualFilter接口,允许我们在过滤器初始化时获取当前字段的元数据(上下文),比如字段名、所属类等。我们只需要让自定义的废弃逻辑过滤器实现这个接口,就能把上下文信息注入进去,进而写出可扩展的废弃判断逻辑。
具体实现代码
1. 实现带上下文感知的自定义过滤器
import com.fasterxml.jackson.databind.ser.ContextualFilter; import com.fasterxml.jackson.databind.ser.ValueFilter; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.JsonMappingException; public class CustomDeprecationLogic implements ValueFilter, ContextualFilter { // 存储属性上下文信息 private String fieldName; private Class<?> parentClass; // Jackson要求的无参构造器,用于初始实例化 public CustomDeprecationLogic() {} // 私有构造器,用于创建携带上下文的过滤器实例 private CustomDeprecationLogic(String fieldName, Class<?> parentClass) { this.fieldName = fieldName; this.parentClass = parentClass; } @Override public boolean equals(Object value) { // 这里就是你的可扩展废弃逻辑,直接使用上下文信息判断 // 示例逻辑:如果字段名为"oldAttribute"且所属类是SomeParent,就过滤掉该字段 boolean isDeprecated = "oldAttribute".equals(fieldName) && SomeParent.class.equals(parentClass); // 返回true表示过滤(不返回该字段),返回false表示保留 return isDeprecated; } @Override public ContextualFilter createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (property == null) { return this; } // 从BeanProperty中提取上下文信息:字段名、所属父类 String targetFieldName = property.getName(); Class<?> targetParentClass = property.getMember().getDeclaringClass(); // 返回携带上下文的过滤器实例 return new CustomDeprecationLogic(targetFieldName, targetParentClass); } }
2. 在目标字段上添加注解
public class SomeParent { // 直接在需要处理的字段上添加@JsonInclude注解,指定自定义过滤器 @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = CustomDeprecationLogic.class) private SomeClass attribute; // 其他字段... }
为什么这个方案可行?
- 上下文获取:通过
ContextualFilter的createContextual方法,Jackson会在处理每个标注了注解的字段时,自动传入该字段的BeanProperty对象,我们从中就能拿到字段名、所属类等关键上下文。 - 字段彻底移除:
@JsonInclude的CUSTOM过滤逻辑是在序列化阶段直接决定是否包含该字段,而不是像自定义JsonSerializer那样只是修改序列化内容,所以能彻底把字段从JSON响应中移除。 - 可扩展性:你可以在
equals方法里根据上下文信息编写任意复杂的废弃规则,比如读取配置文件、根据父类类型分支处理等,完全满足可扩展的需求。 - 非全局配置:只需要在需要废弃逻辑的字段上添加注解,不会影响其他字段,符合你的要求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

