Reputation:
I have a map which I want to serialize using Jackson but only want to serialize a subset of it. Say I have a simple map as follows:
final Map<String, String> map = new HashMap<>();
map.put("key 1", "value 1");
map.put("key 2", "value 2");
map.put("_internal key 1", "value 3");
map.put("_internal key 2", "value 4");
Then when serializing this I want to filter out any item whose key starts with _
, so that the serialized representation would be {'key 1': 'value 1','key 2': 'value 2'}
.
I started looking at @JsonFilter
but can't find any examples beyond very simplistic ones against basic types and nothing which appears to help with this more advanced type of filtering.
What's the best way to provide this custom serialization?
This is using Jackson 2.4, in case it matters.
Upvotes: 3
Views: 2311
Reputation: 10853
You can achieve this by defining a Jackson filter which outputs the keys that don't start with an underscore, and enable this filter for all the Map classes via the annotation introspector. Here is an example:
public class JacksonMapSubset {
public static void main(String[] args) throws JsonProcessingException {
final Map<String, String> map = new HashMap<>();
map.put("key 1", "value 1");
map.put("key 2", "value 2");
map.put("_internal key 1", "value 3");
map.put("_internal key 2", "value 4");
ObjectMapper mapper = new ObjectMapper();
SimpleFilterProvider filters = new SimpleFilterProvider();
final String filterName = "exclude-starting-with-underscore";
mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public Object findFilterId(Annotated a) {
if (Map.class.isAssignableFrom(a.getRawType())) {
return filterName;
}
return super.findFilterId(a);
}
});
filters.addFilter(filterName, new SimpleBeanPropertyFilter() {
@Override
protected boolean include(BeanPropertyWriter writer) {
return true;
}
@Override
protected boolean include(PropertyWriter writer) {
return !writer.getName().startsWith("_");
}
});
mapper.setFilters(filters);
System.out.println(mapper.writeValueAsString(map));
}
}
Output:
{"key 1":"value 1","key 2":"value 2"}
Upvotes: 4