【问题标题】:Receive Map in ktor server using kotlinx.serialization使用 kotlinx.serialization 在 ktor 服务器中接收 Map
【发布时间】:2023-03-28 07:29:01
【问题描述】:

我有一个运行 kotlinx.serialization 的 Ktor 服务器,因为它是 json (de)serializer 我向我的 Ktor 发送了这样一条消息:

{
  "Brick(partNumber=004229, partName=Sticker Sheet for Set 295-1, dataSource=Rebrickable, brickImage=null, categoryID=58)": 5
}

这是一对 Int 和这个类:

import kotlinx.serialization.Serializable

@Serializable
data class Brick(
    val partNumber: String,
    val partName: String,
    val dataSource: String,
    val brickImage: String?,
    val categoryID: Int?
)

但我得到了这个错误

kotlinx.serialization.json.JsonDecodingException: Invalid JSON at 0: Expected '[, kind: MAP'
    at kotlinx.serialization.json.internal.JsonReader.fail(JsonReader.kt:293)

这对我来说意味着 kotlinx.serialization 期望 map 类有不同的语法。这对我来说很奇怪。当我将类型更改为 List> 时,它会引发相同的异常,但使用 LIST 而不是 MAP。 编辑:经过进一步检查,它期望在行首使用 [ 而不是 { 。 我的(部分)应用程序实现

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)
                }
            }
        }
    }
}

发送类的android改造函数(使用GSON):

    @POST("/user/brick")
    suspend fun setBricksAmounts(
        @Query("userName")
        userName: String,
        @Body
        brickAmounts: Map<Brick, Int>
    )

【问题讨论】:

    标签: json dictionary kotlin ktor kotlinx.serialization


    【解决方案1】:

    我认为使用类作为键在 kotlinx 序列化中不起作用 看起来该类只是序列化为一个字符串以将其用作键

    相反,您可以将其接收为Map&lt;String, Int&gt; 然后运行

    bricks.mapKeys { (jsonString, number) ->
       Json(JsonConfiguration.Stable).parse(Brick.Serializer, jsonString)
    }
    

    如果需要,也可以使用等效的杰克逊代码

    【讨论】:

      猜你喜欢
      • 2018-03-05
      • 2019-03-10
      • 2018-09-28
      • 2020-11-13
      • 2021-03-09
      • 1970-01-01
      • 2022-07-09
      • 1970-01-01
      • 2021-06-19
      相关资源
      最近更新 更多