I am trying to implement a universal method which serializes the given object to JSON, but only those properties which are passed in a collection. If possible I want to get this functionality without specifying @JsonFilter
on the class. For this I am trying to use FilterExceptFilter
from Jackson 2.4.1. Dependencies:
Here is what I have at the moment:
public static String serializeOnlyGivenFields(Object o,
Collection<String> fields) throws JsonProcessingException {
if ((fields == null) || fields.isEmpty()) return null;
Set<String> properties = new HashSet<String>(fields);
SimpleBeanPropertyFilter filter =
new SimpleBeanPropertyFilter.FilterExceptFilter(properties);
SimpleFilterProvider fProvider = new SimpleFilterProvider();
fProvider.addFilter("fieldFilter", filter);
fProvider.setDefaultFilter(filter);
ObjectMapper mapper = new ObjectMapper();
mapper.setFilters(fProvider);
String json = mapper.writeValueAsString(o);
return json;
}
However, the filter is never applied. It always serializes all properties.
Set<String> fields = new HashSet<String>(); fields.add("name");
String json = Serializer.serializeOnlyGivenFields(e, fields);
System.out.println(json);
{"name":"Test entity","description":"Test description"}
I have also tried to register the FilterProvider
on the ObjectWriter
, but same result:
String json = mapper.writer(fProvider).writeValueAsString(o);
What am I missing? Is there a nice way to achieve this with Jackson?
Overview This tutorial is going to illustrate how we can use Jackson to only serialize a field if it meets a specific, custom criteria. For example, say we only want to serialize an integer value if it's positive – and we want to skip it entirely if it's not.
1. Overview This tutorial will show how to ignore certain fields when serializing an object to JSON using Jackson 2.x. This is very useful when the Jackson defaults aren't enough and we need to control exactly what gets serialized to JSON — and there are several ways to ignore properties.
And when you're serializing or deserializing them with Jackson in your Spring Boot application, you just want to ignore them. For example, you might store the user's password.
A more flexible but also more complex alternative would be using a fully custom serializer to control the JSON output – so if this solution isn't flexible enough, it may be worth looking into that.
Based on http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html an alternate way to set up the filter is setting up a class that extends JacksonAnnotationIntrospector and overrides findFilterId. You can then specify to find your filter in the findFilterId. This could be made to be as robust if you want based on some other map or algorithm. Below is sample code. Not sure if the performance is better than the solution above but it seems to be simpler and probably more easily extensible. I was doing this for serializing CSV using Jackson. Any feedback is welcome!
public class JSON {
private static String FILTER_NAME = "fieldFilter";
public static String serializeOnlyGivenFields(Object o,
Collection<String> fields) throws JsonProcessingException {
if ((fields == null) || fields.isEmpty()) fields = new HashSet<String>();
Set<String> properties = new HashSet<String>(fields);
SimpleBeanPropertyFilter filter =
new SimpleBeanPropertyFilter.FilterExceptFilter(properties);
SimpleFilterProvider fProvider = new SimpleFilterProvider();
fProvider.addFilter(FILTER_NAME, filter);
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector( new AnnotationIntrospector() );
String json = mapper.writer(fProvider).writeValueAsString(o);
return json;
}
private static class AnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public Object findFilterId(Annotated a) {
return FILTER_NAME;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With