当前位置: 首页 > 知识库问答 >
问题:

具有嵌套类型信息属性的Jackson多态反序列化

景承教
2023-03-14
{
  "metadata": {
    "eventName": "FooEvent",
    "field1": "bla"
  },
  "event": { ... }
}

如何使用多态反序列化和嵌套类型信息属性反序列化它?我在@JsonTypeInfo中使用metadata.eventName嵌套属性,如下所示:

@JsonTypeInfo(
    use = Id.NAME,
    include = As.EXISTING_PROPERTY,
    visible = true,
    property = "metadata.eventName"
)
@JsonSubTypes({
    @Type(name="fooEvent", value = FooEvent.class)
    @Type(name="barEvent", value = BarEvent.class)
})
public class EventPayload<T> {
     private Metadata metadata;
     private T event;
}

鉴于config Jackson抱怨无法找到属性:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'metadata.eventName' that is to contain type id  (for class EventPayload)
 at [Source: {
  "metadata": {
     "eventName": "FooEvent",
     "field1": "bla"
  },
  "content": { ... }
}; line: 16, column: 1]

共有1个答案

百里秋月
2023-03-14

您在这里面临两个问题:

  1. 正如您所看到的,Jackson无法轻松地且仅通过注释使用嵌套JSON对象中的属性来推导要反序列化到的类型。
  2. @JsonTypeInfo@JsonSubtypes意味着继承,例如Class FooEventPayload extends EventPayload。在您的示例中,EventPayload 是一个泛型类,需要告诉Jackson使用TypeReference是什么T例如这里的内容

假设您想要一个泛型类,我建议先将其序列化为树,然后查看树以获得指定类型的属性,然后将树转换为此类型的对象。您可以跳过@jsontypeinfo@jsonsubtypes。例如。

// user object mapper to parse JSON into a tree (node is the root) 
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);

// use get as many times as needed by depth
// to get the value that defines the type to deserialise to
String type = node.get("metadata").get("eventName").textValue();

// convert JsonNode variable to the required type
if (type.equals("fooEvent")) {
    EventPayload<FooEvent> event = 
        mapper.convertValue(node, new TypeReference<EventPayload<FooEvent>>(){});
} else if (type.equals("barEvent")) {
    EventPayload<BarEvent> event =
        mapper.convertValue(node, new TypeReference<EventPayload<BarEvent>>(){});
}
 类似资料:
  • 我正试图找到一种方法来使用jackson的多态反序列化功能,它将基于嵌套在标头/控件对象中的属性反序列化我的对象: JSON 1-类别1: JSON 2-类别2 父类(类似这样的注释) 子类 jackson中是否有现成的功能可以让我进行这种反序列化,或者我遗漏了什么?

  • 我正在尝试使用Jakson反序列化一个嵌套的多态类型。也就是说,我的顶级类型引用了另一个多态类型,该类型最终由不抽象的类扩展。这不起作用,它会抛出一个异常。 下面是我尝试做的一个简化的例子。 我得到了关于抽象类型的标准异常。 让我解释一下我的用例。我有一个描述数据工作流的Json文档。我在“Level One”有一个抽象类型,描述对单个值的操作。我派生了一堆不是抽象的类,它们实现了公共操作(我用@

  • 当我使用Jackson ectivtMapper将有效负载序列化为字符串值时,我很难获取要维护的泛型属性的类型信息。 我想要达到的结果如下。 我实际得到的结果如下(注意TestClassA缺少@type信息)。 我使用的测试是: “test JSON编组”测试中有两个版本。注释掉的版本和未注释的版本都会产生完全相同的结果。 第二个测试验证TestClassA本身是否生成了正确的类型信息。 只有当包

  • 我看过jackson反序列化@JsonTypeInfo的一个例子,那就是: 我试过了,效果很好。现在的问题是,在示例类中,Cat和Dog是从Animal中引用的,我想避免这种情况。有没有一种方法可以将类型绑定从类动物中移除,并且仍然进行反序列化工作?谢谢

  • 问题内容: 如果我有这样的类结构: 还有另一种反序列化的方法吗?在父类上使用此注释: 我不想强迫我的API的客户包括反序列化一个子类。 杰克逊不是使用,而是提供了一种方法来注释子类并通过唯一属性将其与其他子类区分开来?在上面的示例中,这类似于“如果JSON对象将其反序列化为,如果它将其反序列化为”。 问题答案: 感觉像是应该使用的东西,但是我在文档中进行了选择,可以提供的任何属性似乎都不符合您所描

  • 问题内容: 我正在尝试使用Jakson反序列化嵌套的多态类型。意思是我的顶级类型引用了另一个多态类型,该类型最终由不是抽象的类扩展。这不起作用,并引发异常。 这是我要尝试做的简化示例。 我得到有关抽象类型的标准例外。 让我解释一下我的用例。我有一个描述数据工作流程的Json文档。我在“一级”有一个抽象类型,描述了对单个值的操作。我派生了一堆不是抽象的类,它们实现了常见的操作(我用@JsonSubT