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