9

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()                    
                }
        }
Rodion Altshuler
  • 1,583
  • 14
  • 29

9 Answers9

10

Figured out - we can pass in constructor:

serializer = KotlinxSerializer(Json.nonstrict)
xsveda
  • 13,503
  • 2
  • 14
  • 16
Rodion Altshuler
  • 1,583
  • 14
  • 29
9

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.

Jacques.S
  • 1,810
  • 1
  • 15
  • 21
4

After Kotlin 1.4.0 released:

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

And you httpClient:

            HttpClient {
                install(JsonFeature) {
                    serializer = KotlinxSerializer()
                }
                install(Logging) {
                    logger = Logger.DEFAULT
                    level = LogLevel.ALL
                }
            }
Dr.jacky
  • 2,499
  • 6
  • 41
  • 76
4

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 })
    }
    ...
Max Cruz
  • 557
  • 6
  • 11
3

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

mochadwi
  • 759
  • 8
  • 24
  • 75
2

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
    }
}
Joshua Kaden
  • 1,140
  • 11
  • 16
2

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()
fevziomurtekin
  • 144
  • 2
  • 10
1

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()
bluecheese
  • 31
  • 3
1

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
                    })
                }
Vojtěch Sázel
  • 492
  • 4
  • 14