use*_*874 5 serialization json field filter jackson
For some 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",
}
}
}
Run Code Online (Sandbox Code Playgroud)
I want to apply a tree-like list of field names. This could probably be expressed in JSONPath:
root
|-id
|-sub_object
|-sub_field_2
|-sub_field_array
|-array_field_1
|-sub_sub_object
Run Code Online (Sandbox Code Playgroud)
Then I should get back something like:
{
"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",
}
}
}
Run Code Online (Sandbox Code Playgroud)
The idea is that, for some field hierarchy, I want to limit the fields that are output.
I am doing this through a library that has annotated its objects' fields, but I cannot modify the library. It wouldn't really matter if I could because the hierarchy will be on a per-serialization basis. Currently, I am passing the objects into the JsonGenerator's writeObject method, but that returns everything.
Some sub-objects may share field names, so it is not as simple as creating a SimpleBeanPropertyFilter to serialize only a set of names.
Thank you in advance,
John
您可以编写一个自定义属性过滤器,它将考虑序列化属性的声明类。
您应该扩展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));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
{
"field1" : "foo",
"field2" : [ {
"list" : [ {
"field1" : "A1"
}, {
"field1" : "A2"
} ]
} ]
}
Run Code Online (Sandbox Code Playgroud)