Java 在Jackson json序列化中使用条件动态排除POJO属性
我需要在定义的POJO列表中动态排除某些属性。 要序列化的主要POJO是:Java 在Jackson json序列化中使用条件动态排除POJO属性,java,json,serialization,jackson,pojo,Java,Json,Serialization,Jackson,Pojo,我需要在定义的POJO列表中动态排除某些属性。 要序列化的主要POJO是: public class Foo { List<Bar> bar; public void setBar(List<Bar> bar) { this.bar = bar; } public List<Bar> getBar() { return this.bar; } public s
public class Foo
{
List<Bar> bar;
public void setBar(List<Bar> bar)
{
this.bar = bar;
}
public List<Bar> 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;
}
}
}
目前,我已尝试使用JsonFilter
和JacksonJsonViews
但无法获得所需的输出。
如果能为实现这一点提供任何指导,我将非常高兴。您应该编写一个自定义,根据其他属性值过滤掉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<Bar> 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));
}
}
我正在使用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;
}
}
}
注意:模型类在客户机-服务器体系结构env中通过网络传递,我刚才看到了罪魁祸首。
非常感谢Alexey在这件事上和我在一起。经过多次尝试,我发现Jackson 2.4.2可能要求我将序列化程序放在它可以使用的模型中。我想知道为什么,但可能是由于Java对象序列化要求,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 );
}
}
}
}
}
公共类后期项目
{
/*此项目的字段模板*/
私有列表field\u模板;
/**
*@作者Damilola Okuboyejo
*/
@JsonFilter(“FieldTemplatedFilter”)
公共静态类FieldTemplateObject
{
私有int-id;
私有布尔是_继承的;
私有字符串项_类型;
/**
*@返回id
*/
公共int getId()
{
返回id;
}
/**
*@param-id
*要设置的id
*/
公共无效集合id(内部id)
{
this.id=id;
}
/**
*@return是继承的
*/
公共布尔值isIs_继承()
{
回报是继承的;
}
/**
*@param是继承的
*要设置的对象是继承的
*/
public void集合是\u继承的(布尔值是\u继承的)
{
this.is_inherited=is_inherited;
}
/**
*@返回项目类型
*/
公共字符串getItem_type()
{
返回项目类型;
}
/**
*@param item_类型
*要设置的项目类型
*/
公共无效集合项类型(字符串项类型)
{
this.item\u type=item\u type;
}
}
公共静态类ModelFieldSerializer扩展SimpleBeanPropertyFilter
{
@凌驾
受保护的布尔值包括(BeanPropertyWriter)
{
返回true;
}
@凌驾
受保护的布尔值包括(PropertyWriter写入程序)
{
返回true;
}
@凌驾
公共字段(对象pPojo、JsonGenerator pJgen、,
序列化提供程序(提供程序、属性编写程序(编写程序)
抛出异常
{
if(FieldTemplateObject的pPojo实例)
{
布尔值vAllowId=((FieldTemplateObject)pPojo).isIs_inherited();
如果(!vAllowId&(“id”.equals(pWriter.getName()))
{
return;//跳过id属性
}
其他的
{
super.Asfield(pPojo、pJgen、pProvider、pWriter);
}
}
}
}
}
JsonFilter应在这种情况下使用。你能描述一下为什么过滤器不能为你工作吗?@AlexeyGavrilov,我创建了这样一个逻辑:@JsonFilter(“Exclude.Id”)类PropertyFilterMixIn{}
如果我有设置ignorableFieldNames=newArrayList().add(“Id”)代码>我可以做:FilterProviderFilters=new SimpleFilterProvider().addFilter(“Exclude.Id”,SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));ObjectWriter=mapper.writer(过滤器);System.out.println(writer.writeValueAsString(new Foo());我的挑战是动态地将
id`添加到ignorableFieldNames[]
当且仅当ignoreId
为true时。我似乎没有配置id为的过滤器。
@Damilola上面的例子对我很有用。你是哪一个版本的杰克逊?你能用你的过滤代码更新你的问题吗?看起来我的问题类似于与Tatu的讨论。你能告诉我如何为ObjectMapper注册你的过滤吗?将代码移到问题中也是有意义的,因为这不是实际的答案。vJsonMapper.setFilters(新的SimpleFilterProvider().addFilter(“FieldTemplateIdFilter”,新的ModelFieldSerializer())代码>您是在设置过滤器之前还是之后使用ObjectMapper?你能制作一个完整的类来重现你的问题吗?我的答案中的代码对你有用吗?这是一个相当冗长的代码。我在回答部分前面指定的注释应该重现这个问题。我注意到,只要我用@JsonFilter(“FieldTemplateIdFilter”)
标记FieldTemplateObject
,我就得到了异常。根据jacksondoc2.3+,我注意到属性或getter也可以用@JsonFilter注释。如果我尝试这样做,问题就会消失,但不会发生过滤。Java对象序列化要求不适用于Jackson。你应该遇到别的事情。如果您可以将最小化的可复制示例代码发布到GitHub,我会尝试跟进,否则我就没有任何线索了。@Alexey我刚刚将缩小的可复制版本发布到了
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;
}
}
}
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 );
}
}
}
}
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 );
}
}
}
}
}