用Jackson解析Kotlin中泛型密封类

eqqqjvef  于 2022-12-13  发布在  Kotlin
关注(0)|答案(2)|浏览(159)

我有下面的泛型密封类来表示网络响应的状态。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "status")
@JsonSubTypes(
    value = [
        JsonSubTypes.Type(value = Response.OK::class, name = "OK"),
        JsonSubTypes.Type(value = Response.Error::class, name = "ERROR"),
    ]
)
sealed class Response<out Content, out Error> {
    data class OK<out Content>(val content: Content) : Response<Content, Nothing>()
    data class Error<out Error>(val error: Error) : Response<Nothing, Error>()
}

网络响应json可以具有status": "OK",在这种情况下,它包含content密钥,或者具有"status": "ERROR",在这种情况下,它包含error密钥。
contenterror键下的类型对于我正在与之对话的每个端点可以是不同的。
例如,一个端点返回String作为类型,因此Response<String, String>
第一次
另一个端点返回Double作为内容,Int作为错误,因此
Response<Double, Int>
第一个
解析失败,但消息为
一个
我注意到只要内容是通用的,解析就可以正常工作:

sealed class Response<out Content > {
    data class OK<out Content>(val content: Content) : Response<Content>()
    object Error : Response<Nothing>()
}

当然我会丢失错误负载
将json解析为泛型类的正确方法是什么?

lvmkulzt

lvmkulzt1#

我认为问题出在Nothing上,因为它就像Void,你不能创建它的示例,也不能获得类型信息,这就是为什么序列化库在处理它时遇到困难的原因。所以当前问题的解决方案是像这样更新模型定义,它能工作。尽管这并不理想。

sealed class Response<out Content, out Error> {

    data class OK<out Content, out Error>(val content: Content) : Response<Content, Error>()

    data class Error<out Content, out Error>(val error: Error) : Response<Content, Error>()
}
rta7y2nd

rta7y2nd2#

对于这种情况,您根本不需要泛型。只需:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "status")
@JsonSubTypes(
    value = [
        JsonSubTypes.Type(value = Response.OK::class, name = "OK"),
        JsonSubTypes.Type(value = Response.Error::class, name = "ERROR"),
    ]
)
sealed interface Response {
  data class Success(val content: Content): Response
  data class Error(val error: Error): Response
}

Jackson将能够正确地解析所有内容。

相关问题