我想做什么
我想使用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"
}
*/
这通常可以通过Jackson自动反序列化如下:
public Object deserialize(String body, Class clazz) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(body, clazz);
}
(如果删除@JsonUnwrapped注释,这将有效)
问题
多态类型与杰克逊的@JsonUnwrapped
注释不相符,正如2012年的这张Jira票据中所讨论的那样:
http://markmail.org/message/pogcetxja6goycws#query:+page:1+mid:pogcetxja6goycws+state:results
使用@JsonUnwrapped处理多态类型
同意 - 在修理内容时显然更可取,如果无法完成,改进错误消息将非常有用。
展开是一个功能,其中实现变得足够复杂,任何错误出现(反序列化esp)往往是抗生素抗性...
几乎没有鼓励。
三年后:
http://markmail.org/message/cyeyc2ousjp72lh3
使用@JsonUnwrapped处理多态类型
决议:不会修复
该死。
那么,有没有办法哄骗杰克逊给我这个行为而不修改deserialize()
或删除@JsonUnwrapped
注释?
答案 0 :(得分:2)
我来自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
的通用序列化程序,则可以很容易地自己编写它,而无需进行任何反思或自省:只需将内部对象的ObjectNode
合并到ObjectNode
上的对象。