沿着创建注释的路径,动态确定字段是否应该序列化。
注解的实现如下:
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = HiddenFieldSerializer.class)
@Target(value = ElementType.FIELD)
public @interface Hidden {
}
现在是序列化器的代码:
public class HiddenFieldSerializer
extends StdSerializer<String>
implements ContextualSerializer {
public HiddenFieldSerializer() {
super(String.class);
}
@Override
public void serialize(String value,
JsonGenerator jgen,
SerializerProvider provider) {
try {
provider.defaultSerializeNull(jgen);
} catch (IOException e) {
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov,
BeanProperty property) {
return shouldHide() ?
new HiddenFieldSerializer() : new StringSerializer();
}
public boolean shouldHide() {
/* Simplifying this */
return Boolean.TRUE;
}
}
一些代码来展示它是如何工作的:
public class Test {
static final ObjectMapper mapper = new ObjectMapper()
.setSerializationInclusion(Include.NON_NULL)
.setSerializationInclusion(Include.NON_EMPTY);
static class User {
@JsonProperty
String username;
@Hidden
@JsonProperty
String pin;
}
public static void main(String... args)
throws JsonProcessingException {
final POC.User u = new POC.User();
u.username = "harry_potter";
u.pin = "1298";
System.out.println(mapper.writeValueAsString(u));
}
}
输出如下:
{"username":"harry_potter","pin":null}
如何从序列化中删除字段引脚而不是将其设置为空?显然,在这种情况下,设置映射器的属性很少有用户关注。有什么建议么?想法?也许整件事都是个坏主意?
理想情况下我应该能够看到以下内容:
{"username":"harry_potter"}
尚不清楚您是否想要静态或动态忽略给定属性。不管怎样,看起来你已经过度设计了。
@JsonIgnore
。如果它不满足您的需求,您可以定义自定义忽略注释,如下所示:
@Retention(RetentionPolicy.RUNTIME)
public @interface Hidden {
}
然后选择最适合您需求的方法:
JacksonAnnotationIntrospector
并重写检查忽略标记的方法:
public class CustomAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
return super.hasIgnoreMarker(m) || m.hasAnnotation(Hidden.class);
}
}
ObjectMapper
以使用注释内省器:
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new CustomAnnotationIntrospector());
注释自省每个类仅发生一次,因此您无法动态更改您使用的标准(如果有)。类似的例子可以在这个answer中看到。
BeanSerializerModifier
来修改将要序列化的属性:
public class CustomBeanSerializerModifier extends BeanSerializerModifier {
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
return beanProperties.stream()
.filter(property -> property.getAnnotation(Hidden.class) == null)
.collect(Collectors.toList());
}
}
Module
并将其注册到您的 ObjectMapper
:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(new CustomBeanSerializerModifier());
}
});
这种方法允许您动态忽略属性。
我也遇到了同样的问题,我必须在序列化期间检查某些权限,但它第一次就被缓存了。