asavio
12/29/2022, 10:35 AMMap<String, Any?>
to a data class object using Kotlinx Serialisation.
The Data Classes:
import kotlinx.serialization.Serializable
@Serializable
data class Person(
val uuid: String,
val age: Int,
val name: String,
val address: Address
)
@Serializable
data class Address(
val street: String,
val city: String,
val zip: Int
)
This is the function I use to convert to data class.
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToJsonElement
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.Json
internal inline fun <reified T : Any> Map<String, Any?>.toPojo(): T {
val JSON = Json { encodeDefaults = true }
val jsonObject = JSON.encodeToJsonElement(this).jsonObject
return JSON.decodeFromJsonElement<T>(jsonObject)
}
Here’s the function call:
val map = mapOf(
"uuid" to "agsdjhdg",
"age" to 26,
"name" to "Aseem",
"address" to mapOf(
"city" to "Chennai",
"street" to "street1"
)
)
println(map.toPojo<Person>())
I get the following error:
Exception in thread "main" kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
at kotlinx.serialization.internal.PlatformKt.platformSpecificSerializerNotRegistered(Platform.kt:29)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:60)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source)
at kotlinx.serialization.SerializersKt__SerializersKt.serializersForParameters(Serializers.kt:117)
at kotlinx.serialization.SerializersKt.serializersForParameters(Unknown Source)
at kotlinx.serialization.SerializersKt__SerializersKt.serializerByKTypeImpl$SerializersKt__SerializersKt(Serializers.kt:99)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:59)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source)
at MainKt.main(Main.kt:98)
How does one convert a Map<String, Any?> to data class? Thanks in advance!CLOVIS
12/29/2022, 11:02 AMAny?
because it's a security risk (it can be used by an attacker to execute arbitrary code on your server).CLOVIS
12/29/2022, 11:05 AMCLOVIS
12/29/2022, 11:12 AMdata class Person(val data: Map<String, Any?>) {
val uuid: String by data
val age: Int by data
val name: String by data
val address: Address by data
}
(of course this has the usual downsides of using a map as storage, including a bit slower access due to hashes and casts everywhere)asavio
12/29/2022, 11:14 AMCLOVIS
12/29/2022, 11:15 AMPair
. I don't know if they provide conversions for Map
by defaultCLOVIS
12/29/2022, 11:16 AMAdam S
12/29/2022, 11:19 AMYou cannot deserializeI thought you could, so long as you registered `Any` as polymorphic? (although I don’t think that helps in this instance)Any?
CLOVIS
12/29/2022, 11:21 AMCLOVIS
12/29/2022, 11:22 AMasavio
12/29/2022, 11:25 AMI’m curious why you’re using maps at all, though, where do they come from?It’s for dynamodb reads and writes. I don’t want to use the expensive bean based reads & writes. Let’s say
Any
will only be one of the following types - String, Int, Long, Double, and Boolean. Would it be possible by tweaking the original code?CLOVIS
12/29/2022, 11:25 AMAdam S
12/29/2022, 11:26 AMjsonObjectBuilder {}
CLOVIS
12/29/2022, 11:28 AMAny
can be Map<String, Any?>
(address.city
)CLOVIS
12/29/2022, 11:29 AMJsonObject
instead of Map
? It already has all the types you care aboutCLOVIS
12/29/2022, 11:29 AMCLOVIS
12/29/2022, 11:30 AMMap<String, Any?> <=> JsonObject
conversion functionsasavio
12/29/2022, 11:31 AMCLOVIS
12/29/2022, 11:33 AMAdam S
12/29/2022, 11:36 AMCLOVIS
12/29/2022, 11:39 AMasavio
12/29/2022, 11:39 AMCLOVIS
12/29/2022, 11:44 AMasavio
12/29/2022, 11:45 AM