java 使用条件动态排除Jackson json序列化中的POJO属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25603581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using conditions to dynamically exclude POJO property in Hymanson json serialization
提问by Damilola
I have a requirement to dynamically exclude certain property within a List of a defined POJO. The main POJO to be serialized is:
我需要在已定义 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 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;
}
}
}
id is to be ignored if ignoreId = true, like so:
如果 ignoreId = true,则 id 将被忽略,如下所示:
[
{ "id": "1", "name": "one" },
{ "name": "two" }
{ "name": "three" }
{ "id": "4", "name": "four" }
]
At the moment, I have tried using JsonFilter
and HymansonJsonViews
but couldn't get the required output.
I would be glad if any pointer can be given towards achieving this.
目前,我已经尝试使用JsonFilter
和HymansonJsonViews
,但无法获得所需的输出。如果可以为实现这一目标提供任何指示,我会很高兴。
回答by Alexey Gavrilov
You should write a custom Hymanson filterwhich would filter out a POJO property depending on other property value. You should override the PropertyFilter.serializeAsField()
method to get access to the instance of the serialized object. Here is an example:
您应该编写一个自定义Hymanson 过滤器,它会根据其他属性值过滤掉 POJO 属性。您应该覆盖该PropertyFilter.serializeAsField()
方法以访问序列化对象的实例。下面是一个例子:
public class HymansonFilter2 {
@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));
}
}
Output:
输出:
[ {
"id" : 1,
"name" : "one"
}, {
"name" : "two"
} ]
回答by Damilola
I am using Hymanson 2.4.2.
我正在使用Hyman逊 2.4.2。
Model object is:
模型对象是:
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 serializer is like so:
我的序列化器是这样的:
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 );
}
}
}
}
NOTE: The model class is passed through the network in a client-server architecture env
注意:模型类在客户端 - 服务器架构环境中通过网络传递
回答by Damilola
I just saw the culprit. Thanks a lot @Alexey for staying with me on this. After much try, I discover Hymanson 2.4.2 might have required that I place my serialzer within the model it would work with. I wonder why though, but probably due to Java object serialization requirements, Hymanson was failing to map the Filter at runtime. I hope Tatu would note this in Hymanson documentation
我刚刚看到了罪魁祸首。非常感谢@Alexey 和我在一起。经过多次尝试,我发现 Hymanson 2.4.2 可能要求我将序列化器放在它可以使用的模型中。我想知道为什么,但可能是由于 Java 对象序列化要求,Hymanson 未能在运行时映射过滤器。我希望 Tatu 会在 Hymanson 文档中注意到这一点
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 );
}
}
}
}
}