Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson deserializer - change null collection to empty one

Tags:

java

json

jackson

I have an entity that contains collection as attribute:

public class Entity {      @JsonProperty(value="homes")     @JsonDeserialize(as=HashSet.class, contentAs=HomeImpl.class)     private Collection<Home> homes = new ArrayList<Home>();  } 

If request contains null as request property:

{   "homes": null } 

then homes is set to null. What I want to do is to set homes to empty list. Do I need to write special deserializer for this or is there one for collections? What I tried is this deserializer but it looks ugly (it's not generic and uses implementation instead of interface).

public class NotNullCollectionDeserializer extends JsonDeserializer<Collection<HomeImpl>> {    @Override   public Collection<HomeImpl> deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {     return jsonParser.readValueAs(new TypeReference<Collection<HomeImpl>>(){});   }    @Override   public Collection<HomeImpl> getNullValue() {     return Collections.emptyList();   } } 

So few questions:

  1. Is there some jackson property that changes null to empty collection during deserialization?
  2. If no for the first point - do I need to write deserializer for this? If yes, can I write generic one?
like image 597
pepuch Avatar asked Sep 04 '15 13:09

pepuch


People also ask

How do I ignore null values in Jackson?

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.

Does Jackson serialize null fields?

With its default settings, Jackson serializes null-valued public fields. In other words, resulting JSON will include null fields. Here, the name field which is null is in the resulting JSON string.

What is serialization and Deserialization in Jackson?

3. Serialization. Serialization converts a Java object into a stream of bytes, which can be persisted or shared as needed. Java Maps are collections that map a key Object to a value Object, and are often the least intuitive objects to serialize.

Does Jackson use Java serialization?

Note that Jackson does not use java.


2 Answers

As of Jackson 2.9, it looks like null-handling for specific properties can be configured with @JsonSetter, for example:

@JsonSetter(nulls = Nulls.AS_EMPTY) public void setStrings(List<String> strings) {     this.strings = strings; } 

Similar configuration can also be applied globally for collections:

ObjectMapper mapper = objectMapperBuilder()     .changeDefaultNullHandling(n -> n.withContentNulls(Nulls.AS_EMPTY))     .build(); 

Or by type:

ObjectMapper mapper = objectMapperBuilder()     .withConfigOverride(List.class,         o -> o.setNullHandling(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY)))     .build(); 

I haven't been able to try the feature out, so this is based on the feature discussion and examination of unit tests. YMMV.

like image 146
Mike Partridge Avatar answered Sep 22 '22 05:09

Mike Partridge


I also couldn't find a Jackson property or annotation for this. So I'll have to answer no to the first question. But I would recommend a simple setter instead of the special deserializer :

public class Entity {      @JsonDeserialize(contentAs = HomeImpl.class)     private Collection<Home> homes = new ArrayList<>();      public void setHomes(List<Home> homes) {         if (homes != null)             this.homes = homes;     } } 

This is generic as it only uses the Home interface instead of HomeImpl. You don't need @JsonProperty as Jackson will associate setHomes and homes.

like image 41
Manos Nikolaidis Avatar answered Sep 20 '22 05:09

Manos Nikolaidis