我有一个带有Optional字段的Java类。我使用Jackson 2.8.3(从Spring web 4.3.3调用)将类序列化为JSON。
如果Optional为空,我希望让序列化程序跳过该字段,并将包含的字符串序列化(如果存在)。我要查找的结果示例包含两个对象的列表:
[
{
"id": 1,
"foo": "bar"
},
{
"id": 2,
}
]
这里,id为2的对象的foo Optional为空。
相反,我得到的是:
[
{
"id": 1,
"foo": {
"present": true
}
},
{
"id": 2,
"foo": {
"present": false
}
}
]
即使我注释了" bar"这也是结果。类中的字段,如
@JsonInclude(JsonInclude.Include.NON_ABSENT)
public Optional<String> getFoo() { ...
有没有办法可以使用Jackson注释或自定义序列化器来获得第一个列表的结果?
答案 0 :(得分:11)
无需编写自定义序列化程序。使用@JsonInclude(JsonInclude.Include.NON_ABSENT)
注释您的课程。
您还需要:
com.fasterxml.jackson.datatype:jackson-datatype-jdk8
作为您的依赖objectMapper.registerModule(new Jdk8Module());
答案 1 :(得分:1)
根据您的需要使用JsonSerializer
。
像这样(半伪):
public class MySer extends JsonSerializer<Opional<?>> {
@Override
public void serialize(Optional<?> optString, JsonGenerator generator, SerializerProvider provider)
throws IOException, JsonProcessingException {
//Check Optional here...
generator.writeString(/* DO SOMETHING HERE WHATEVER */);
}
//然后在你的模型中:
public class ClassWhatever {
@JsonSerialize(using = MySer .class)
public Optional<String> getFoo() { ...
}
为避免使用@JsonSerialize注释每个字段,您可以使用
将自定义序列化程序注册到对象映射器 ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addSerializer(new MyCustomSerializer()); // assuming serializer declares correct class to bind to
mapper.registerModule(testModule);
此外,给定的解决方案仅适用于序列化。除非您编写自己的反序列化程序,否则反序列化将失败。然后,您需要使用@JsonDeserializ
e注释每个字段或注册您的自定义反序列化器。
答案 2 :(得分:1)
您可以使用objectMapper.registerModule(new Jdk8Module());
,但它会使用空值进行序列化。
但是仍然要从JSON中删除空值,请使用以下代码:
objectMapper.registerModule(new Jdk8Module().configureAbsentsAsNulls(true));
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);