使用@JsonUnwrapped使用Jackson反序列化多态类型



我想做什么

我想使用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将JSON反序列化为多态类型-一个完整的例子给了我一个编译错误

这通常可以由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:+页码:1+mid:pogsetxja6goycws+状态:结果

使用@JsonUnwrapped 处理多态类型

同意——虽然修复问题显然更可取,但如果不能做到这一点,改进错误消息将非常有用。

解包是实现变得足够复杂的功能之一,以至于出现的任何错误(尤其是反序列化)都会对抗生素产生耐药性。。。

几乎不令人鼓舞。

三年后:

http://markmail.org/message/cyeyc2ousjp72lh3

使用@JsonUnwrapped 处理多态类型

解决方案:无法修复

该死。

那么,在不修改deserialize()或删除@JsonUnwrapped注释的情况下,有什么方法可以说服Jackson给我这种行为吗?

此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上。

最新更新