我有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客户端的异步质量。
我做错了什么?我该怎么解决?
答案 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
警告。