kotlin - 如何在 Ktor 中接收 JSON 对象?
问题描述
我定义了数据类,配置了 gson 并创建了 rout 来处理 post 请求,如下所示:
data class PurchaseOrder(val buyer: String, val seller: String,
val poNumber: String, val date: String,
val vendorReference: String)
install(ContentNegotiation) {
gson {
setDateFormat(DateFormat.LONG)
setPrettyPrinting()
}
post("/purchaseOrder"){
val po = call.receive<PurchaseOrder>()
println("purchase order: ${po.toString()}")
call.respondText("post received", contentType =
ContentType.Text.Plain)
以下 JSON 在 POST 请求中发送
{
"PurchaseOrder" : {
"buyer": "buyer a",
"seller": "seller A",
"poNumber": "PO1234",
"date": "27-Jun-2018",
"vendorReference": "Ref1234"
}
}
输出显示所有空值。
purchase order: PurchaseOrder(buyer=null, seller=null, poNumber=null,
date=null, vendorReference=null)
从 call.request.receiveChannel() 读取数据确实显示正确的 JSON。所以我正在接收数据,但 call.receive() 似乎没有产生预期的结果。
手动获取 JSON 并尝试按如下方式创建 PurchaseOrder 但没有运气:
val channel = call.request.receiveChannel()
val ba = ByteArray(channel.availableForRead)
channel.readFully(ba)
val s = ba.toString(Charset.defaultCharset())
println(s) // prints JSON
val gson = Gson()
val po = gson.fromJson(s, PurchaseOrder::class.java)
println("buyer = ${po.buyer}" //prints null
解决方案
问题是您已将 json 包装在"PurchaseOrder"
.
如果您改为发布此内容:
{
"buyer": "buyer a",
"seller": "seller A",
"poNumber": "PO1234",
"date": "27-Jun-2018",
"vendorReference": "Ref1234"
}
它正确接收以下内容:
purchase order: PurchaseOrder(buyer=buyer a, seller=seller A, poNumber=PO1234, date=27-Jun-2018, vendorReference=Ref1234)
如果你想保持 json 请求不变,你有 2 个选项。
一个自定义的 gson 序列化器,它期望请求被包装在
PurchaseOrder
.像这样的包装类:
class PurchaseOrderWrapper(
val purchaseOrder: PurchaseOrder
)
然后你可以收到这样的:
call.receive<PurchaseOrderWrapper>().purchaseOrder
推荐阅读
- jquery - 如何在使用 Angular 6 模糊之前调用按钮单击事件
- blockchain - 流启动期间的 net.corda.serialization.internal.amqp.IllegalCustomSerializerException
- python - Python Sockets 将大于 127 的整数值作为单个字节发送
- django - DJango Driver 13 for SQL Server][SQL Server]无效的对象名称'django_session'
- c# - 在 StackPanel 中对齐元素
- android - 如何在谷歌地图中一一删除标记?
- azure - 当定义的函数“routePrefix”不同于“api”时,Azure 函数活动在数据工厂中失败
- excel - 如何在 VBA 中对范围进行排序?
- database - 如何在两列数据类型都是时间戳的 Oracle 中找到两列之间的分钟差异?
- asp.net-core - 从日期时间输入中删除时间