在序列化MyObject时,我想在运行时决定的Attributes类中包含或不包含null属性。什么是最好的方法呢?
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyObject {
private String property1;
private DateTime property2;
private Attributes attributes;
}
@Data
public class Attributes {
private String property1;
private String property2;
}
答案 0 :(得分:1)
如果您使用的是Jackson 2.8,则可以使用新的"配置覆盖"功能(在高级别讨论了f.ex here),以指定注释的等价物,如下所示:
mapper.configOverride(Attributes.class)
// first value for value itself (POJO); second value only relevant
// for structured types like Map/Collection/array/Optional
.setInclude(JsonInclude.Value.construct(Include.NON_NULL, null));
(以及之前仅使用注释提供的一些其他方面)
但请注意,与注释一样,此设置不是初始设置后可以更改的设置:必须为ObjectMapper
定义一次,并且进一步的更改不会生效。
如果需要不同配置的映射器,则需要创建不同的实例。
答案 1 :(得分:1)
有一些可能性,具体取决于您的运行时决策控制需要的精细程度。
如果行为在运行时完全自定义,您可以使用自己的自定义过滤器来执行复杂的决策,以便序列化字段。过滤器看起来像这样:
PropertyFilter myFilter = new SimpleBeanPropertyFilter() {
@Override public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {
boolean needsSerialization = needsSerializationBasedOnAdvancedRuntimeDecision((MyValueObject) pojo, writer.getName());
if (needsSerialization){
writer.serializeAsField(pojo, jgen, provider);
}
}
@Override protected boolean include(BeanPropertyWriter writer) { return true; }
@Override protected boolean include(PropertyWriter writer) { return true; }
};
您的序列化决策可以逐个属性处理,例如:
private boolean needsSerializationBasedOnAdvancedRuntimeDecision(MyValueObject myValueObject, String name) {
return !"property1".equals(name) || ( myValueObject.getProperty1() == null && property1NullSerializationEnabled );
}
然后,您可以按如下方式应用所需的过滤器:
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", myFilter);
String json = new ObjectMapper().writer(filters).writeValueAsString(myValueObject);
如果某个属性的行为相同,则使用@JsonInclude(JsonInclude.Include.NON_NULL)
注释该属性
public class MyObject {
@JsonInclude(JsonInclude.Include.NON_NULL)
private String property1;
private String property2;
}
如果完整类的行为相同(例如属性),请使用@JsonInclude(JsonInclude.Include.NON_NULL)
或使用描述的配置覆盖StaxMan配置类
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Attributes {
private String property1;
private String property2;
}
如果当前映射的所有类的行为相同:配置映射器,franjavi
答案 2 :(得分:0)
您可以在映射器中更改该行为:
if (noNull) {
mapper.setSerializationInclusion(Include.NON_NULL);
} else {
mapper.setSerializationInclusion(Include.ALWAYS);
}