Learn to serialize the fields and ignore NULL, empty and absent values using Jackson. In this tutorial, we will learn the difference between different empty values and how to ignore a specific value.
1. Setup
Add the latest version of Jackson, if you have not already added it to the project.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
For demo purposes, we will use the following RecordWithNulls class. We are using Lombok to reduce the boilerplate code such as getters, setters, constructors and toString() method.
@lombok.Data
@lombok.AllArgsConstructor
@lombok.NoArgsConstructor
class RecordWithNulls {
private Long id;
private String text;
private LocalDateTime timestamp;
private Boolean status;
}
2. Difference between NULL, Empty and Absent Values
Before diving into code, let us first understand the meaning of an empty value or absent value. So that we can make a better decision of what option to use.
Jackson’s enum JsonInclude.Include
contains different values that represent empty or absent values.
2.1. NULL Values
Null values are all fields with null
reference.
2.2. Absent Values
Absent values consist of two types:
null
values, and- absent” value of referential types such as Optional or AtomicReference. For example, there is no value present when invoking Optional.get() method. Jackson supports Optionals from Java 8, as well as, Guava.
2.3. Empty Values
Empty values include null, absent, and a few additional values. These consist of the following types:
null
values, and- absent” value of referential types such as Optional or AtomicReference.
- Empty strings of length 0.
- Empty containers such as arrays/collections of size 0.
3. Ignoring NULL, Empty and Absent Values
To ignore null and empty values, we use one of the values present in the @JsonInclude.Include enum:
JsonInclude.Include.NON_NULL
JsonInclude.Include.NON_ABSENT
JsonInclude.Include.NON_EMPTY
3.1. At Class Level
When applying @JsonInclude at class level, all the fields with NULL
values will be ignored during serialization.
@JsonInclude(JsonInclude.Include.NON_NULL)
class RecordWithNulls {
...
}
Let’s test this out.
RecordWithNulls record = new RecordWithNulls(1L, "test", null, null);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
String json = mapper.writeValueAsString(record);
The above code will produce the following JSON.
{"id":1,"text":"test"}
3.2. At Fields Level
When applying @JsonInclude at the field level, only the annotated fields with NULL
values will be ignored.
class RecordWithNulls {
...
@JsonInclude(JsonInclude.Include.NON_NULL)
private LocalDateTime timestamp;
...
}
The generated JSON will have timestamp field be ignored when it is NULL. The status field will not be serialized because it has not been annotated.
{"id":1,"text":"test","status":null}
4. Globally Configuring the ObjectMapper
If ignoring NULL fields is the application’s default behavior, then it makes sense to configure globally. One way to achieve it is by configuring it in the ObjectMapper class.
ObjectMapper mapper = new ObjectMapper();
...
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
Now this mapper will ignore all the NULL fields for all the classes it serializes.
5. Using Custom Filter
We can further customize the check for emptiness by creating a custom filter class and overriding its equals()
method. If equals() returns true
value is excluded (that is, filtered out); if false
value is included.
Create a custom filter like the following:
class StringFilter {
@Override
public boolean equals(Object value) {
//custom logic
return true;
}
}
And register it as a custom filter for a field as follows:
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = StringFilter.class)
private String text;
5. Using Custom Serializer
Another way to filter out empty values is by overriding the isEmpty()
method of the custom serializer class. If isEmpty() returns true, field can be excluded from serialization using @JsonInclude(JsonInclude.Include.NON_EMPTY).
class RecordSerializer extends StdSerializer<Record> {
...
@Override
public boolean isEmpty(SerializerProvider provider, Record value) {
//write custom logic
//return super.isEmpty(provider, value);
}
...
}
6. Conclusion
In this short tutorial, we learned to ignore the null, empty and absent values when serializing a POJO to JSON. We learned to use the @JsonInclude annotation and set SerializationInclusion feature in the ObjectMapper class.
Happy Learning !!
Leave a Reply