Deserializing a json object property to a String using kotlinx.serialization
Asked Answered
B

2

12

Given json as follows where the structure of the payload object will vary:

{
    "id": 1,
    "displayName": "Success",
    "payload": {
        "someProperty": "example",
        "someOtherProperty": {
            "someNestedProperty": "example"
        }
    }
}

...using kotlinx.serialization how can I deserialize this into the following data class, where the value of payload should be the raw json string of the payload object.

@Serializable
data class Stub(
    val id: Int,
    val displayName: String,
    val payload: String
)
Boise answered 26/9, 2020 at 10:29 Comment(0)
B
18

Struggled to find a way of doing this with Serializers, but it was simple enough to implement manually using JsonElement.

val jsonObject = Json.parseToJsonElement(jsonString).jsonObject
val stub = Stub(
    jsonObject["id"]!!.jsonPrimitive.int,
    jsonObject["displayName"]!!.jsonPrimitive.content,
    jsonObject["payload"]!!.toString()
)
Boise answered 26/9, 2020 at 19:14 Comment(0)
S
13

There is a way to handle using JSONTransformingSerializer. It allows you to transform the json prior to deserialization. In this case from a jsonElement into a jsonPrimitive (of type String).

First create a transformer as follows:

object JsonAsStringSerializer: JsonTransformingSerializer<String>(tSerializer = String.serializer()) {
    override fun transformDeserialize(element: JsonElement): JsonElement {
        return JsonPrimitive(value = element.toString())
    }
}

Now apply this transfer to the specific element in your data class by adding...

@Serializable(with = JsonAsStringSerializer::class)

just above the property you want to transform. Like this...

@Serializable
data class Stub(
    val id: Int,
    val displayName: String,
    @Serializable(with = JsonAsStringSerializer::class)
    val payload: String
)

The value of payload will be a string:

"{'someProperty': 'example','someOtherProperty': {'someNestedProperty':'example'}"

If you are later trying to deserialize this into different models depending on the structure, check out the JsonContentPolymorphicSerializer feature.

Softa answered 15/12, 2021 at 19:40 Comment(3)
Could you also post how to do the opposite? To serialize string property as json object.Sportscast
you didn't understand the question, how to deserialize Stub class itself from string?Dramaturgy
this is more elegant and idiomatic than the accepted answerSuitcase

© 2022 - 2024 — McMap. All rights reserved.