12

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.

2
  • You have to write a custom deserializer stackoverflow.com/questions/40366524/… Commented Apr 24, 2018 at 18:23
  • I'm looking for solution for serialization, not deserialization, as well as one that works with all object types. Commented Apr 28, 2018 at 21:31

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

This works but what about if you don't initialize Child or Sibling inside Person? It would return null for both of them even though Person has NOT_EMPTY specified in its definition
1

In your case, I think ignoring null values on the serializer level should be enough:

mapper.setSerializationInclusion(Include.NON_EMPTY); mapper.setSerializationInclusion(Include.NON_NULL); 

1 Comment

The question is about how to not include an object if all its fields are null, these options only work for if the object itself is null or something like an empty array

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.