如果我使用子类型和泛型,则无法使用 Jackson 解析 Json

问题描述

我有一个这样的类层次结构:

@JsonIgnoreProperties(ignoreUnkNown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes(
    JsonSubTypes.Type(value = SubClass1::class,name = "SC1"),JsonSubTypes.Type(value = SubClass2::class,name = "SC2")
)
interface Base

data class SubClass1(
    @JsonProperty("i") val i: Int
) : Base

data class SubClass2(
    @JsonProperty("s") val s: String
) : Base

我还有一些容器:

data class Container(
    @JsonProperty("base") val base: Base
)

data class GenericContainer<T: Base> (
    @JsonProperty("base") val base: T
)

如果我在以下情况下使用它,它会起作用:

    val mapper = ObjectMapper()

//  It works
    val jsonStringSubClass = mapper.writeValueAsstring(SubClass1(1))    // {"base":{"@type":"SC1","i":1}}
    val subClassInstance = mapper.readValue(jsonStringSubClass,SubClass1::class.java)
    println(subClassInstance)   // SubClass1(i=1)

//  It works too
    val jsonStringContainer = mapper.writeValueAsstring(Container(SubClass1(1)))    // {"base":{"@type":"SC1","i":1}}
    val containerInstance = mapper.readValue(jsonStringContainer,Container::class.java)
    println(containerInstance)    // Container(base=SubClass1(i=1))

//  It works too
    val jsonStringGenericContainer = mapper.writeValueAsstring(GenericContainer(SubClass1(1)))    // {"base":{"@type":"SC1","i":1}}
    val genericType = mapper.typeFactory.constructParametricType(
        GenericContainer::class.java,SubClass1::class.java
    )
    val genericContainerInstance = mapper.readValue<GenericContainer<SubClass1>>(jsonStringGenericContainer,genericType)
    println(genericContainerInstance)    // GenericContainer(base=SubClass1(i=1))

但是如果我使用一些集合或者不指定泛型的类型:

data class GenericContainer<T> (
    @JsonProperty("base") val base: T
)

我有一个例外

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type,class SubClass1]: missing type id property '@type' (for POJO property 'base')
 at [Source: (String)"{"base":{"i":1}}"; line: 1,column: 15] (through reference chain: GenericContainer["base"])

因为 json 字符串不包含字段 '@type'。

我有两个问题:

  1. 如果我知道类型是什么,我可以解析没有类型字段的 json 字符串吗?因为我可以从一些客户那里得到这样的 json 字符串——他们不知道子类型。
  2. 如果 1 不可能,我可以总是将这些类的“@type”字段写入 json 字符串吗?

我目前使用的是最新的 fastxml jackson (2.12.3)。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)