没有类型的杰克逊反序列化

时间:2019-12-14 00:11:17

标签: kotlin jackson deserialization

我有一个与杰克逊(Jackson)和多态性有关的问题:是否有一种方法可以在不指定类型的情况下反序列化JSON字符串?

假设我不拥有此消息(例如,外部API),并且我有两条单独的消息分别在不同的时间出现:

{
    "responseCode": 200
    "responseMessage": "You did something successfully"
}

{
    "errorCode": 401
    "errorDescription": "Permission denied"
}

我想通过多态性使用基于这些消息创建的一些数据类来反序列化此消息(请参见下一个代码块中的抽象类):

data class MyDataClass(
    val responseCode: Int,
    val responseMessage: String
): MyAbstractClass()

data class MyOtherDataClass(
    val errorCode: Int,
    val errorDescription: String
): MyAbstractClass()

我正在通过一个函数来解析这些消息,该函数将使用Jackson对象映射器反序列化字符串化的JSON有效负载:

@JsonSubTypes(
    JsonSubTypes.Type(value = MyDataClass::class),
    JsonSubTypes.Type(value = MyOtherDataClass::class)
)
@JsonIgnoreProperties(ignoreProperties = true)
abstract class MyAbstractClass

fun receiveMessage(message: String) {
    val convertedMessage = jacksonObjectMapper().readValue<MyAbstractClass>(message)

    log.info(convertedMessage)
    /* prints either:
    MyDataClass(responseCode=200, responseMessage=You did something successfully)
    OR
    MyOtherDataClass(errorCode=401, errorDescription=Permission denied)
    */
}

但是由于我没有描述如何识别数据类(使用@JsonTypeInfo),所以它失败了。

要重复一遍,我很好奇是否有一种方法可以将传入消息反序列化为我的多态类型之一而不必指定@JsonTypeInfo。或者,如果我必须描述@JsonTypeInfo,我该怎么做而MyAbstractClass的两个子类之间没有相似之处?

1 个答案:

答案 0 :(得分:1)

我将编写一个自定义解串器,将其用作通用JSONObject等。然后,我将检查是否存在区分密钥。例如:

// pseudocode
when (json: JSONObject) {
    hasKey("responseCode") -> // deserialize as MyDataClass
    hasKey("errorCode") -> // deserialize as MyOtherDataClass
}