首页 > 解决方案 > Ktor:在多平台中以 List 为根序列化/反序列化 JSON

问题描述

我们如何使用 kotlin.serialize 和 Ktor 的 HttpClient 来反序列化/序列化 JSON 并以列表为根?我正在按如下方式创建 HttpClient:

HttpClient {
       install(JsonFeature) {
           serializer = KotlinxSerializer().apply {
               setMapper(MyClass::class, MyClass.serializer())
               setMapper(AnotherClass::class, AnotherClass.serializer())
           }
       }
       install(ExpectSuccess)
   }

似乎我需要为 List 设置映射器,但是这对于泛型是不可能的。我看到我可以使用 MyClass.serializer().list 为它获取序列化程序,但是将其注册为对 http 请求进行反序列化/序列化并不简单。有人知道一个好的解决方案吗?

标签: jsonserializationkotlinktorkotlin-multiplatform

解决方案


您可以编写包装器和自定义序列化程序:

@Serializable
class MyClassList(
    val items: List<MyClass>
) {

    @Serializer(MyClassList::class)
    companion object : KSerializer<MyClassList> {

        override val descriptor = StringDescriptor.withName("MyClassList")

        override fun serialize(output: Encoder, obj: MyClassList) {
            MyClass.serializer().list.serialize(output, obj.items)
        }

        override fun deserialize(input: Decoder): MyClassList {
            return MyClassList(MyClass.serializer().list.deserialize(input))
        }
    }
}

注册它:

HttpClient {
    install(JsonFeature) {
        serializer = KotlinxSerializer().apply {
            setMapper(MyClassList::class, MyClassList.serializer())
        }
    }
}

并使用:

suspend fun fetchItems(): List<MyClass> {
    return client.get<MyClassList>(URL).items
}

推荐阅读