Reputation: 2752
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
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
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