您可以结合使用自定义序列化程序和使用JsonViews的自定义属性过滤器。这是使用Jackson 2.0的一些代码
定义一个自定义注释:
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface FilterUsingView { Class<?>[] value();}定义一些视图:
// Define your views herepublic static class Views { public class Public {}; public class Internal extends Public{};}然后,您可以像这样编写实体。请注意,您可以定义自己的注释,而不是使用
@JsonView:
public class Foo { @JsonView(Views.Public.class) public String bar; @JsonView(Views.Internal.class) public String biz;}public class FooContainer { public Foo fooA; @FilterUsingView(Views.Public.class) public Foo fooB;}然后,这是代码开始的地方:)首先,您的自定义过滤器:
public static class CustomFilter extends SimpleBeanPropertyFilter { private Class<?>[] _nextViews; public void setNextViews(Class<?>[] clazz){ _nextViews = clazz; } @Override public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider prov, BeanPropertyWriter writer) throws Exception { Class<?>[] propViews = writer.getViews(); if(propViews != null && _nextViews != null){ for(Class<?> propView : propViews){ System.out.println(propView.getName()); for(Class<?> currentView : _nextViews){ if(!propView.isAssignableFrom(currentView)){ // Do the filtering! return; } } } } // The property is not filtered writer.serializeAsField(bean, jgen, prov); }}然后
AnnotationIntrospector,将执行以下两项操作的自定义:
- 为任何bean启用自定义过滤器…除非在类上定义了另一个过滤器(如果您明白我的意思,则不能同时使用它们)
- 如果他发现了
@FilterUsingView
注释,则启用您的CustomSerializer 。
这是代码
public class CustomAnnotationIntrospector extends AnnotationIntrospector { @Override public Version version() { return DatabindVersion.instance.version(); } @Override public Object findFilterId(AnnotatedClass ac) { // CustomFilter is used for EVERY Bean, unless another filter is defined Object id = super.findFilterId(ac); if (id == null) { id = "CustomFilter"; } return id; } @Override public Object findSerializer(Annotated am) { FilterUsingView annotation = am.getAnnotation(FilterUsingView.class); if(annotation == null){ return null; } return new CustomSerializer(annotation.value()); }}这是您的自定义序列化程序。它唯一要做的就是将注释的值传递给自定义过滤器,然后让默认的序列化程序完成这项工作。
public class CustomSerializer extends JsonSerializer<Object> { private Class<?>[] _activeViews; public CustomSerializer(Class<?>[] view){ _activeViews = view; } @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { BeanPropertyFilter filter = provider.getConfig().getFilterProvider().findFilter("CustomFilter"); if(filter instanceof CustomFilter){ CustomFilter customFilter = (CustomFilter) filter; // Tell the filter that we will filter our next property customFilter.setNextViews(_activeViews); provider.defaultSerializevalue(value, jgen); // Property has been filtered and written, do not filter anymore customFilter.setNextViews(null); }else{ // You did not define a CustomFilter ? Well this serializer is useless... provider.defaultSerializevalue(value, jgen); } }}终于!让我们放在一起:
public class CustomModule extends SimpleModule { public CustomModule() { super("custom-module", new Version(0, 1, 0, "", "", "")); } @Override public void setupModule(SetupContext context) { super.setupModule(context); AnnotationIntrospector ai = new CustomAnnotationIntrospector(); context.appendAnnotationIntrospector(ai); }}@Testpublic void customField() throws Exception { FooContainer object = new FooContainer(); object.fooA = new Foo(); object.fooA.bar = "asdf"; object.fooA.biz = "fdsa"; object.fooB = new Foo(); object.fooB.bar = "qwer"; object.fooB.biz = "test"; ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new CustomModule()); FilterProvider fp = new SimpleFilterProvider().addFilter("CustomFilter", new CustomFilter()); StringWriter writer = new StringWriter(); mapper.writer(fp).writevalue(writer, object); String expected = "{"fooA":{"bar":"asdf","biz":"fdsa"},"fooB":{"bar":"qwer"}}"; Assert.assertEquals(expected, writer.toString());}


