【问题标题】:ktor with kotlinx serialization: how to use JSON.nonstrictktor 与 kotlinx 序列化:如何使用 JSON.nonstrict
【发布时间】:2019-05-02 00:18:57
【问题描述】:

我正在尝试初始化 Ktor http 客户端并设置 json 序列化。我需要允许 JSON.nonstrict 对象允许的非严格反序列化。只是不知道如何将此设置应用于序列化程序。

 val client = HttpClient {
                install(JsonFeature) {
                    serializer = KotlinxSerializer()                    
                }
        }

【问题讨论】:

    标签: kotlin ktor kotlinx.serialization


    【解决方案1】:

    您可以使用传递给 KotlinxSerializer 的 Json 构建器指定 json 配置。

    val client = HttpClient {
        install(JsonFeature) {
            serializer = KotlinxSerializer(Json {
                isLenient = true
                ignoreUnknownKeys = true
            })                    
        }
    }
    

    Json 构建器的确切字段是实验性的,可能会发生变化,因此请查看source code here.

    【讨论】:

      【解决方案2】:

      想通了——我们可以传入构造函数:

      serializer = KotlinxSerializer(Json.nonstrict)
      

      【讨论】:

      • 现在已弃用。
      • 形成我所看到的他们似乎每 2 天更改一次 API
      【解决方案3】:

      这种变化非常频繁,但是对于 Kotlin 1.4.10 和 Ktor 1.4.1,您需要传递一个 kotlinx Json(小心,因为还有一个 io.ktor.client.features.json.Json,我使用了导入别名区分它们,因为我需要两者import kotlinx.serialization.json.Json as KotlinJson)

      val client = HttpClient {
          install(JsonFeature) {
              serializer = KotlinxSerializer(KotlinJson { ignoreUnknownKeys = true })
          }
          ...
      

      【讨论】:

        【解决方案4】:

        Kotlin1.4.0 发布后:

        使用它来将字符串转换为对象:

        val response = Json {
            ignoreUnknownKeys = true
        }.decodeFromString(ResponseObject.serializer(), jsonString)
        

        对于您的 httpClient 使用:

        HttpClient {
            install(JsonFeature) {
                serializer = KotlinxSerializer()
            }
            install(Logging) {
                logger = Logger.DEFAULT
                level = LogLevel.ALL
            }
        }
        

        【讨论】:

        • 谢谢它的工作!因此,我已经在 HTTP 客户端的网络层中执行此操作,但第一个使用 decodeFromString 的客户端确实很有帮助,因为我需要将它用于将字符串转换为模型。
        【解决方案5】:

        对于那些使用改造的人,您可能需要考虑在改造构建器上使用JsonConfiguration(strictMode = false)

        例如:

        // your retrofit builder
        Retrofit.Builder()
                .baseUrl(url)
                .client(okHttpClient)
                .client(httpClient)
                .addConverterFactory(
                  Json(JsonConfiguration(strictMode = false))
                      .asConverterFactory(MediaType.get("application/json")
                )
        )
        

        来源:issue on the kotlinx github

        【讨论】:

        • Json { ignoreUnknownKeys = true }.asConverterFactory(contentType)
        【解决方案6】:

        根据上述 Rodion Altshuler 的回答,这对我的 KMP 项目有用:

        install(JsonFeature) {
            serializer = KotlinxSerializer(kotlinx.serialization.json.Json(JsonConfiguration.Stable.copy(strictMode = false))).apply {
              useDefaultTransformers = true
            }
        }
        

        【讨论】:

          【解决方案7】:

          “1.0.0RC”版本,加装后使用如下。

          Retrofit.Builder()
                  .client(okHttpClient)
                  .baseUrl(Env.BASE_URL)
                  .addConverterFactory(Json{
                      isLenient = true
                      ignoreUnknownKeys = true
                  }.asConverterFactory(MediaType.get("application/json")))
                  .addCallAdapterFactory(CoroutineCallAdapterFactory())
                  .build()
          

          【讨论】:

            【解决方案8】:

            这是为 Spring 响应式 Web 客户端配置 JsonConfig 的方法:

            
            
            val json = Json { ignoreUnknownKeys = true isLenient = true }
            
            val strategies = ExchangeStrategies
                .builder()
                .codecs { clientDefaultCodecsConfigurer ->
                    run {
                        clientDefaultCodecsConfigurer.defaultCodecs()
                            .kotlinSerializationJsonDecoder(KotlinSerializationJsonDecoder(json))
                        clientDefaultCodecsConfigurer.defaultCodecs()
                            .kotlinSerializationJsonEncoder(KotlinSerializationJsonEncoder(json))
            
                    }
                }.build()
            
            return WebClient
                .builder()
                .exchangeStrategies(strategies)
                .baseUrl(baseUrl!!)
                .build()
            

            【讨论】:

              【解决方案9】:

              似乎对于 1.4.32 我有如下:

              install(JsonFeature) {
                                  serializer = KotlinxSerializer(json = kotlinx.serialization.json.Json {
                                      isLenient = true
                                      ignoreUnknownKeys = true
                                  })
                              }
              

              【讨论】:

                猜你喜欢
                • 2020-08-19
                • 2019-12-31
                • 2020-11-20
                • 2020-12-05
                • 2021-02-24
                • 2019-06-17
                • 2020-03-09
                • 1970-01-01
                • 2021-05-14
                相关资源
                最近更新 更多