Using Jackson ObjectMapper with Java 8 Optional values

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.


You could use jackson-datatype-jdk8 which is described as:

Support for new JDK8-specific types, such as Optional

In order to do this:

  • add com.fasterxml.jackson.datatype:jackson-datatype-jdk8 as a dependency
  • register the module with your object mapper: objectMapper.registerModule(new Jdk8Module());

Similar to @Manikandan's answer but add @JsonProperty to the private field instead of a getter so you don't expose your work around on the public api.

public class Test {

    @JsonProperty("field")
    private String field;

    @JsonIgnore
    public Optional<String> getField() {
        return Optional.of(field); // or Optional.ofNullable(field);
    }
}