Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MuyembeII/c003d4b48f0ac602b814b7616c2816c0 to your computer and use it in GitHub Desktop.
Save MuyembeII/c003d4b48f0ac602b814b7616c2816c0 to your computer and use it in GitHub Desktop.
Kotlin data class deserializer
@JsonDeserialize(using = KotlinDataDeserializer::class)
data class Foo(val x: String, val y: String, val z: Int)
class KotlinDataDeserializer : StdDeserializer<Foo>(Foo::class.java) {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Foo {
return p.readValueAs(Foo::class.java)
}
override fun deserialize(p: JsonParser, ctxt: DeserializationContext, intoValue: Foo): Foo {
val copy = intoValue::copy
val tree = p.readValueAsTree<ObjectNode>()
val args = mutableMapOf<KParameter, Any?>()
for (param : KParameter in copy.parameters) {
if (!tree.has(param.name)) {
if (param.isOptional) {
continue
}
throw RuntimeException("Missing required field: ${param.name}")
}
val node = tree.get(param.name)
if (node == null && !param.type.isMarkedNullable) {
throw RuntimeException("Got null value for non-nullable field: ${param.name}")
}
val javaType = ctxt.typeFactory.constructType(param.type.javaType)
val reader = jacksonObjectMapper().readerFor(javaType)
val obj = reader.readValue<Any?>(node)
println(param.type)
args[param] = obj
}
val result = copy.callBy(args)
return result
}
}
fun main(args: Array<String>) {
val mapper = ObjectMapper().registerKotlinModule()
val obj = Foo("foo", "bar", 3)
val deser = mapper.readerForUpdating(obj).readValue<Foo>("""{"x": "baz", "z": 5}""")
println("obj=%s, deserialized=%s, deser id=%s obj id=%s".format(obj, deser, System.identityHashCode(deser), System.identityHashCode(obj)))
println(obj === deser)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment