user1173706
user1173706

Reputation: 2752

Deserializing a json object property to a String using kotlinx.serialization

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
)

Upvotes: 13

Views: 18303

Answers (2)

FFFF0H
FFFF0H

Reputation: 683

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.

Upvotes: 14

user1173706
user1173706

Reputation: 2752

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()
)

Upvotes: 20

Related Questions