杰克逊序列化地图的一个子集

时间:2014-08-10 17:47:34

标签: java serialization jackson

我有一张地图,我想用Jackson序列化,但只想序列化它的一部分。假设我有一个简单的地图如下:

final Map<String, String> map = new HashMap<>();
map.put("key 1", "value 1");
map.put("key 2", "value 2");
map.put("_internal key 1", "value 3");
map.put("_internal key 2", "value 4");

然后在序列化时,我想过滤掉任何以_开头的项目,以便序列化的表示形式为{'key 1': 'value 1','key 2': 'value 2'}

我开始关注@JsonFilter,但除了基本类型之外,找不到任何非常简单的例子,也没有任何可能有助于这种更高级的过滤类型的例子。

提供此自定义序列化的最佳方法是什么?

这是使用杰克逊2.4,如果它很重要。

1 个答案:

答案 0 :(得分:3)

您可以通过定义Jackson filter来实现此目的,该the annotation introspector输出不以下划线开头的键,并通过{{3}}为所有Map类启用此过滤器。这是一个例子:

public class JacksonMapSubset {

    public static void main(String[] args) throws JsonProcessingException {
        final Map<String, String> map = new HashMap<>();
        map.put("key 1", "value 1");
        map.put("key 2", "value 2");
        map.put("_internal key 1", "value 3");
        map.put("_internal key 2", "value 4");

        ObjectMapper mapper = new ObjectMapper();

        SimpleFilterProvider filters = new SimpleFilterProvider();
        final String filterName = "exclude-starting-with-underscore";
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
            @Override
            public Object findFilterId(Annotated a) {
                if (Map.class.isAssignableFrom(a.getRawType())) {
                    return filterName;
                }
                return super.findFilterId(a);
            }
        });
        filters.addFilter(filterName, new SimpleBeanPropertyFilter() {
            @Override
            protected boolean include(BeanPropertyWriter writer) {
                return true;
            }

            @Override
            protected boolean include(PropertyWriter writer) {
                return !writer.getName().startsWith("_");
            }
        });

        mapper.setFilters(filters);
        System.out.println(mapper.writeValueAsString(map));
    }
}

输出:

{"key 1":"value 1","key 2":"value 2"}