使用条件动态排除Jackson json序列化中的POJO属性

我需要动态排除定义的POJO的List中的某些属性。 要序列化的主要POJO是:

public class Foo { List bar; public void setBar(List bar) { this.bar = bar; } public List getBar() { return this.bar; } public static class Bar { private int id; private boolean ignoreId; private String name; public void setId(int id) { this.id = id; } public int getId() { return this.id; } public void setIgnoreId(boolean ignoreId) { this.ignoreId = ignoreId; } public boolean isIgnoreId() { return this.ignoreId; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } } } 

如果ignoreId = true,则忽略id,如下所示:

 [ { "id": "1", "name": "one" }, { "name": "two" } { "name": "three" } { "id": "4", "name": "four" } ] 

目前,我已尝试使用JsonFilterJacksonJsonViews但无法获得所需的输出。 如果有任何指针可以实现这一点,我会很高兴。

您应该编写一个自定义Jacksonfilter ,它会根据其他属性值过滤掉POJO属性。 您应该重写PropertyFilter.serializeAsField()方法以访问序列化对象的实例。 这是一个例子:

 public class JacksonFilter2 { @JsonFilter("filter") public static class Bar { public final int id; @JsonIgnore public final boolean ignoreId; public final String name; public Bar(int id, boolean ignoreId, String name) { this.id = id; this.ignoreId = ignoreId; this.name = name; } } public static class ExcludeIdFilter extends SimpleBeanPropertyFilter { @Override protected boolean include(BeanPropertyWriter writer) { return true; } @Override protected boolean include(PropertyWriter writer) { return true; } @Override public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception { if (pojo instanceof Bar && "id".equals(writer.getName()) && ((Bar) pojo).ignoreId) { writer.serializeAsOmittedField(pojo, jgen, provider); } else { super.serializeAsField(pojo, jgen, provider, writer); } } } public static void main(String[] args) throws JsonProcessingException { List bars = Arrays.asList(new Bar(1, false, "one"), new Bar(2, true, "two")); ObjectMapper mapper = new ObjectMapper(); mapper.setFilters(new SimpleFilterProvider().addFilter("filter", new ExcludeIdFilter())); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bars)); } } 

输出:

 [ { "id" : 1, "name" : "one" }, { "name" : "two" } ] 

我正在使用Jackson 2.4.2。

模型对象是:

 public class PostProject { /* The field template of this project */ private List< FieldTemplateObject > field_templates; /** * @author Damilola Okuboyejo */ @JsonFilter( "FieldTemplateIdFilter" ) public static class FieldTemplateObject { private int id; private boolean is_inherited; private String item_type; /** * @return the id */ public int getId() { return id; } /** * @param id * the id to set */ public void setId( int id ) { this.id = id; } /** * @return the is_inherited */ public boolean isIs_inherited() { return is_inherited; } /** * @param is_inherited * the is_inherited to set */ public void setIs_inherited( boolean is_inherited ) { this.is_inherited = is_inherited; } /** * @return the item_type */ public String getItem_type() { if( item_type == null ) { item_type = PostProject.item_type; } return item_type; } /** * @param item_type * the item_type to set */ public void setItem_type( String item_type ) { this.item_type = item_type; } } } 

Myy序列化器是这样的:

 public static class ModelFieldSerializer extends SimpleBeanPropertyFilter { @Override protected boolean include( BeanPropertyWriter writer ) { return true; } @Override protected boolean include( PropertyWriter writer ) { return true; } @Override public void serializeAsField( Object pPojo, JsonGenerator pJgen, SerializerProvider pProvider, PropertyWriter pWriter ) throws Exception { if( pPojo instanceof FieldTemplateObject ) { if( ("id".equals( pWriter.getName() )) && ((FieldTemplateObject) pPojo).isIs_inherited() ) { pWriter.serializeAsOmittedField( pPojo, pJgen, pProvider ); } else { super.serializeAsField( pPojo, pJgen, pProvider, pWriter ); } } } } 

注意:模型类在客户端 – 服务器体系结构环境中通过网络传递

我刚看到罪魁祸首。 非常感谢@Alexey和我一起住在这里。 经过多次尝试,我发现Jackson 2.4.2可能要求我将我的系列设备放在它可以使用的模型中。 我想知道为什么,但可能是由于Java对象序列化要求,jackson未能在运行时映射filter。 我希望Tatu会在jackson的文档中注意这一点

 public class PostProject { /* The field template of this project */ private List< FieldTemplateObject > field_templates; /** * @author Damilola Okuboyejo */ @JsonFilter( "FieldTemplateIdFilter" ) public static class FieldTemplateObject { private int id; private boolean is_inherited; private String item_type; /** * @return the id */ public int getId() { return id; } /** * @param id * the id to set */ public void setId( int id ) { this.id = id; } /** * @return the is_inherited */ public boolean isIs_inherited() { return is_inherited; } /** * @param is_inherited * the is_inherited to set */ public void setIs_inherited( boolean is_inherited ) { this.is_inherited = is_inherited; } /** * @return the item_type */ public String getItem_type() { return item_type; } /** * @param item_type * the item_type to set */ public void setItem_type( String item_type ) { this.item_type = item_type; } } public static class ModelFieldSerializer extends SimpleBeanPropertyFilter { @Override protected boolean include( BeanPropertyWriter writer ) { return true; } @Override protected boolean include( PropertyWriter writer ) { return true; } @Override public void serializeAsField( Object pPojo, JsonGenerator pJgen, SerializerProvider pProvider, PropertyWriter pWriter ) throws Exception { if( pPojo instanceof FieldTemplateObject ) { boolean vAllowId = ((FieldTemplateObject) pPojo).isIs_inherited(); if( !vAllowId && ("id".equals( pWriter.getName() )) ) { return; // skip the id property } else { super.serializeAsField( pPojo, pJgen, pProvider, pWriter ); } } } } }