我想做什么
我想使用Jackson来反序列化多态类型,使用标准@JsonTypeInfo
注释,如下所示:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = As.EXISTING_PROPERTY,
property = "identifier")
@JsonSubTypes({@Type(value = A.class, name = "A"),
@Type(value = B.class, name = "B")})
abstract Class Base {}
Class A implements Base {
public String identifier = "A";
}
Class B implements Base {
public String identifier = "B";
}
Class Decorated {
public String decoration = "DECORATION";
@JsonUnwrapped
public Base base;
}
/*
Serialized instance of Decorated WITHOUT @JsonUnwrapped:
{
"decoration" : "DECORATION",
"base" : {
"identifier" : "A"
}
}
Serialized instance of Decorated WITH @JsonUnwrapped:
{
"decoration" : "DECORATION",
"identifier" : "A"
}
*/
相关文章:Deserialize JSON with Jackson into Polymorphic Types - A Complete Example is giving me a compile error
通常,Jackson可以自动将其反序列化,如下所示:
public Object deserialize(String body, Class clazz) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(body, clazz);
}
(如果删除@JsonUnwrapped注释,这将起作用)
问题
多态类型在Jackson的
@JsonUnwrapped
批注中不能很好地发挥作用,正如2012年这张Jira票证中所述:http://markmail.org/message/pogcetxja6goycws#query:+page:1+mid:pogcetxja6goycws+state:results
不太令人鼓舞。
三年后:
http://markmail.org/message/cyeyc2ousjp72lh3
该死。
因此,有什么办法可以哄 jackson 在不修改
deserialize()
或删除@JsonUnwrapped
注释的情况下给我这种行为? 最佳答案
我来自this Gist的SinglePolyUnwrappedDeserializer
可以处理单个多态@JsonUnwrapped
属性。它在Kotlin中,但是如果需要可以很容易地移植到Java。例子:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes(
JsonSubTypes.Type(value = A::class, name = "a"),
JsonSubTypes.Type(value = B::class, name = "b")
)
abstract class Base
data class A(val x: Int) : Base()
data class B(val y: Boolean) : Base()
@JsonDeserialize(using = SinglePolyUnwrappedDeserializer::class)
data class C(val a: String, @JsonUnwrapped val b: Base)
AFAIK,支持其他注释的所有组合。唯一的限制是只有一个
@JsonUnwrapped
属性。如果还需要用于多态
@JsonUnwrapped
的通用序列化程序,则可以很容易地自己编写它,而无需进行任何反射(reflection)或自省(introspection):只需将内部对象的ObjectNode
合并到包含对象的ObjectNode
上。