Ktor 从与 ContentNegotiation 一起使用 receive() 的端点返回 415
Posted
技术标签:
【中文标题】Ktor 从与 ContentNegotiation 一起使用 receive() 的端点返回 415【英文标题】:Ktor returns 415 from endpoints where receive() is used with ContentNegotiation 【发布时间】:2020-11-09 20:39:51 【问题描述】:我有带有@Searializable 注释的参数类:
@Serializable
data class ShowPostURL(
val date: String,
val titleSlug: String,
override val redirectTo: String? = null
)
无论我做什么call.receive()
都不起作用。我收到 HTTP 415 错误,而 Ktor 没有记录任何内容。我也添加了序列化支持:
install(ContentNegotiation)
json()
我该如何解决这个问题?这就是我尝试使用它的方式:
accept(ContentType.Any)
get("/foo/date/titleSlug")
val input = call.receive(ShowPostURL::class)
call.respondText("foo")
如果我进行跟踪,我可以看到我的路由匹配,但它无法接收参数。当我从这样的 url 参数反序列化时,这个 json()
设置是否应该工作?
【问题讨论】:
【参考方案1】:首先,ContentNegotiation
功能仅适用于从 POST、PUT 和 PATCH 请求的负载接收自定义对象:
POST、PUT 和 PATCH 请求具有关联的请求正文(有效负载)。该有效载荷通常是经过编码的。 为了从有效负载接收自定义对象,您必须使用ContentNegotiation 功能。例如,这对于在 REST API 中接收和发送 JSON 有效负载很有用。 接收时,将使用请求的
Content-Type
来确定将使用哪个ContentConverter
来处理该请求
其次,有三个开箱即用的ContentConverter
可用:
GsonConverter、JacksonConverter 和 SerializationConverter。
这些转换器中的每一个都有自己的配置功能:分别为gson
、jackson
和serialization
。你使用json
的配置函数,很可能不适合ContentNegotiation
的配置。
要解决您的问题,您可以通过使用 call.parameters
引用 URL 参数并手动创建 ShowPostURL
对象来访问它们。然后根据需要使用kotlinx.serialization
框架对其进行序列化。
另外,您可以编写自己的ContentConverter 来实现receiving typed objects 的自定义逻辑。
【讨论】:
我使用json
因为官方文档是这么说的。我在 Kotlin Slack 上讨论过这个问题,一个 JetBrains 的人说它还不支持这个功能,你根本不能反序列化来自 url 的对象。以上是关于Ktor 从与 ContentNegotiation 一起使用 receive() 的端点返回 415的主要内容,如果未能解决你的问题,请参考以下文章
Ktor挖坑日记还在用Retrofit网络请求吗?试试Ktor吧
Ktor挖坑日记还在用Retrofit网络请求吗?试试Ktor吧
“未找到转换:类 io.ktor.utils.io.ByteChannelNative”错误使用 Ktor
Ktor Websocket 功能与 ktor 中的 ContentNeogation 功能 (JSON / GSON)