Jackson serialization: ignore empty values (or null)
You have the annotation in the wrong place - it needs to be on the class, not the field. i.e:
@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case
public static class Request {
// ...
}
As noted in comments, in versions below 2.x the syntax for this annotation is:
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY
The other option is to configure the ObjectMapper
directly, simply by calling mapper.setSerializationInclusion(Include.NON_NULL);
(for the record, I think the popularity of this answer is an indication that this annotation should be applicable on a field-by-field basis, @fasterxml)
How to tell Jackson to ignore a field during serialization if its value is null?
To suppress serializing properties with null values using Jackson >2.0, 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
{
String bar;
}
Alternatively, you could use @JsonInclude
in a getter so that the attribute would be shown if the value is not null.
A more complete example is available in my answer to How to prevent null values inside a Map and null fields inside a bean from getting serialized through Jackson.
Jackson: ignore empty object
You can use @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Inner .class)
on Inner
field in Item
class, but to make this work you need to override hashcode and equals method in Item
class.
Basically, the equals
method in Inner class will be called when deciding whether or not inner object should be excluded or not. If equals returns true
, then the object will be excluded from response.
So make the method match anything you want to filter out and return false
for anything that should be written out normally.
You can read more details here
For your particular case, the following code should work :
@Data
public class Item {
private int id;
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Inner .class)
private Inner inner;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Inner getInner() {
return inner;
}
public void setInner(Inner inner) {
this.inner = inner;
}
@Data
public static class Inner {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Inner inner = (Inner) o;
return Objects.equals(name, inner.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
}
NOTE: @JsonInclude(JsonInclude.Include.NON_NULL)
will ignore null fields, so if you put it on class level for Inner
class you will get response like this (it will ignore name
field in Inner class since it's value is null
) :
{
"id": 123,
"inner": {}
}
That will also not work if you put it on class level for class Item
since your Inner
object is not null, it's empty object, so that will produce this:
{
"id": 123,
"inner": {
"name": null
}
}
Jackson serialization - ignore not set values but provide values explicitly set to null
This can be achieved using Optional
fields:
public class JsonTest {
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
static class Example {
private Optional<String> name;
private Optional<String> test;
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper().registerModule(new Jdk8Module());
Example[] examples = {
new Example(),
Example.builder().name(Optional.of("exampleName")).build(),
Example.builder().name(Optional.of("exampleName")).test(Optional.empty()).build(),
};
for (Example ex : examples) {
System.out.println(mapper.writeValueAsString(ex));
}
}
}
Output:
{}
{"name":"exampleName"}
{"name":"exampleName","test":null}
How to JSON serialize null values but not empty values with Jackson?
In case you use java.util.Optional
be sure you have registered com.fasterxml.jackson.datatype.jdk8.Jdk8Module
module which provides extra serialisers and deserialisers.
In your case the simplest way would be to use annotation on property levels:
class Car {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Optional<String> ownerName;
@JsonInclude
String manufacturer;
//getters, setters
}
Default value is Include.ALWAYS
which should be used in your case.
If you want to do that globally you need to implement custom filter and check all cases manually. Simple example:
class CustomFilter {
@Override
public boolean equals(Object obj) {
// return false to keep value in response
// return true to filter out value from response
if (obj == null) {
return false;
}
if (obj instanceof Optional) {
Optional opt = (Optional) obj;
return !opt.isPresent();
}
//other cases if needed
return false;
}
}
You can register it as below:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(new Jdk8Module());
mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.CUSTOM, JsonInclude.Include.CUSTOM, CustomFilter.class, CustomFilter.class));
In case, this is not what you wanted you need to set globally most appropriate value and for given properties set another value. If you can not modify DTO
classes, you can always use MixIn
feature.
Ignore Empty Collections during Serialisation
Try with the annotation
@JsonInclude(Include.NON_EMPTY)
private Collection field;
Jackson: Ignore empty fields except those that are mandatory with respect to the project
I think the suggestion from @chrylis is what you are looking for. The idea to annotate specific fields with @JsonInclude
(default value is JsonInclude.Include.ALWAYS
) in field level to override the class level @JsonInclude(JsonInclude.Include.NON_EMPTY)
. Following is an example:
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public static class Attribute {
private String label;
@JsonInclude
private String name; // Mandatory
@JsonInclude
private String description; // Mandatory
@JsonInclude
private String type; // Mandatory
Related Topics
Apache Httpclient Digest Authentication
How to Change Size of Title's Text on Action Bar
Android - How to Create Clickable Listview
Java.Lang.Classnotfoundexception: Org.Postgresql.Driver, Android
Cannot Resolve Method Getmap()
Polyline Is Not on the Roads: It Goes Straight from One Point to Other
Firebase Realtime Database Search by Word in Between the Query
Using Asynctask with Passing a Value
Google Maps API and Custom Polyline Route Between Markers
Simple Date Format Returns Wrong Date Intermittently
Android Buildscript Repositories: Jcenter VS Mavencentral
Android JSON Parsing of Multiple JSONobjects Inside JSONobject
Android - Viewrootimpl$Calledfromwrongthreadexception
Read/Write .Txt File with Special Characters
What Is the Correct Way to Do Inserts/Updates/Deletes in Android SQLitedatabase Using a Query String
Android:Table Has No Column Named "Variable Name" MySQL Database Error
Google Cloud Messaging: Don't Receive Alerts When iOS App Is in Background