如何在 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 正文?的主要内容,如果未能解决你的问题,请参考以下文章

在 Ktor 应用程序模块而不是 Main 中获取命令行参数?

如何在 Ktor 中调用内部端点?

获取 Ktor http 请求的内容

如何使用 ktor 获取客户端 IP

如何以编程方式在 Ktor 中提供 https 请求

如何在 Ktor 中注册一个 servlet?