如何在Jackson序列化期间跳过Optional.empty字段?

时间:2016-11-03 17:47:12

标签: java json serialization spring-boot jackson

我有一个带有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注释或自定义序列化器来获得第一个列表的结果?

3 个答案:

答案 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);