Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global property filter in Jackson

Tags:

json

jackson

Is there a way to register a global property filter in ObjectMapper? Global means that it will be applied to all serialized beans. I can't use annotations (I can't modify serialized beans) and don't know what properties the beans have. The filtering should be name based.

My first idea was to write a custom serializer, but I don't know what should I pass to the constructor.

like image 767
DAN Avatar asked Nov 22 '11 23:11

DAN


1 Answers

I'd make use of a FilterProvider. It's a little involved, but not too unwieldy.

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.map.annotate.JsonFilter;
import org.codehaus.jackson.map.ser.FilterProvider;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Bar bar = new Bar();
    bar.id = "42";
    bar.name = "James";
    bar.color = "blue";
    bar.foo = new Foo();
    bar.foo.id = "7";
    bar.foo.size = "big";
    bar.foo.height = "tall";

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    System.out.println(mapper.writeValueAsString(bar));
    // output: 
    // {"id":"42","name":"James","color":"blue","foo":{"id":"7","size":"big","height":"tall"}}

    String[] ignorableFieldNames = { "id", "color" };

    FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));

    mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    mapper.getSerializationConfig().addMixInAnnotations(Object.class, PropertyFilterMixIn.class);
    ObjectWriter writer = mapper.writer(filters);

    System.out.println(writer.writeValueAsString(bar));
    // output:
    // {"name":"James","foo":{"size":"big","height":"tall"}}
  }
}

@JsonFilter("filter properties by name")
class PropertyFilterMixIn
{

}

class Bar
{
  String id;
  String name;
  String color;
  Foo foo;
}

class Foo
{
  String id;
  String size;
  String height;
}

For other approaches and more information, I recommend the following resources.

  • http://wiki.fasterxml.com/JacksonJsonViews
  • http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html
  • http://wiki.fasterxml.com/JacksonFeatureJsonFilter
  • http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html
like image 57
Programmer Bruce Avatar answered Nov 18 '22 03:11

Programmer Bruce