将 Jackson ObjectMapper 与 Java 8 Optional 值一起使用

2022-08-31 15:09:38

我试图使用Jackson将类值写入JSON,该值具有可选字段:

public class Test {
    Optional<String> field = Optional.of("hello, world!");

    public Optional<String> getField() {
        return field;
    }

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(new Test()));
    }
}

执行时,此类将生成以下输出:

{"field":{"present":true}}

我理解包含当前/不存在的字段,并且可以在读取JSON数据时解决此问题,但是我无法摆脱这样一个事实,即可选内容的实际内容永远不会写入输出。:(

除了根本不使用ObjectMapper之外,这里有什么解决方法吗?


答案 1

你可以使用 jackson-datatype-jdk8,它被描述为:

支持新的 JDK8 特定类型,例如可选

为此,请执行以下操作:

  • 添加为依赖项com.fasterxml.jackson.datatype:jackson-datatype-jdk8
  • 向对象映射器注册模块:objectMapper.registerModule(new Jdk8Module());

答案 2

该类有一个字段,但没有标准的 getter/setter。默认情况下,Jackson 查找 getters/setters 以查找类属性。Optionalvalue

您可以添加自定义 Mixin 以将字段标识为属性

final class OptionalMixin {
    private Mixin(){}
    @JsonProperty
    private Object value;
}

并将其注册到您的 .ObjectMapper

ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Optional.class, OptionalMixin.class);

现在可以序列化对象。

System.out.println(mapper.writeValueAsString(new Test()));

将打印

{"field":{"value":"hello, world!","present":true}}

考虑一下杰克逊数据类型番石榴。有一个Jackson实现用于番石榴类型,包括他们的.它可能比我上面显示的更完整。ModuleOptional


推荐