Jackson ObjectMapper:如何从序列化中省略(忽略)某些类型的字段?
Jackson ObjectMapper: How to omit (ignore) fields of certain type from serialization?
如何告诉 Jackson ObjectMapper 从序列化中忽略某些类型的字段 (class),在我的 Object.class
情况下?
约束:
- 无法控制来源class - 它是第三方class
- Class 正在序列化的类型预先未知 - 我猜它不符合 MixIn(s)
- 此类字段名称预先未知
为了提供帮助,下面是一个单元测试,期望从序列化中忽略字段 objectsList
和 objectField
,但它的方法不正确,它按名称而不是按类型过滤它们.
public static class FavoriteShows {
public Simpsons favorite = new Simpsons();
public BigBangTheory preferred = new BigBangTheory();
}
public static class Simpsons {
public String title = "The Simpsons";
public List<Object> objectsList = List.of("homer", "simpson");
public Object objectField = new HashMap() {{
put("mr", "burns");
put("ned", "flanders");
}};
}
public static class BigBangTheory {
public String title = "The Big Bang Theory";
public List<Object> objectsList = List.of("sheldon", "cooper");
public Object objectField = new HashMap() {{
put("leonard", "hofstadter");
put("Raj", "koothrappali");
}};
}
public abstract static class MyMixIn {
@JsonIgnore
private Object objectField;
@JsonIgnore
private Object objectsList;
}
@Test
public void test() throws JsonProcessingException {
// GIVEN
// Right solution must work for any (MixIn(s) is out of questions) Jackson annotated class
// without its modification.
final ObjectMapper mapper = new ObjectMapper()
.addMixIn(Simpsons.class, MyMixIn.class)
.addMixIn(BigBangTheory.class, MyMixIn.class);
// WHEN
String actual = mapper.writeValueAsString(new FavoriteShows());
System.out.println(actual);
// THEN
// Expected: {"favorite":{"title":"The Simpsons"},"preferred":{"title":"The Big Bang Theory"}}
assertThat(actual).isEqualTo("{\"favorite\":{\"title\":\"The Simpsons\"},\"preferred\":{\"title\":\"The Big Bang Theory\"}}");
}
如果您正在使用 mixins,您应该能够使用 @JsonIgnoreType 进行注释以使其忽略 class。 docs For reference Globally ignore class in Jackson
其中一种方法是使用自定义 AnnotationIntrospector
。
class A {
int three = 3;
int four = 4;
B b = new B();
// setters + getters
}
class B {
int one = 1;
int two = 2;
// setters + getters
}
忽略类型为B
的所有字段:
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
protected boolean _isIgnorable(Annotated a) {
return super._isIgnorable(a)
// Ignore B.class
|| a.getRawType() == B.class
// Ignore List<B>
|| a.getType() == TypeFactory.defaultInstance()
.constructCollectionLikeType(List.class, B.class);
}
});
String json = mapper.writeValueAsString(new A());
如何告诉 Jackson ObjectMapper 从序列化中忽略某些类型的字段 (class),在我的 Object.class
情况下?
约束:
- 无法控制来源class - 它是第三方class
- Class 正在序列化的类型预先未知 - 我猜它不符合 MixIn(s)
- 此类字段名称预先未知
为了提供帮助,下面是一个单元测试,期望从序列化中忽略字段 objectsList
和 objectField
,但它的方法不正确,它按名称而不是按类型过滤它们.
public static class FavoriteShows {
public Simpsons favorite = new Simpsons();
public BigBangTheory preferred = new BigBangTheory();
}
public static class Simpsons {
public String title = "The Simpsons";
public List<Object> objectsList = List.of("homer", "simpson");
public Object objectField = new HashMap() {{
put("mr", "burns");
put("ned", "flanders");
}};
}
public static class BigBangTheory {
public String title = "The Big Bang Theory";
public List<Object> objectsList = List.of("sheldon", "cooper");
public Object objectField = new HashMap() {{
put("leonard", "hofstadter");
put("Raj", "koothrappali");
}};
}
public abstract static class MyMixIn {
@JsonIgnore
private Object objectField;
@JsonIgnore
private Object objectsList;
}
@Test
public void test() throws JsonProcessingException {
// GIVEN
// Right solution must work for any (MixIn(s) is out of questions) Jackson annotated class
// without its modification.
final ObjectMapper mapper = new ObjectMapper()
.addMixIn(Simpsons.class, MyMixIn.class)
.addMixIn(BigBangTheory.class, MyMixIn.class);
// WHEN
String actual = mapper.writeValueAsString(new FavoriteShows());
System.out.println(actual);
// THEN
// Expected: {"favorite":{"title":"The Simpsons"},"preferred":{"title":"The Big Bang Theory"}}
assertThat(actual).isEqualTo("{\"favorite\":{\"title\":\"The Simpsons\"},\"preferred\":{\"title\":\"The Big Bang Theory\"}}");
}
如果您正在使用 mixins,您应该能够使用 @JsonIgnoreType 进行注释以使其忽略 class。 docs For reference Globally ignore class in Jackson
其中一种方法是使用自定义 AnnotationIntrospector
。
class A {
int three = 3;
int four = 4;
B b = new B();
// setters + getters
}
class B {
int one = 1;
int two = 2;
// setters + getters
}
忽略类型为B
的所有字段:
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
protected boolean _isIgnorable(Annotated a) {
return super._isIgnorable(a)
// Ignore B.class
|| a.getRawType() == B.class
// Ignore List<B>
|| a.getType() == TypeFactory.defaultInstance()
.constructCollectionLikeType(List.class, B.class);
}
});
String json = mapper.writeValueAsString(new A());