I was trying to use Jackson to write a class value to JSON that has Optional as fields:
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())); } } When executed, this class generates the following output:
{"field":{"present":true}} I understand the present/not present field being included and could work around it when reading the JSON data, however I can't get around the fact that the actual content of the optional is never written to the output. :(
Any workarounds here except not using ObjectMapper at all?
You could use jackson-datatype-jdk8 which is described as:
Support for new JDK8-specific types, such as Optional
In order to do this:
com.fasterxml.jackson.datatype:jackson-datatype-jdk8 as a dependencyobjectMapper.registerModule(new Jdk8Module()); The Optional class has a value field, but no standard getter/setter for it. By default, Jackson looks for getters/setters to find class properties.
You can add a custom Mixin to identify the field as a property
final class OptionalMixin { private Mixin(){} @JsonProperty private Object value; } and register it with your ObjectMapper.
ObjectMapper mapper = new ObjectMapper(); mapper.addMixInAnnotations(Optional.class, OptionalMixin.class); You can now serialize your object.
System.out.println(mapper.writeValueAsString(new Test())); will print
{"field":{"value":"hello, world!","present":true}} Consider also looking at jackson-datatype-guava. There's a Jackson Module implementation for Guava types including their Optional. It's possibly more complete than what I've shown above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With