我遇到了"多态反序列化问题"所以我配置jackson为非具体类添加类型信息作为属性,如下所示:
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.NONE)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE)
.withIsGetterVisibility(JsonAutoDetect.Visibility.NONE))
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_CONCRETE_AND_ARRAYS, "__class__")
它运行良好,但是对于集合实例(例如List),它创建了一个双元素数组,第一个位置包含一个字符串,其中包含集合的类型信息(java.util.ArrayList)。
这会影响客户端(Javascript)期望的json的结构,因为它预期数组的位置,现在有一个数组,其中另一个位于第二个位置。
我希望Jackson只为非集合而非具体类型插入类型信息,因为框架本身并不需要集合实现类型才能正确反序列化集合属性。
这是否可以以可配置的方式进行?
答案 0 :(得分:2)
您可以创建ObjectMapper.DefaultTypeResolverBuilder
的自定义版本并覆盖useForType()方法。
以下是默认方法的实现:
public boolean useForType(JavaType t)
{
switch (_appliesFor) {
case NON_CONCRETE_AND_ARRAYS:
while (t.isArrayType()) {
t = t.getContentType();
}
// fall through
case OBJECT_AND_NON_CONCRETE:
return (t.getRawClass() == Object.class) || !t.isConcrete();
case NON_FINAL:
while (t.isArrayType()) {
t = t.getContentType();
}
return !t.isFinal(); // includes Object.class
default:
//case JAVA_LANG_OBJECT:
return (t.getRawClass() == Object.class);
}
}
在您的版本中,只需添加此前提条件
即可if (t.isCollectionLikeType()) {
return false;
}
告诉Jackson跳过类似Collection的类型以插入类型信息。
并使用TypeResolverBuilder
ObjectMapper.setDefaultTyping(myCustomTyper);