【问题标题】:Deserializing Polymorphic Types with @JsonUnwrapped using Jackson使用 Jackson 使用 @JsonUnwrapped 反序列化多态类型
【发布时间】:2016-09-22 06:33:53
【问题描述】:

我想做的事

我想用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

使用@JsonUnwrapped 处理多态类型

同意 - 虽然修复问题显然更可取,但如果无法做到,改进错误消息将很有用。

解包是实现变得足够复杂以至于出现的任何错误(尤其是反序列化)往往具有抗生素抗性的功能之一...

很难令人鼓舞。

三年后:

http://markmail.org/message/cyeyc2ousjp72lh3

使用@JsonUnwrapped 处理多态类型

解决方案:不会修复

该死的。

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

【问题讨论】:

  • 您是否设法解决了这个问题或找到了解决方法?
  • 我没有,不。在编写“装饰”字段后,您始终可以实现一个自定义序列化程序,将 Base 的序列化委托给 Jackson。

标签: java jackson polymorphism deserialization


【解决方案1】:

来自this GistSinglePolyUnwrappedDeserializer 可以处理单个多态@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 上。

【讨论】:

  • 你能详细说明一下序列化吗?一个 JsonSerializer 有一个 JsonGenerator,所以不清楚如何将内部对象序列化为 ObjectNode?​​span>
  • @TomQuarendon (gen.codec as ObjectMapper).valueToTree<ObjectNode>(inner)(很抱歉几个月没有回复,哈哈。当时我觉得这很明显,我只需要反序列化器)
猜你喜欢
  • 1970-01-01
  • 2014-05-01
  • 2012-10-18
  • 2012-07-24
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
相关资源
最近更新 更多