removing empty(technically) Objects from Array/List

1,241 views
Skip to first unread message

Ramesh Sibi

unread,
Nov 6, 2017, 3:47:43 PM11/6/17
to jackson-user
Hi, I am developing a micro service using spring boot. 
as part of it, i came across an issue with Jackson mapper which i couldn't resolve. any guidance is appreciated. please see the details below.


For example: i have following classes

import java.util.List;

public class School {

private List<Student> students;

public List<Student> getStudents() {
return students;
}

public void setStudents(List<Student> students) {
this.students = students;
}
}

import java.util.List;
public class Student {

private String firstName;
private String lastName;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}
}

In the spring boot class, i have following.

@SpringBootApplication
@RefreshScope
@RestController
public class Application 
{
@RequestMapping("/") 
           public School welcome() {
                             School school= new School();
                             List<Student> students = new ArrayList<Student>();
                            students.add(new Student()); 
                          school.setStudents(students); 
                           return school; 
                 }

@Configuration
    class WebMvcConfiguration extends WebMvcConfigurationSupport {
        @Override
        protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
            for(HttpMessageConverter<?> converter: converters) {
                if(converter instanceof MappingJackson2HttpMessageConverter) {
                    ObjectMapper mapper = ((MappingJackson2HttpMessageConverter)converter).getObjectMapper();
                    mapper.setSerializationInclusion(Include.NON_NULL);
                    mapper.setSerializationInclusion(Include.NON_EMPTY);                   
                }
            }
        }
    }
    
}

the current output i get is :
{
    "students": [
        {}
    ]
}

Expected Output:
{}

since the students has the empty object in an array, i would like the result to be ignored when serialized to JSON.
global solution did not work, as you can see i specified to ignore the empty objects.
Don't add an empty student object to the list, could be suggested as a solution but i would have to do for all the fields as the application grows.
Also i have scenarios where the Object in array can turn up empty, in turn the array being empty, since the array has only one empty properties object.
can anyone suggest a solution that i can set globally to resolve this issue?

Tatu Saloranta

unread,
Nov 6, 2017, 3:57:22 PM11/6/17
to jackson-user
Ok, first things first: these lines

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

would simply result in second one taking effect: there is no way to
combine settings, there is simply one default level.
Second: with jackson 2.9, you can separately specify filtering both
for Container (List) and contents within.
You would get better results with

mapper.setDefaultPropertyInclusion(JsonInclude.ValueOf.construct(Include.NON_EMPTY,
Include.NON_EMPTY));

since that would first check elements for filtering (i.e. leave out
any that are empty), and taking this into account,
see if container might not have any non-empty elements, and be empty.
(if only container was checked it would see content elements and
decide container is non empty).

So far so good: in theory you could get nested case to work.

Unfortunately there is no concept of empty POJOs -- only Collections,
arrays, referential types (Optional) and some
scalar have this filtering mechanism available -- at least not without
custom handlers. This is because checking is done at Java Object
level,
and not at json token level (if it was latter determination could be
done in generic fashion).

But you could register custom serializer for `Student`, and override
its "isEmpty(SerializerProvider, T)", and this should work.
Question there is whether you want to do that, it's quite a bit of
work. It would be possible to use "BeanSerializerModifier", get
hold of standard BeanSerializer, and wrap that (in fact,
StdDelegatingSerializer does about this), and only override
"isEmpty()" implementation.

So, there are no settings that allow you to achieve this declaratively
that I know. There are ways you can build something to do it.

-+ Tatu +-
> --
> You received this message because you are subscribed to the Google Groups
> "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to jackson-user...@googlegroups.com.
> To post to this group, send email to jackso...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages