2

I am using Immutables library (https://immutables.github.io).

My class looks as follows:

package com.abc.myservice.data.models;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.immutables.value.Value;

import java.util.Map;
import java.util.Optional;

@Value.Immutable
@JsonSerialize(as = ImmutableMyEntityModel.class)
@JsonDeserialize(as = ImmutableMyEntityModel.class)
public interface MyEntityModel {
    String myEntityId();
    String status();
    Optional<Integer> count();
    Optional<Integer> version();
    Optional<Map<String, String>> attributes();
}

I build the immutable class object with:

ImmutableMyEntityModel.builder()
    .myEntityId("some-id")
    .status("some-status")
    .count(Optional.of(10))
    .build()

And my output is:

{
    "MyEntityId": "some-id",
    "status": "some-status",
    "count": {
        "present": true
    },
    "version": {
        "present": false
    },
    "attributes": {
        "present": false
    }
}

Instead what I would like to see is:

{
    "MyEntityId": "some-id",
    "status": "some-status",
    "count": 10
}

How can I make it work like that?

bappak
  • 865
  • 8
  • 23

1 Answers1

4

Use the jackson-datatype-jdk8 module so that Jackson properly understands the java.util.Optional type - a pretty good explanation is in this article.


  • Add jackson-datatype-jdk8 library to your project/classpath, which contains a Jackson module that allows Jackson to properly understand Optionals.
  • When creating an ObjectMapper, register the Jdk8Module:
ObjectMapper om = new ObjectMapper();
om.registerModule(new Jdk8Module());
  • Optionally, add @JsonIgnoreProperties(ignoreUnknown = true) to properties or the class itself to avoid serializing Optional.empty() to null values and instead ignore the property completely.

Full example:

public class JacksonOptionalTest
{
    public static void main(String... args)
    throws Exception
    {
        ObjectMapper om = new ObjectMapper();
        om.registerModule(new Jdk8Module());

        Thing thing = new Thing();
        thing.name = "John Smith";
        thing.count = Optional.of(12);

        String s = om.writeValueAsString(thing);
        System.out.println(s);
    }

    @JsonInclude(Include.NON_ABSENT)
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Thing
    {
        public String name;
        public Optional<Integer> count = Optional.empty();
        public Optional<Integer> version = Optional.empty();
    }
}

The output of this is {"name":"John Smith","count":12}.

prunge
  • 22,460
  • 3
  • 73
  • 80