如何使用ktor客户端设置HttpServletResponse的正文

时间:2019-06-28 18:50:59

标签: kotlin ktor

我有Spring Boot控制器

@PostMapping(path = ["/download"])
fun getFile(@RequestBody myObjectRq: myObjectRq, httpServletResponse: HttpServletResponse): CompletableFuture<HttpServletResponse> {
    return GlobalScope.async {
       val response = webService.getFile(myObjectRq)
       response?.let {
           httpServletResponse.setHeader("Content-Type", response.headers.get("Content-Type"))
           httpServletResponse.setHeader("Content-Disposition", response.headers.get("Content-Disposition"))
           httpServletResponse.writer.write(String(response.content.toByteArray()))
           httpServletResponse.writer.flush()
           httpServletResponse.status = response.status.value
       }
       httpServletResponse
   }.asCompletableFuture()
}

我在其中使用服务,该服务又使用ktor客户端将发布请求发送到外部服务器,该服务器应响应发送csv文件。 csv文件的内容取决于我在myObjectRq中发送的值。

服务:

suspend fun getFile(myObjectRq: myObjectRq): HttpResponse {
    val response = ktorClient.post<HttpResponse> {
        accept(ContentType.Application.OctetStream)
        url(externalWebServerUrl)
        body = myObjectRq
        contentType(ContentType.Application.Json)
    }
    log.info(String(response.content.toByteArray()))
    response
}

正确设置了响应头,该方法中的log.info(String(response.content.toByteArray()))也会打印出接收文件的内容,但是我不能将其设置为HttpServletResponse的主体。我不断收到org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

我也得到Inappropriate blocking method call的{​​{1}},这破坏了ktor客户端的异步质量。 我做错了什么?我该怎么解决?

2 个答案:

答案 0 :(得分:0)

所以,我认为SpringBoot与您的返回类型混淆了。它正在尝试找到一种将返回CompletableFuture<HttpServletResponse>序列化为HTTP响应正文但失败的方法。我相信您可以通过如下更改实现来达到相同的结果:

@PostMapping(path = ["/download"])
fun getFile(@RequestBody myObjectRq: myObjectRq, httpServletResponse: HttpServletResponse): CompletableFuture<Void> {
    return GlobalScope.async {
       val response = webService.getFile(myObjectRq)
       response?.let {
           httpServletResponse.setHeader("Content-Type", response.headers.get("Content-Type"))
           httpServletResponse.setHeader("Content-Disposition", response.headers.get("Content-Disposition"))
           httpServletResponse.writer.write(String(response.content.toByteArray()))
           httpServletResponse.writer.flush()
           httpServletResponse.status = response.status.value
       }
       null
   }.asCompletableFuture()
}

答案 1 :(得分:0)

我实际上设法使用CompletableFuture<ResponseEntity<ByteArray>>作为返回类型并通过以下方式设置响应主体来解决此问题:  ResponseEntity.ok().body(response.content.toByteArray()) 这也删除了Inappropriate blocking method call警告。