Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't return property when it's an empty list with jackson

Tags:

java

json

jackson

I have a class need to be dessrialized using jackson and the class has an collection property. The collection is empty, but not null. Question: How to desersialise the class without empty collection. Sample code below:

class Person {     String name;     List<Event> events;     //....getter, setter } 

if

person.list = new List<Event>();  persion.name = "hello"; 

then excepted the json would be:

{name: "hello"} 

not

{name: "hello", events:[]} 

How to make it? Thank you~~

================================================

I have solved this by n1ckolas's advice. Thank you first. My jackson version is 2.1.1, and Spring-3.2.2 import better support for this verson of jackson. Also, this works for both arrays and collection. Below is my configuraion:

<!-- Enables the Spring MVC @Controller programming model --> <mvc:annotation-driven>     <mvc:message-converters>         <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">             <property name="objectMapper" ref="objectMapper"/>         </bean>     </mvc:message-converters>         </mvc:annotation-driven>  <!--Json Mapper--> <bean name="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" autowire="no">     <property name="featuresToDisable">         <list>             <!--not to return empty colletion-->             <value type="com.fasterxml.jackson.databind.SerializationFeature">WRITE_EMPTY_JSON_ARRAYS</value>         </list>     </property> </bean> 
like image 433
Kinorsi Avatar asked Mar 15 '13 06:03

Kinorsi


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.

How do I ignore properties in Jackson?

Ignore Fields Using Filters Finally, we can also use filters to ignore specific fields in Jackson. First, we need to define the filter on the Java object: @JsonFilter("myFilter") public class MyDtoWithFilter { ... }

What is @JsonInclude?

@JsonInclude It says that if the value of a property (or all properties) in question is equal to a certain value ( null , empty - whatever that means, or a default value) this property is not serialized. Without this annotation, the property value is always serialized.


2 Answers

You can use @JsonInclude(JsonInclude.Include.NON_EMPTY) annotation on your class or filed.

import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.NON_EMPTY) class Person {     String name;     List<Event> events;     //....getter, setter } 
like image 108
Eylon Avatar answered Sep 28 '22 09:09

Eylon


If you can change your original model with Jackson annotations, here is the way how to achieve this.

Jackson has WRITE_EMPTY_JSON_ARRAYS. And you may turn off it with:

objectMapper.configure(SerializationConfig.Feature.WRITE_EMPTY_JSON_ARRAYS, false); 

But it works only for Arrays, but not for Collections. But you may combine @JsonProperty with @JsonIgnore, something like the following:

//....getter, setter of Person class @JsonIgnore public List<Event> getEvents() {     return events; }  @JsonProperty("events") public Event[] getEventsArr() {     return events.toArray(new Event[0]); } 

And afterwards you'll have output, as you expected.

EDIT: If you are using SpringMVC, then you can configure your actual ObjectMapper with explicit reference in mvc:annotation-driven:

<!-- Configures the @Controller programming model --> <mvc:annotation-driven>     <mvc:message-converters>         <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">             <property name="objectMapper" ref="objectMapper"/>         </bean>     </mvc:message-converters> </mvc:annotation-driven>  <!--custom Json Mapper configuration--> <bean name="objectMapper" class="org.springframework.http.converter.json.JacksonObjectMapperFactoryBean" autowire="no">     <property name="featuresToDisable">         <list>             <!--Ignore unknown properties-->             <value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_EMPTY_JSON_ARRAYS</value>         </list>     </property> </bean> 

Offtop: usually it's quite useful to specify explicit instance of ObjectMapper, because:

  • you can configure it in the way you want
  • you can use its reference through @Autowired
like image 31
n1ckolas Avatar answered Sep 28 '22 09:09

n1ckolas