Search code examples
javaserializationjacksonjson-deserializationjackson2

Remove empty JSON objects from an array in Jackson serialization


I have a List in a Java Pojo class. That list contains some MyChildPojo objects which are not null but can have properties with null values. Example:

MyChildPojo obj1 = new MyChildPojo();
MyChildPojo obj2 = new MyChildPojo();

I have added @JsonInclude(JsonInclude.Include.NON_EMPTY) on my MyChildPojo class so null properties will not be added while serializing the object. Now my final serialized output for the List object is:

[
  {}, {}
]

I want to remove the complete List object in this case. I have tried by adding @JsonInclude(JsonInclude.Include.NON_EMPTY) and @JsonInclude(value = Include.NON_EMPTY, content = Include.NON_EMPTY) on the List object but still getting the same output.

I can only use annotation in my case. Is there any possible way to do this?


Solution

  • You can use annotations with custom filter to do this. In the custom filter you can omit the list property altogether when the whole set of MyChildPojo objects are just shell.

    Annotate MyChildPojo class with

    @JsonInclude(value = JsonInclude.Include.NON_EMPTY, valueFilter = EmptyListFilter.class)
    public class MyChildPojo {
    ...
    }
    

    And define EmptyListFilter something like the following

    public class EmptyListFilter {
        @Override
        public boolean equals(Object obj) {
            if (obj == null || !(obj instanceof List)) {return false;}
            Optional<Object> result = ((List)obj).stream().filter(
                    eachObj -> Arrays.asList(eachObj.getClass().getDeclaredFields()).stream().filter(eachField -> {
                        try {
                            eachField.setAccessible(true);
                            if ( eachField.get(eachObj)  != null && !eachField.get(eachObj).toString().isEmpty()) {
                                return true;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return false;
                    }).count() > 0).findAny();
           return  !result.isPresent();
        }
    }
    

    Example uses the following dependencies on Java:8

       compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.11.0'
       compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4'