如何在 Ktor 中获取 call.response 的 http 正文?
Posted
技术标签:
【中文标题】如何在 Ktor 中获取 call.response 的 http 正文?【英文标题】:How to get http body of call.reponse in Ktor? 【发布时间】:2022-01-13 06:28:05 【问题描述】:我用 Ktor 构建了一个 Web 服务器,并且想要缓存 API 方法的结果。但我不知道如何从 call.response 获取响应正文。如下代码
fun Application.module()
// before method was called
intercept(ApplicationCallPipeline.Features)
val cache = redis.get("cache")
if(cache)
call.respond(cache)
return @intercept finish()
// after method was called
intercept(ApplicationCallPipeline.Fallback)
// TODO, how to get call.response.body
redis.set("cache", call.response.body)
如果我无法获取响应正文,还有其他解决方案可以在 Ktor 中缓存 API 方法的结果吗?
【问题讨论】:
你的call
在哪里定义
@GuanHongHuang call
是一个lambda参数
【参考方案1】:
在拦截器中,对于 ApplicationCallPipeline.Features
阶段,您可以在 ApplicationSendPipeline.Engine
之前添加一个阶段并拦截它以检索响应正文 (content
):
val phase = PipelinePhase("phase")
call.response.pipeline.insertPhaseBefore(ApplicationSendPipeline.Engine, phase)
call.response.pipeline.intercept(phase) response ->
val content: ByteReadChannel = when (response)
is OutgoingContent.ByteArrayContent -> ByteReadChannel(response.bytes())
is OutgoingContent.NoContent -> ByteReadChannel.Empty
is OutgoingContent.ReadChannelContent -> response.readFrom()
is OutgoingContent.WriteChannelContent -> GlobalScope.writer(coroutineContext, autoFlush = true)
response.writeTo(channel)
.channel
else -> error("")
// Do something with content
【讨论】:
对不起,我复制你的代码并粘贴到intercept(ApplicationCallPipeline.Fallback)
的回调函数中,但是拦截器没有执行。我是不是误会了什么?
ApplicationCallPipeline.Fallback
阶段的拦截器仅在未处理调用时执行。
我尝试了很多次,但每次都调用Fallback
,即使调用已处理。而且,阶段的拦截器没有被执行。完整代码:replit.com/@gtfhxy/ktor-pipeline-sample#src/main/kotlin/com/…
我看不到您的代码。你能通过 Github gist 分享一下吗?
gist.github.com/gtfhxy/35458fb30f9cd1e8b964440819705d75以上是关于如何在 Ktor 中获取 call.response 的 http 正文?的主要内容,如果未能解决你的问题,请参考以下文章