Java 使用Jackson动态序列化-删除带有特定注释的字段

Java 使用Jackson动态序列化-删除带有特定注释的字段,java,serialization,jackson,annotations,Java,Serialization,Jackson,Annotations,沿着创建注释的路径,该注释将动态确定字段是否应序列化 注释的实现如下所示: {"username":"harry_potter","pin":null} @Retention(RetentionPolicy.RUNTIME) @杰克逊尼奥塞德酒店 @JsonSerialize(使用=HiddenFieldSerializer.class) @目标(值=ElementType.FIELD) 公共@接口隐藏{ } 现在,序列化程序的代码

沿着创建注释的路径,该注释将动态确定字段是否应序列化

注释的实现如下所示:

{"username":"harry_potter","pin":null}
@Retention(RetentionPolicy.RUNTIME)
@杰克逊尼奥塞德酒店
@JsonSerialize(使用=HiddenFieldSerializer.class)
@目标(值=ElementType.FIELD)
公共@接口隐藏{
}
现在,序列化程序的代码是:

公共类HiddenFieldSerializer
扩展标准序列化程序
实现ContextualSerializer{
公共HiddenFieldSerializer(){
super(String.class);
}
@凌驾
公共void序列化(字符串值,
Jsongen发电厂,
序列化提供程序(提供程序){
试一试{
provider.defaultSerializeNull(jgen);
}捕获(IOE异常){
}
}
@凌驾
公共JsonSerializer CreateContext(SerializerProvider,
BeanProperty(不动产){
返回shoulhide()?
新建HiddenFieldSerializer():新建StringSerializer();
}
公共布尔值shoulhide(){
/*简化这个*/
返回Boolean.TRUE;
}
}
一点代码来说明它是如何工作的:

公共类测试{
静态最终ObjectMapper映射器=新ObjectMapper()
.setSerializationInclusion(包括.NON_NULL)
.setSerializationInclusion(包括.NON_EMPTY);
静态类用户{
@JsonProperty
字符串用户名;
@隐藏的
@JsonProperty
弦销;
}
公共静态void main(字符串…参数)
抛出JsonProcessingException{
final POC.User u=新的POC.User();
u、 用户名=“哈利·波特”;
u、 pin=“1298”;
System.out.println(mapper.writeValueAsString(u));
}
}
输出如下:

{"username":"harry_potter","pin":null}
如何将字段pin从序列化中删除,而不是将其设置为null?显然,在这样的环境中,设置映射器的属性几乎没有什么用处。有什么建议吗?思想?也许整件事都是个坏主意

理想情况下,我应该能够看到以下内容:

{"username":"harry_potter"}

不清楚您是要静态地还是动态地忽略给定的属性。不管怎么说,看起来你设计得太过火了

首先,我想确定你以前见过面。如果它不适合您的需要,您可以如下定义自定义忽略注释:

{"username":"harry_potter"}
@Retention(RetentionPolicy.RUNTIME)
公共@接口隐藏{
}
然后选择最适合您需要的方法:

方法#1 扩展并重写检查忽略标记的方法:

公共类CustomAnnotationIntrospector扩展了JacksonAnnotationIntrospector{
@凌驾
公共布尔hasIgnoreMarker(注释成员m){
返回super.hasIgnoreMarker(m)| | m.hasaannotation(Hidden.class);
}
}
配置为使用注释内省器:

ObjectMapper mapper=new ObjectMapper();
setAnnotationIntroSector(新的CustomAnnotationIntroSector());
注释内省在每个类中只发生一次,因此您不能动态更改所使用的条件(如果有)。在这一点上可以看到一个类似的例子

进近#2 扩展以修改将序列化的属性:

公共类CustomBeanSerializerModifier扩展了BeanSerializerModifier{
@凌驾
公共列表changeProperties(SerializationConfig配置,
Bean描述Bean描述,列出Bean属性){
return beanProperties.stream()
.filter(property->property.getAnnotation(Hidden.class)==null)
.collect(Collectors.toList());
}
}
然后将其添加到并注册到您的:

ObjectMapper mapper=new ObjectMapper();
registerModule(新的SimpleModule(){
@凌驾
公共无效设置模块(设置上下文上下文){
super.setupModule(上下文);
addBeanSerializerModifier(新的CustomBeanSerializerModifier());
}
});

这种方法允许您动态忽略属性。

我喜欢CustomSerializerModifier,不确定重写JacksonAnnotationInspector是否有帮助。现在检查您的解决方案,感谢您提供的insightCustomBeanSerializerModifier也将只被调用一次,并且对相同对象类型的后续调用将被缓存。是否有一种方法可以在每次序列化对象时调用此修饰符?我的场景是在序列化期间检查某些权限(可能会动态更改)。