Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson JSON serialization: How to ignore a nested object when all its fields are null?

Tags:

java

json

jackson

I'm using Jackson and I have some JSON schema objects set up something like this:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Person {

    String name;
    Child child = new Child();
    Sibling sibling = new Sibling();

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public Child getChild() {
        return child;
    }
    public void setChild(Child child) {
        this.child = child;
    }

    public Sibling getSibling() {
        return sibling;
    }
    public void setSibling(Sibling sibling) {
        this.sibling = sibling;
    }
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Child {

    String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Sibling {

    String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

I'm attempting to ignore all fields that are null or empty, which works fine. But I also want to ignore objects with fields that are all null or empty. For example:

Person person = new Person();
person.setName("John Doe");
ObjectMapper mapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(person);

The resulting JSON string is {"name":"John Doe","child":{},"sibling":{}}, but I want it to be {"name":"John Doe"}. Child and Sibling need to be initialized when Person is created so I don't want to change that. Is there a way to make Jackson treat objects with null fields as null with a custom serializer? I've seen examples of using custom serializers for specific types of objects but I need one that would work for any object.

like image 440
David DeMar Avatar asked Apr 24 '18 18:04

David DeMar


People also ask

How do you tell Jackson to ignore a field during serialization if its null?

Ignoring null fields at field level in Jackson We can do this by annotating each field with @JsonInclude(Include. NON_NULL) annotation. If a field is annotated by this, then it will be not included in the JSON output if its null.

How do I ignore null values in JSON response Jackson?

To ignore Null fields in JSON, Jackson provides Include. NON_NULL and to ignore Empty fields Jackson provides Include. NON_EMPTY .

How do you tell Jackson to ignore a field during serialization?

If there are fields in Java objects that do not wish to be serialized, we can use the @JsonIgnore annotation in the Jackson library. The @JsonIgnore can be used at the field level, for ignoring fields during the serialization and deserialization.

How do you tell Jackson to ignore empty objects during deserialization?

Inspect the field in question, determine, if it is emtpy and return null , so your ContainedObject would be null. Hope this helps!


1 Answers

You can achieve this in an arguably simpler way without custom serialiser(s) for Person or Child and Sibling but with CUSTOM include and passing the type of the field as filter.

First of all define correct equals methods for Child and Sibling. Then, to filter nested objects that are equal to what their default constructor would return, annotate the pertinent getters in Person like this:

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Child.class)
public Child getChild() {
    return child;
}

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Sibling.class)
public Sibling getSibling() {
    return sibling;
}

Setting valueFilter to Child.class above has the effect of creating an object with the default constructor Child emptyChild = new Child() and then to decide that another object Child child should be serialised checks that emptyChild.equals(child) is false

docs for valueFilter

like image 107
Manos Nikolaidis Avatar answered Oct 26 '22 16:10

Manos Nikolaidis