【问题标题】:How to serialize a generic class with kontlinx.serialization?如何使用 kontlinx.serialization 序列化泛型类?
【发布时间】:2021-02-06 18:28:03
【问题描述】:

我遵循tutorial 为我的泛型类创建了自定义序列化。但我仍然有错误:

SerializationException:“ApiResponse”类的序列化程序不是 成立。将类标记为@Serializable 或提供序列化程序 明确的。

我的 ApiResponse 类如下所示:

@Serializable(with = ApiResponseSerializer::class)
class ApiResponse<T>(
    @SerialName("data")
    val data: T? = null,
    @SerialName("error")
    val error: ApiError? = null
)

上面注释中使用的ApiResponseSerializer是:

class ApiResponseSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<ApiResponse<T>> {
    override val descriptor: SerialDescriptor = buildClassSerialDescriptor("ApiResponseDataSerializer") {
        val dataDescriptor = dataSerializer.descriptor
        element("data", dataDescriptor)
        element("error", ApiError.serializer().descriptor)
    }
    override fun deserialize(decoder: Decoder): ApiResponse<T> =
        decoder.decodeStructure(descriptor) {
            var data: T? = null
            var error: ApiError? = null
            loop@ while (true) {
                when (val i = decodeElementIndex(descriptor)) {
                    0 -> data = decodeSerializableElement(descriptor, i, dataSerializer)
                    1 -> error = decodeSerializableElement(descriptor, i, ApiError.serializer())
                    CompositeDecoder.DECODE_DONE -> break
                    else -> throw SerializationException("Unknown index $i")
                }
            }
            ApiResponse(data, error)
        }
    override fun serialize(encoder: Encoder, value: ApiResponse<T>) {
        encoder.encodeStructure(descriptor) {
            encodeNullableSerializableElement(descriptor, 0, dataSerializer, value.data)
            encodeNullableSerializableElement(descriptor, 1, ApiError.serializer(), value.error)
        }
    }
}

然后,当我尝试序列化我的数据对象时,我收到了上面提到的异常。

Json.encodeToString(ApiResponse(data = response.data))
---- OR ----
Json.encodeToString(ApiResponse.serializer(T::class.serializer()), ApiResponse(data = response.data))

谁能告诉我哪里错了?谢谢。

【问题讨论】:

  • Json.encodeToString(ApiResponse(data = "some string")) 在我的机器上运行良好。 response.data 的类型是什么?是否标有@Serializable注解?
  • @loop 标签的意义何在?
  • 在我的例子中,数据可以用任何带有@Serializable注解的数据类来表示。 @loop 注释出现在文档中。到KSerializer 类,并且,我如何理解它,标记了程序在break 的情况下应该返回的位置。更多:kotlinlang.org/docs/reference/…现在它可以工作了。也许是由于缓存不好或其他原因。无论如何感谢您的测试和支持

标签: kotlin serialization kotlinx.serialization


【解决方案1】:

问题中的代码很好,程序由于缓存错误或其他原因而失败。

【讨论】:

    【解决方案2】:

    好像是kapt的bug。

    我从序列化存储库中找到了这个comment

    但是,由于提到的 kapt 问题,目前是不可能的。一个可行的解决方法可能是将模型和序列化程序移至单独的 Gradle 模块,该模块不由 kapt 处理。

    关于这个问题还有更多问题:

    【讨论】:

      【解决方案3】:

      kotlinx.serialization 使用特定的插件来生成序列化程序。如果您直接在 IDE 中启动代码(例如通过 main 方法),则不会使用该插件。

      为确保生成的序列化程序在类路径中可用,请尝试从单元测试中调用您的代码并使用适当的 Gradle 任务启动此测试。

      【讨论】:

        猜你喜欢
        • 2016-09-02
        • 2017-04-18
        • 2022-09-23
        • 2016-05-27
        • 1970-01-01
        • 2014-04-05
        • 2012-10-18
        • 2013-08-26
        相关资源
        最近更新 更多