繁体   English   中英

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

[英]Jackson polymorphic deserialization with nested type info property

我受限于给定的JSON结构:

{
  "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;
}

鉴于配置杰克逊抱怨该物业无法找到:

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. 正如您所见,杰克逊不能轻易地通过注释使用嵌套JSON对象中的属性来推断要反序列化的类型。
  2. @JsonTypeInfo@JsonSubTypes用于继承,例如class FooEventPayload extends EventPayload 在你的情况下, EventPayload<T>是一个泛型类,杰克逊需要告诉你什么是TTypeReference 在这里看看例如

假设你想要一个泛型类,我建议首先序列化到树中,查看树以获取指定类型的属性,然后将树转换为此类型的对象。 您可以跳过@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>>(){});
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM