Reputation: 1054
I have a Ktor server running with kotlinx.serialization as it's json (de)serializer I send my Ktor a message like this one:
{
"Brick(partNumber=004229, partName=Sticker Sheet for Set 295-1, dataSource=Rebrickable, brickImage=null, categoryID=58)": 5
}
which is a pair of an Int and this class:
import kotlinx.serialization.Serializable
@Serializable
data class Brick(
val partNumber: String,
val partName: String,
val dataSource: String,
val brickImage: String?,
val categoryID: Int?
)
But I get this error
kotlinx.serialization.json.JsonDecodingException: Invalid JSON at 0: Expected '[, kind: MAP'
at kotlinx.serialization.json.internal.JsonReader.fail(JsonReader.kt:293)
Which to me means that kotlinx.serialization expects a different syntax for the map class. Which is odd to me. When I change the type into List> it throws the same exception but with LIST instead of MAP. EDIT: Upon further inspection, it expects a [ instead of a { at the start of the line. My (partial) application implementation
fun Application.module(testing: Boolean = false) {
install(ContentNegotiation) { serialization() }
routing {
route("user") {
route("brick") {
post {
call.request.queryParameters["userName"]
?.let { userRepository.login(it) } // Someone else is still working login nvm this
?.let { user ->
val bricks = call.receive<Map<Brick, Int>>() // This throws an error
userRepository.addBricks(user, bricks)
call.respond(HttpStatusCode.OK)
}
?: call.respond(HttpStatusCode.Unauthorized)
}
}
}
}
}
The android retrofit function that sends the class (using GSON):
@POST("/user/brick")
suspend fun setBricksAmounts(
@Query("userName")
userName: String,
@Body
brickAmounts: Map<Brick, Int>
)
Upvotes: 1
Views: 2041
Reputation: 518
I think using a class as a key does not work in kotlinx serialization and it looks like that class is just serialized into a string to use it as key
Instead you can receive it as Map<String, Int>
and afterwards run
bricks.mapKeys { (jsonString, number) ->
Json(JsonConfiguration.Stable).parse(Brick.Serializer, jsonString)
}
or the equivalent jackson code if you want
Upvotes: 2