Jackson Serialization: Ignore Empty Values (Or Null)

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



Leave a reply



Submit