Как установить тело HttpServletResponse с помощью клиента Ktor - PullRequest
0 голосов
/ 28 июня 2019

У меня есть контроллер весенней загрузки

@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 для httpServletResponse.writer, который нарушает асинхронные качества клиента ktor.Что я делаю не так?Как мне это решить?

Ответы [ 2 ]

0 голосов
/ 29 июня 2019

Мне действительно удалось решить эту проблему, используя CompletableFuture<ResponseEntity<ByteArray>> в качестве типа возврата и настройки тела ответа следующим образом: ResponseEntity.ok().body(response.content.toByteArray()) Это также удалило Inappropriate blocking method call предупреждения.

0 голосов
/ 29 июня 2019

Итак, я думаю, что 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()
}
...