Ktor与kotlinx.serialization: 如何使用JSON.nonstrict

19

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

 val client = HttpClient {
                install(JsonFeature) {
                    serializer = KotlinxSerializer()                    
                }
        }
10个回答

15
您可以使用 Json 构建器指定 JSON 配置,然后将其传递到 KotlinxSerializer 中。
val client = HttpClient {
    install(JsonFeature) {
        serializer = KotlinxSerializer(Json {
            isLenient = true
            ignoreUnknownKeys = true
        })                    
    }
}

Json builder的确切字段是实验性的并且可能会更改,因此请查看此处的源代码


12

在 Kotlin 1.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的方法真的很有帮助,因为我需要将字符串转换为模型。 - sud007

11

我已经想到了 - 我们可以在构造函数中传递参数:

serializer = KotlinxSerializer(Json.nonstrict)

4
这已经过时了。 - Jacques.S
1
据我所见,他们似乎每两天更改一次API。 - frankelot

6

这个要求经常会变化,但是在使用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 })
    }
    ...

5

对于那些使用retrofit的人,你可能想考虑在retrofit构建器上使用JsonConfiguration(strictMode = false)参数。

例如:

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

来源: kotlinx的GitHub问题

请注意,此链接为英文内容。

3
Json { ignoreUnknownKeys = true }.asConverterFactory(contentType) - Duanniston Cardoso Cabral

4

使用 "1.0.0RC" 版本时,与 Retrofit 的使用方式如下:

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

3

对于 ktor 2.0+

        return HttpClient(CIO) {
            engine {
                maxConnectionsCount = 10
            }

            install(ContentNegotiation) {
                json(kotlinx.serialization.json.Json {
                    ignoreUnknownKeys = true
                })
            }

            install(HttpTimeout) {
                requestTimeoutMillis = 1000L
                connectTimeoutMillis = 1000L
                socketTimeoutMillis = 1000L
            }
        }

3

参考Rodion Altshuler的答案,下面是我在我的KMP项目中所使用的方法:

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

2
这是如何为Spring响应式Webclient配置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()

2

看起来对于1.4.32版本,我的情况如下:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接