Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How parse raw json list of data posted in ktor

Tags:

kotlin

ktor

I'm posting json array of objects. I'm trying to parse it in code like this

val objs = call.receive<List<MyClass>>() // this work fine
val name objs[0].name // this throw exception LinkedTreeMap cannot be cast to MyClass

In above code second line throws exception com.google.gson.internal.LinkedTreeMap cannot be cast to MyClass

If i post simple object and parse it in ktor with call.receive<MyClass>() then it will work fine. So issue is only when parsing list of objects.

like image 786
William Avatar asked Apr 23 '19 13:04

William


People also ask

How do I use KTOR?

To use Ktor, you first need to add the Ktor core dependency. Then add other dependencies such as the HTTP client engine dependency for processing and performing network requests. Since we are building on Android, we are adding Android specific functionality. For iOS, we would use an iOS dependency.

What is a raw JSON file?

Raw JSON text is the format Minecraft uses to send and display rich text to players. It can also be sent by players themselves using commands and data packs. Raw JSON text is written in JSON, a human-readable data format.


2 Answers

Using your code with Array instead of List worked for me using ktor v1.2.3:

val objs = call.receive<Array<MyClass>>() 
val name = objs[0].name


Side Note:

I later changed my data class to this format to help with mapping from database rows to a data class (i.e. to use BeanPropertyRowMapper). I don't remember this having an effect on de/serialization, but if the first part still isn't working for you, you may try this...

data class MyClass(
    var id: Int? = null,
    var name: String? = null,
    var description: String? = null,
)

Reference: Kotlin data class optional variable

like image 144
cs_pupil Avatar answered Oct 13 '22 00:10

cs_pupil


You can do like this

val json = call.receive<String>()
val objs = Gson().fromJson(json, Array<MyClass>::class.java)
objs[0].name

Updated

You can also create extention function for that like this

suspend inline fun <reified T> ApplicationCall.safeReceive(): T {
    val json = this.receiveOrNull<String>()
    return Gson().fromJson(json, T::class.java)
}

then use it like this

val objs = call.safeReceive<Array<MyClass>>()
objs[0].name
like image 43
Sabeeh Avatar answered Oct 12 '22 23:10

Sabeeh