【问题标题】:Serialize Sealed class within a data class using Gson in kotlin在 kotlin 中使用 Gson 序列化数据类中的密封类
【发布时间】:2020-02-17 10:08:53
【问题描述】:

我为 CustomAttribute 数据类下的 json 字段 Value 创建了一个密封类。该字段可以返回StringArray of Strings

我们如何从 json 中反序列化这个密封类?

data class CustomAttribute (
     val attributeCode: String,
     val value: Value 
)

sealed class Value {
      class StringArrayValue(val value: List<String>) : Value()
      class StringValue(val value: String)            : Value()
}

【问题讨论】:

  • 请问为什么需要一个可以是列表或单个字符串值的值参数?我问是因为我的古玩不要批评,顺便说一句,这可以帮助还是你已经看过了? github.com/Kotlin/kotlinx.serialization/issues/103
  • @Dak28 这是必需的,因为 API 可以一次返回任何这些值。感谢您的链接,但我仍然无法解决这个问题,请您帮忙..

标签: json kotlin gson json-deserialization sealed-class


【解决方案1】:

一种解决方案是按照this answer 中的说明使用RuntimeTypeAdapterFactory

val valueTypeAdapter = RuntimeTypeAdapter.of(Value::class.java)
    .registerSubtype(StringArrayValue::class.java)
    .registerSubtype(StringValue::class.java)
val gson = GsonBuilder().registerTypeAdapter(valueTypeAdapter).create()

RuntimeTypeAdapter 包含在 Gson 的源代码中,但不作为 Maven 工件公开。

它旨在复制/粘贴到您的项目from here

【讨论】:

    【解决方案2】:

    我过去曾成功序列化和反序列化一个密封类,并声明使用 Jackson 而不是 Gson 作为我的序列化引擎。

    我的密封类被定义为:

    @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, visible = true)
    sealed class FlexibleResponseModel
        class SnapshotResponse(val collection: List<EntityModel>): FlexibleResponseModel()
        class DifferentialResponse(val collection: List<EntityModel>): FlexibleResponseModel()
        class EventDrivenResponse(val collection: List<EntityEventModel>): FlexibleResponseModel()
        class ErrorResponse(val error: String): FlexibleResponseModel()
    

    使用注释后,无需进一步配置 Jackson 实例即可正确序列化和反序列化此密封类的实例,前提是通信双方都拥有密封类的统一定义。

    虽然我认识到 JsonTypeInfo 是 Jackson 特定的注释,但如果此功能是必须的,也许您可​​能会考虑从 Gson 切换 - 或者您可能能够找到 Gson 的等效配置,其中也包括该类序列化数据中的标识符。

    【讨论】:

    • 我目前在应用程序中使用 Gson,因此现阶段无法更改为 Jackson。我将尝试在 gson 中找到它的等价物。
    • @AkashBisariya 你找到了吗?
    • 不,我只是让它可以为空并在运行时检查值的类型@noloman
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 2020-11-20
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多