Json 使用Jackson序列化时如何仅包含特定属性

Json 使用Jackson序列化时如何仅包含特定属性,json,serialization,filter,jackson,Json,Serialization,Filter,Jackson,我试图实现一个通用方法,该方法将给定对象序列化为JSON,但只将在集合中传递的属性序列化。如果可能的话,我希望在不在类上指定@JsonFilter的情况下获得此功能。为此,我尝试使用Jackson 2.4.1中的内容。依赖项: 以下是我目前的情况: publicstaticstringserializeOnlyGiveFields(对象o, 集合字段)引发JsonProcessingException{ if((fields==null)| | fields.isEmpty())返回n

我试图实现一个通用方法,该方法将给定对象序列化为JSON,但只将在集合中传递的属性序列化。如果可能的话,我希望在不在类上指定
@JsonFilter
的情况下获得此功能。为此,我尝试使用Jackson 2.4.1中的内容。依赖项:

以下是我目前的情况:

publicstaticstringserializeOnlyGiveFields(对象o,
集合字段)引发JsonProcessingException{
if((fields==null)| | fields.isEmpty())返回null;
Set properties=新哈希集(字段);
SimpleBeanPropertyFilter过滤器=
新的SimpleBeanPropertyFilter.FilterExceptFilter(属性);
SimpleFilterProvider fProvider=新SimpleFilterProvider();
fProvider.addFilter(“fieldFilter”,filter);
fProvider.setDefaultFilter(过滤器);
ObjectMapper mapper=新的ObjectMapper();
映射器设置过滤器(fProvider);
字符串json=mapper.writeValueAsString(o);
返回json;
}
但是,从未应用过滤器。它总是序列化所有属性

Set fields=newhashset();字段。添加(“名称”);
String json=Serializer.SerializeOnlyGiveFields(e,字段);
System.out.println(json);
{“名称”:“测试实体”,“描述”:“测试描述”}

我还尝试注册了,但结果相同:

String json = mapper.writer(fProvider).writeValueAsString(o);

我错过了什么?使用Jackson是否有一个很好的方法来实现这一点?

另外一件事是,您必须指示Java类,该类的筛选器将由
@JsonFilter
注释使用:


@JsonFilter(“字段过滤器”)
公共类MyType{}


然后它应该适用。

我找到了一个基于的解决方案。我改为总是使用。这样,将始终应用过滤器

性能方面不是一个很好的解决方案,因为每次方法调用都必须构造一个
ObjectMapper
。请随时发布改进或建议

模块实现:

公共类FilteredModule扩展了SimpleModule{
私有静态最终长serialVersionUID=1L;
@凌驾
公共无效设置模块(设置上下文上下文){
super.setupModule(上下文);
addBeanSerializerModifier(新的BeanSerializerModifier(){
@凌驾
公共JsonSerializer修改序列化程序(
SerializationConfig配置,
BEAN说明beanDesc,
JsonSerializer(序列化程序){
if(BeanSerializerBase的序列化程序实例){
返回新的FilteredBeanSerializer(
(BeanSerializerBase)序列化程序);
} 
返回序列化程序;
}                   
});
}
私有类FilteredBeanSerializer扩展BeanSerializer{
公共筛选器BeanSerializer(BeanSerializerBase源){
超级(来源);
}
@凌驾
受保护的空字段(对象arg0、JsonGenerator arg1、,
SerializerProvider arg2)引发IOException,
JsonGenerationException{
super.SerializedFieldsFiltered(arg0、arg1、arg2);
}
}
}
API方法:

publicstaticstringserializeOnlyGiveFields(对象o,
集合字段)引发JsonProcessingException{
如果((fields==null)| | fields.isEmpty())fields=new HashSet();
Set properties=新哈希集(字段);
SimpleBeanPropertyFilter过滤器=
新的SimpleBeanPropertyFilter.FilterExceptFilter(属性);
SimpleFilterProvider fProvider=新SimpleFilterProvider();
fProvider.addFilter(“fieldFilter”,filter);
fProvider.setDefaultFilter(过滤器);
ObjectMapper mapper=新的ObjectMapper();
registerModule(新的FilteredModule());
字符串json=mapper.writer(fProvider.writeValueAsString(o);
返回json;
}
示例

实体e=新实体(“测试实体”、“测试描述”);
Set fields=new HashSet();字段。添加(“名称”);
字符串json=json.SerializeOnlyGiveFields(e,字段);
System.out.println(json);
{“名称”:“测试实体”}

基准测试:同一对象上的1000次迭代

基于另一种设置过滤器的方法,设置一个扩展JacksonAnnotationIntrospector并重写findFilterId的类。然后可以指定在findFilterId中查找筛选器。如果您希望基于其他映射或算法,可以使其具有同样的健壮性。下面是示例代码。不确定性能是否优于上述解决方案,但它似乎更简单,而且可能更易于扩展。我这样做是为了使用Jackson序列化CSV。欢迎任何反馈

public class JSON {

private static String FILTER_NAME = "fieldFilter";

public static String serializeOnlyGivenFields(Object o,
                                              Collection<String> fields) throws JsonProcessingException {
    if ((fields == null) || fields.isEmpty()) fields = new HashSet<String>();

    Set<String> properties = new HashSet<String>(fields);

    SimpleBeanPropertyFilter filter =
            new SimpleBeanPropertyFilter.FilterExceptFilter(properties);
    SimpleFilterProvider fProvider = new SimpleFilterProvider();
    fProvider.addFilter(FILTER_NAME, filter);

    ObjectMapper mapper = new ObjectMapper();
    mapper.setAnnotationIntrospector( new AnnotationIntrospector() );

    String json = mapper.writer(fProvider).writeValueAsString(o);
    return json;
}

private static class AnnotationIntrospector extends JacksonAnnotationIntrospector {
    @Override
    public Object findFilterId(Annotated a) {
        return FILTER_NAME;
    }
}

}
公共类JSON{
私有静态字符串过滤器\u NAME=“fieldFilter”;
公共静态字符串SerializeOnlyGiveFields(对象o,
集合字段)引发JsonProcessingException{
如果((fields==null)| | fields.isEmpty())fields=new HashSet();
Set properties=新哈希集(字段);
SimpleBeanPropertyFilter过滤器=
新的SimpleBeanPropertyFilter.FilterExceptFilter(属性);
SimpleFilterProvider fProvider=新SimpleFilterProvider();
fProvider.addFilter(过滤器名称,过滤器);
ObjectMapper mapper=新的ObjectMapper();
setAnnotationIntroSector(新的AnnotationIntroSector());
字符串json=mapper.writer(fProvider.writeValueAsString(o);
返回json;
}
私有静态类AnnotationIntrospector扩展了JacksonAnnotationIntrospector{
@凌驾
公共对象findFilterId(带注释的a){
返回过滤器名称;
}
}
}

因此,如果不使用
@
public class JSON {

private static String FILTER_NAME = "fieldFilter";

public static String serializeOnlyGivenFields(Object o,
                                              Collection<String> fields) throws JsonProcessingException {
    if ((fields == null) || fields.isEmpty()) fields = new HashSet<String>();

    Set<String> properties = new HashSet<String>(fields);

    SimpleBeanPropertyFilter filter =
            new SimpleBeanPropertyFilter.FilterExceptFilter(properties);
    SimpleFilterProvider fProvider = new SimpleFilterProvider();
    fProvider.addFilter(FILTER_NAME, filter);

    ObjectMapper mapper = new ObjectMapper();
    mapper.setAnnotationIntrospector( new AnnotationIntrospector() );

    String json = mapper.writer(fProvider).writeValueAsString(o);
    return json;
}

private static class AnnotationIntrospector extends JacksonAnnotationIntrospector {
    @Override
    public Object findFilterId(Annotated a) {
        return FILTER_NAME;
    }
}

}