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

Dan*_*lay 7 serialization json filter jackson

我试图实现一个通用方法,将给定对象序列化为JSON,但只有那些在集合中传递的属性.如果可能的话,我希望在没有指定@JsonFilter类的情况下获得此功能.为此,我试图使用FilterExceptFilter杰克逊2.4.1.依赖关系:

这就是我现在所拥有的:

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

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

    SimpleBeanPropertyFilter filter =
        new SimpleBeanPropertyFilter.FilterExceptFilter(properties);
    SimpleFilterProvider fProvider = new SimpleFilterProvider();
    fProvider.addFilter("fieldFilter", filter);
    fProvider.setDefaultFilter(filter);

    ObjectMapper mapper = new ObjectMapper();
    mapper.setFilters(fProvider);

    String json = mapper.writeValueAsString(o);
    return json;
}
Run Code Online (Sandbox Code Playgroud)

但是,永远不会应用过滤器.它总是序列化所有属性.

Set<String> fields = new HashSet<String>(); fields.add("name");
String json = Serializer.serializeOnlyGivenFields(e, fields);
System.out.println(json);
Run Code Online (Sandbox Code Playgroud)

{"name":"测试实体","描述":"测试说明"}

我也曾尝试注册FilterProviderObjectWriter,但同样的结果:

String json = mapper.writer(fProvider).writeValueAsString(o);
Run Code Online (Sandbox Code Playgroud)

我错过了什么?杰克逊有没有很好的方法来实现这个目标?

Rob*_*ily 5

基于http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html的另一种设置过滤器的方法是设置一个类,该类扩展了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;
    }
}

}
Run Code Online (Sandbox Code Playgroud)


Sta*_*Man 0

另外一件事是,您必须通过注释指示要使用过滤器的 Java 类@JsonFilter

@JsonFilter("fieldFilter") public class MyType { }

然后它应该适用。

  • 那么,如果不使用“@JsonFilter”,就没有通用的方法来实现这一点吗? (2认同)