Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson to deserialize Map variable as empty Map instead of null

I'm using Jackson to deserialize a JSON that could contain null values for Map variables. What I want is if the value is null, I want the map to be an empty HashMap instead of null.

JSON:

{"names":null, "descriptions":null, "nicknames":null...}

Java class:

private User {
    private Map<String,String> names = new HashMap<>();
    private Map<String,String> descriptions = new HashMap<>();
    private Map<String,String> nicknames = new HashMap<>();
}

Right now when the ObjectMapper deserializes the JSON, it overrides the fields, and sets names, descriptions, and nicknames as null.

Is there a a generic way so I would not have to add code each time I have a new map property?

like image 557
Glide Avatar asked Nov 08 '13 19:11

Glide


People also ask

How do you tell Jackson to ignore a field during Deserialization if its value is null?

Jackson default include null fields 1.2 By default, Jackson will include the null fields. To ignore the null fields, put @JsonInclude on class level or field level.

How do I ignore null values in JSON response Jackson?

You can ignore null fields at the class level by using @JsonInclude(Include. NON_NULL) to only include non-null fields, thus excluding any attribute whose value is null. You can also use the same annotation at the field level to instruct Jackson to ignore that field while converting Java object to json if it's null.

How do you ignore null values in JSON response Jax RS?

In order to ignore null fields at the class level, we use the @JsonInclude annotation with include. NON_NULL.

How do you deserialize a map?

Just like Java objects, we can serialize and deserialize Java Map by using Jackson. We can easily serialize and deserialize Map<Object, Object>, Map<Object, String>, and Map<String, String> to or from JSON-formatted strings by using Jackson.


2 Answers

You can setup you own module and override getNullValue()

see doc http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/map/JsonDeserializer.html

Note

I register the Deserializer for all Map.class, not so exact

test code

    SimpleModule module = new SimpleModule("test",  new Version(1, 0, 0, null));

    module.addDeserializer(Map.class, new JsonDeserializer<Map>() {
        @Override
        public Map deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            return jp.readValueAs(HashMap.class);
        }

        @Override
        public Map getNullValue() {
            return new HashMap();
        }
    });

    mapper.registerModule(module);

test case

String s = "{\"names\":{\"1\":2}, \"descriptions\":null, \"nicknames\":null}";

result

User{descriptions={}, names={1=2}, nicknames={}}
like image 167
farmer1992 Avatar answered Sep 28 '22 19:09

farmer1992


Add a setter for your map:

public void setNames(Map<String, String> names) {
    this.names = (names == null) ? new HashMap<>() : names;
}

This setter will be detected by Jackson and will be used when the property is read from the JSON. So within your setter, you can check if the value is null, and if it is then you create a new HashMap.

like image 42
Simon Forsberg Avatar answered Sep 28 '22 17:09

Simon Forsberg