Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent null values inside a Map and null fields inside a bean from getting serialized through Jackson

Tags:

java

json

jackson

I have a a Map<String,Foo> foosMap that I want to serialize through Jackson . Now I want following two settings on the serialization process:

  1. The Map can have have plenty of null values and null keys and I don't want nulls to be serialized.
  2. For all those Foos that are getting serialized, I do not want to serialize null objects referenced inside Foo.

What is the best way to achieve this ? I am using jackson-core1.9 and jackson-mapper1.9 jars in my project.

like image 744
Inquisitive Avatar asked Jul 12 '12 09:07

Inquisitive


People also ask

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 handle null values on a map?

A HashMap is allowed to have null keys and values. Can you please verify your code? The one you posted will not compile and if "fixed" you will not get a NPE, it will just print null...

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.


2 Answers

If it's reasonable to alter the original Map data structure to be serialized to better represent the actual value wanted to be serialized, that's probably a decent approach, which would possibly reduce the amount of Jackson configuration necessary. For example, just remove the null key entries, if possible, before calling Jackson. That said...


To suppress serializing Map entries with null values:

Before Jackson 2.9

you can still make use of WRITE_NULL_MAP_VALUES, but note that it's moved to SerializationFeature:

mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); 

Since Jackson 2.9

The WRITE_NULL_MAP_VALUES is deprecated, you can use the below equivalent:

mapper.setDefaultPropertyInclusion(    JsonInclude.Value.construct(Include.ALWAYS, Include.NON_NULL)) 

To suppress serializing properties with null values, you can configure the ObjectMapper directly, or make use of the @JsonInclude annotation:

mapper.setSerializationInclusion(Include.NON_NULL); 

or:

@JsonInclude(Include.NON_NULL) class Foo {   public String bar;    Foo(String bar)   {     this.bar = bar;   } } 

To handle null Map keys, some custom serialization is necessary, as best I understand.

A simple approach to serialize null keys as empty strings (including complete examples of the two previously mentioned configurations):

import java.io.IOException; import java.util.HashMap; import java.util.Map;  import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider;  public class JacksonFoo {   public static void main(String[] args) throws Exception   {     Map<String, Foo> foos = new HashMap<String, Foo>();     foos.put("foo1", new Foo("foo1"));     foos.put("foo2", new Foo(null));     foos.put("foo3", null);     foos.put(null, new Foo("foo4"));      // System.out.println(new ObjectMapper().writeValueAsString(foos));     // Exception: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)      ObjectMapper mapper = new ObjectMapper();     mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);     mapper.setSerializationInclusion(Include.NON_NULL);     mapper.getSerializerProvider().setNullKeySerializer(new MyNullKeySerializer());     System.out.println(mapper.writeValueAsString(foos));     // output:      // {"":{"bar":"foo4"},"foo2":{},"foo1":{"bar":"foo1"}}   } }  class MyNullKeySerializer extends JsonSerializer<Object> {   @Override   public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused)        throws IOException, JsonProcessingException   {     jsonGenerator.writeFieldName("");   } }  class Foo {   public String bar;    Foo(String bar)   {     this.bar = bar;   } } 

To suppress serializing Map entries with null keys, further custom serialization processing would be necessary.

like image 79
Programmer Bruce Avatar answered Sep 20 '22 00:09

Programmer Bruce


For Jackson versions < 2.0 use this annotation on the class being serialized:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 
like image 31
AllBlackt Avatar answered Sep 21 '22 00:09

AllBlackt