Java Jackson在子树外按名称忽略字段
我有一个类结构,如下面的简化版本:Java Jackson在子树外按名称忽略字段,java,json,serialization,filter,jackson,Java,Json,Serialization,Filter,Jackson,我有一个类结构,如下面的简化版本: public class A { public int a; public B b; public C c; public D d; public E e; } public class B { public int a; } public class C { public int a; public D d; } public class D { public int a; }
public class A {
public int a;
public B b;
public C c;
public D d;
public E e;
}
public class B {
public int a;
}
public class C {
public int a;
public D d;
}
public class D {
public int a;
}
public class E {
public int a;
}
序列化A时,我想删除所有类的A字段,C子树下包含的类除外。这意味着我想在C实例和d实例中保留a字段,但只保留C下的字段。我希望我说得清楚
我试图使用mixin或提供自定义序列化程序,但无法实现我想要的
请注意,实际上有太多的类,包括a字段,并且正在序列化的类是自动生成的。Put@JsonIgnorePropertiesignoreUnknown=true注释到需要跳过该字段的类。它将如下所示:
@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
public B b;
public C c;
public D d;
public E e;
}
public class B {
public int a;
}
public class C {
public int a;
public D d;
}
public class D {
public int a;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class E {
}
将@JsonIgnorePropertiesignoreUnknown=true注释放入类中,您需要跳过该字段。它将如下所示:
@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
public B b;
public C c;
public D d;
public E e;
}
public class B {
public int a;
}
public class C {
public int a;
public D d;
}
public class D {
public int a;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class E {
}
对字段使用JsonFilter注释。您可以通过MixIn特性注册它,并在给定的类型和getter方法上启用它。见以下代码:
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.addMixIn(A.class, AMixIn.class);
SimpleFilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("excludeA", SimpleBeanPropertyFilter.serializeAllExcept("a"));
mapper.setFilterProvider(filterProvider);
System.out.println(mapper.writeValueAsString(new A()));
}
}
@JsonFilter("excludeA")
interface AMixIn {
@JsonFilter("excludeA")
B getB();
@JsonFilter("excludeA")
D getD();
@JsonFilter("excludeA")
E getE();
}
对于您的POJO型号,上述代码打印:
{
"b" : { },
"c" : {
"a" : 3,
"d" : {
"a" : 4
}
},
"d" : { },
"e" : { }
}
另见:
对字段使用JsonFilter注释。您可以通过MixIn特性注册它,并在给定的类型和getter方法上启用它。见以下代码:
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.addMixIn(A.class, AMixIn.class);
SimpleFilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("excludeA", SimpleBeanPropertyFilter.serializeAllExcept("a"));
mapper.setFilterProvider(filterProvider);
System.out.println(mapper.writeValueAsString(new A()));
}
}
@JsonFilter("excludeA")
interface AMixIn {
@JsonFilter("excludeA")
B getB();
@JsonFilter("excludeA")
D getD();
@JsonFilter("excludeA")
E getE();
}
对于您的POJO型号,上述代码打印:
{
"b" : { },
"c" : {
"a" : 3,
"d" : {
"a" : 4
}
},
"d" : { },
"e" : { }
}
另见:
多亏了@MichałZiober提供的提示,我能够解决以下问题:
// custom serializer for C class, which in fact serializes all fields
public class CNormalSerializer extends JsonSerializer<C> {
@Override
public void serialize(C value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeRawValue(new ObjectMapper().writeValueAsString(value));
}
}
@JsonFilter(JsonFieldFilter.JSON_FILTER)
public class JsonFieldFilter {
public static final String JSON_FILTER = "Json filter";
}
public class X {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
// registered standard C serializer
SimpleModule simpleModule = new SimpleModule();
CNormalSerializer cSerializer = new CNormalSerializer ();
simpleModule.addSerializer(C.class, cSerializer);
objectMapper.registerModule(simpleModule);
// added the 'a' filter
objectMapper.addMixIn(Object.class, JsonFieldFilter.class);
String[] ignorableFieldNames = {"a"};
FilterProvider filters = new SimpleFilterProvider().addFilter(JsonFieldFilter.JSON_FILTER, SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
ObjectWriter writer = objectMapper.writer(filters);
writer.writeValueAsString(new A());
}
}
多亏了@MichałZiober提供的提示,我能够解决以下问题:
// custom serializer for C class, which in fact serializes all fields
public class CNormalSerializer extends JsonSerializer<C> {
@Override
public void serialize(C value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeRawValue(new ObjectMapper().writeValueAsString(value));
}
}
@JsonFilter(JsonFieldFilter.JSON_FILTER)
public class JsonFieldFilter {
public static final String JSON_FILTER = "Json filter";
}
public class X {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
// registered standard C serializer
SimpleModule simpleModule = new SimpleModule();
CNormalSerializer cSerializer = new CNormalSerializer ();
simpleModule.addSerializer(C.class, cSerializer);
objectMapper.registerModule(simpleModule);
// added the 'a' filter
objectMapper.addMixIn(Object.class, JsonFieldFilter.class);
String[] ignorableFieldNames = {"a"};
FilterProvider filters = new SimpleFilterProvider().addFilter(JsonFieldFilter.JSON_FILTER, SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
ObjectWriter writer = objectMapper.writer(filters);
writer.writeValueAsString(new A());
}
}
谢谢你的帮助。实际上,该模型相当复杂,无法创建相应的MixIn类。我能够解决我的答案中的问题。再次感谢!谢谢你的帮助。实际上,该模型相当复杂,无法创建相应的MixIn类。我能够解决我的答案中的问题。再次感谢!