0

I have following data class

@Serializable
data class TestClass(
    val id: Int,
    val content: String)

and following possible JSONs

{"id" = "1", "content": "1" }
{"id" = "2", "content": {"subcontent1": "subvalue1"} }
{"id" = "3", "content": {"subcontent2": "subvalue2"} }

Exact structure of content is unknown and may change. Is it possible to deserialize such json into TestClass ?

If I use

Json {
            ignoreUnknownKeys = true
            isLenient = true
        }.decodeFromString<TestClass>(inputJsonString)

I get following exception

Unexpected JSON token at offset 122: Expected string or non-null literal

Could you please provide any ideas on what is the best way to overcome this?

Do I have to write custom serializer or it can be done easier somehow?

Ivan
  • 340
  • 3
  • 14

1 Answers1

0

I have found an answer on my question.

Need to implement custimn serializer

object AnyToStringSerializer : KSerializer<String> {
override fun deserialize(decoder: Decoder): String {
    val jsonInput = decoder as? JsonDecoder ?: error("Can be deserialized only by JSON")
    val json = jsonInput.decodeJsonElement().jsonObject.toString()
    return json
}

override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("anyString", PrimitiveKind.STRING)


override fun serialize(encoder: Encoder, value: String) {
    val jsonElement = Json.parseToJsonElement(value)
    val jsonEncoder = encoder as? JsonEncoder ?: error("Can be deserialized only by JSON")
    jsonEncoder.encodeJsonElement(jsonElement)

}

}

And then use it for the field you want to be raw string

@SerialName("x")
@Serializable(with = AnyToStringSerializer::class)
val X: String,
Ivan
  • 340
  • 3
  • 14