ktor with kotlinx serialization: how to use JSON.nonstrict
Asked Answered
H

10

22

I'm trying to initialize Ktor http client and setup json serialization. I need to allow non-strict deserialization which JSON.nonstrict object allows. Just can't get how to apply this setting to serializer.

 val client = HttpClient {
                install(JsonFeature) {
                    serializer = KotlinxSerializer()                    
                }
        }
Hillock answered 29/11, 2018 at 20:55 Comment(0)
L
18

You can specify json configurations using the Json builder, which you pass into the KotlinxSerializer.

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

The exact fields for the Json builder is experimental and subject to change, so check out the source code here.

Licketysplit answered 28/6, 2020 at 14:0 Comment(0)
C
16

After Kotlin 1.4.0 released:

use this for converting string to Object:

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

And for your httpClient use:

HttpClient {
    install(JsonFeature) {
        serializer = KotlinxSerializer()
    }
    install(Logging) {
        logger = Logger.DEFAULT
        level = LogLevel.ALL
    }
}
Chord answered 20/8, 2020 at 10:7 Comment(1)
Thanks it worked! So, I am already doing this in Network Layer in for HTTP client but the first one with decodeFromString was really helpful as I needed this for a String conversion to model.Vandavandal
H
12

Figured out - we can pass in constructor:

serializer = KotlinxSerializer(Json.nonstrict)
Hillock answered 29/11, 2018 at 21:51 Comment(2)
This is deprecated now.Licketysplit
form what I see they seem to change the API every 2 daysMincing
E
6

This change very often, but with Kotlin 1.4.10 and Ktor 1.4.1 you need to pass a kotlinx Json (be careful because there is also a io.ktor.client.features.json.Json, I used an import alias to distinguish them because I needed both import kotlinx.serialization.json.Json as KotlinJson)

val client = HttpClient {
    install(JsonFeature) {
        serializer = KotlinxSerializer(KotlinJson { ignoreUnknownKeys = true })
    }
    ...
Eva answered 1/11, 2020 at 20:58 Comment(0)
H
5

For those who use retrofit, you might want to consider using JsonConfiguration(strictMode = false) on the retrofit builder.

E.g:

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

Source: issue on the kotlinx github

Heavyhanded answered 12/10, 2019 at 14:43 Comment(1)
Json { ignoreUnknownKeys = true }.asConverterFactory(contentType)Upbraid
P
4

With the "1.0.0RC" version, the use with retrofit is as follows.

Retrofit.Builder()
        .client(okHttpClient)
        .baseUrl(Env.BASE_URL)
        .addConverterFactory(Json{
            isLenient = true
            ignoreUnknownKeys = true
        }.asConverterFactory(MediaType.get("application/json")))
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .build()
Phenomenalism answered 26/9, 2020 at 6:50 Comment(0)
A
4

For 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
            }
        }
Arbitral answered 27/7, 2022 at 9:0 Comment(0)
C
3

Working from Rodion Altshuler's answer above, this is what worked for me in my KMP project:

install(JsonFeature) {
    serializer = KotlinxSerializer(kotlinx.serialization.json.Json(JsonConfiguration.Stable.copy(strictMode = false))).apply {
      useDefaultTransformers = true
    }
}
Curettage answered 21/2, 2020 at 15:0 Comment(0)
C
2

This is how you can configure the JsonConfig for the Spring reactive Webclient:



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()
Cashew answered 22/3, 2021 at 17:56 Comment(0)
L
2

It seems that for 1.4.32 I have it as follows:

install(JsonFeature) {
                    serializer = KotlinxSerializer(json = kotlinx.serialization.json.Json {
                        isLenient = true
                        ignoreUnknownKeys = true
                    })
                }
Lev answered 13/4, 2021 at 22:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.