json - Jackson 中的过滤字段和子字段

标签 json serialization filter field jackson

对于一些 JSON:

{
  "id":123,
  "name":"Test",
  "sub_object":{
    "sub_field_1":1,
    "sub_field_2":2,
    "sub_field_array":[
      {
        "array_field_1":true,
        "array_field_2":false
      },
      {
        "array_field_1":false,
        "array_field_2":true
      }
    ],
    "sub_sub_object":{
      "field_1":"me",
      "field_2":"myself",
      "field_3":"i",
    }
  }
}

我想应用一个树状的字段名称列表。这可能可以用 JSONPath 表示:
root
  |-id
  |-sub_object
    |-sub_field_2
    |-sub_field_array
      |-array_field_1
    |-sub_sub_object

然后我应该得到类似的东西:
{
  "id":123,
  "sub_object":{
    "sub_field_2":2,
    "sub_field_array":[
      {
        "array_field_1":true
      },
      {
        "array_field_1":false
      }
    ],
    "sub_sub_object":{
      "field_1":"me",
      "field_2":"myself",
      "field_3":"i",
    }
  }
}

这个想法是,对于某些字段层次结构,我想限制输出的字段。

我是通过一个已注释其对象字段的库来执行此操作的,但我无法修改该库。如果可以的话,这并不重要,因为层次结构将基于每个序列化。目前,我将对象传递给 JsonGenerator 的 writeObject 方法,但这会返回所有内容。

一些子对象可能会共享字段名称,因此它不像创建一个 SimpleBeanPropertyFilter 来仅序列化一组名称那么简单。

先感谢您,

约翰

最佳答案

您可以编写一个自定义属性过滤器,它会考虑序列化属性的声明类。

您应该扩展 SimpleBeanPropertyFilter并覆盖 include(PropertyWriter writer)方法。如果给定 writer参数是 BeanPropertyWriter 的一个实例类,您可以提取有关属性来源的信息并应用您的自定义过滤逻辑。

下面是一个过滤器示例,它将排除信息存储在类及其属性名称的映射中:

public class JacksonHierarchyFilter {
    @JsonFilter("filter")
    public static class A {
        public final String field1;

        public A(final String field1) {this.field1 = field1;}
    }

    @JsonFilter("filter")
    public static class B {
        public final String field1;
        public final List<A> list;

        public B(final String field1, final List<A> list) {
            this.field1 = field1;
            this.list = list;
        }
    }
    @JsonFilter("filter")
    public static class Foo {
        public final String field1;
        public final List<B> field2;

        public Foo(final String field1, final List<B> field2) {
            this.field1 = field1;
            this.field2 = field2;
        }
    }

    public static class MyFilter extends SimpleBeanPropertyFilter {
        private final Map<Class<?>, Set<String>> excludePropMap;

        public MyFilter(final Map<Class<?>, Set<String>> excludePropMap) {
            this.excludePropMap = excludePropMap;
        }

        @Override
        protected boolean include(final BeanPropertyWriter writer) {
            return false;
        }

        @Override
        protected boolean include(final PropertyWriter writer) {
            if (writer instanceof BeanPropertyWriter) {
                final Class<?> cls = ((BeanPropertyWriter) writer).getMember().getDeclaringClass();
                final Set<String> excludePropSet = excludePropMap.get(cls);
                return excludePropSet == null || !excludePropSet.contains(writer.getName());
            }
            return true;
        }
    }

    public static void main(String[] args) throws JsonProcessingException {
        final B b = new B("B1", Arrays.asList(new A("A1"), new A("A2")));
        final Foo foo = new Foo("foo", Arrays.asList(b));
        final ObjectMapper mapper = new ObjectMapper();
        final SimpleFilterProvider filters = new SimpleFilterProvider();
        final Map<Class<?>, Set<String>> excludePropMap =
                Collections.<Class<?>, Set<String>>singletonMap(
                        B.class,
                        Collections.singleton("field1"));
        filters.addFilter("filter", new MyFilter(excludePropMap));
        mapper.setFilters(filters);
        final ObjectWriter objectWriter = mapper.writerWithDefaultPrettyPrinter();
        System.out.println(objectWriter.writeValueAsString(foo));
    }

}

输出:
{
  "field1" : "foo",
  "field2" : [ {
    "list" : [ {
      "field1" : "A1"
    }, {
      "field1" : "A2"
    } ]
  } ]
}

关于json - Jackson 中的过滤字段和子字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12865569/

相关文章:

json - 从 curl 请求中提取 token 并在另一个 shell 命令中使用

scala - 如何从 Scala 中的字符串中去除除数字以外的所有内容(快速一行)

asp.net - SQL排序,分页,过滤ASP.NET中的最佳实践

javascript - 如何在 Angular 2 中使用 *ngFor 打印列表中的 json 数组值?

iphone - iOS 从返回 null 的静态库中解析 JSON

javascript - Newtonsoft日期解析错误(删除一天)

Delphi组件序列化

java - 反序列化一个 ArrayList。没有有效的构造函数

java - java序列化时对象之间的循环依赖

javascript - 如何解析电子邮件文本的 "somebody wrote..."部分?