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

Zaa*_*ier 5 java polymorphism jackson deserialization

我想做的事

我想使用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"
    }
*/
Run Code Online (Sandbox Code Playgroud)

相关文章:将杰克逊的JSON反序列化为多态类型 - 完整示例给出了编译错误

这通常可以通过Jackson自动反序列化如下:

public Object deserialize(String body, Class clazz) {
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.readValue(body, clazz);
}
Run Code Online (Sandbox Code Playgroud)

(如果@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注释?

Ant*_*on3 4

SinglePolyUnwrappedDeserializerGist可以处理单个多态@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)
Run Code Online (Sandbox Code Playgroud)

AFAIK,支持其他注释的所有组合。唯一的限制是只有一个@JsonUnwrapped属性。

如果您还需要用于多态的通用序列化器@JsonUnwrapped,您可以非常轻松地自己编写它,而无需任何反射或内省:只需将ObjectNode内部对象的 合并到ObjectNode包含对象的 上。