Как асинхронно записать HttpHeader в ClientHttpResponse?

Я создаю веб-сервис, который должен предлагать файл для загрузки. Сам файл запрашивается у другого внешнего веб-сервиса под капотом. Так что мой веб-сервис больше похож на прокси.

Поскольку файлы могут быть большими, вместо того, чтобы получать их полностью, я записываю файл напрямую как поток.

Проблема: внешний веб-сервис предоставляет HttpHeaders, например Content-Length, Content-Type, Content-Disposition, которые я хотел бы пересылать через свой прокси-сервлет. Но поскольку я транслирую только ресурс, на этом этапе заголовки не известны.

@GetMapping(value = "/files/{filename}")
public ResponseEntity<StreamingResponseBody> getDocument(@PathVariable String filename) {
    StreamingResponseBody responseBody = outputStream -> {
        HttpHeaders headers = download(outputStream, filename);
        outputStream.close();
        System.out.println(headers); //always 'null' at this stage
    };

    return ResponseEntity.ok(responseBody); //TODO how to get the header in?
}

private HttpHeaders download(OutputStream outputStream, String filename) {
        ResponseExtractor<HttpHeaders> responseExtractor = clientHttpResponse -> {
            //directly stream the remote file into the servlet response
            InputStream inputStream = clientHttpResponse.getBody();
            StreamUtils.copy(inputStream, outputStream);

            HttpHeaders headers = clientHttpResponse.getHeaders();
            System.out.println(headers); //external headers are shown correctly

            //is it possible to write the headers into the servlet response at this stage??
            return headers;
        };

        return restTemplate.execute("https://www.external-webservice.com?file = " + filename, HttpMethod.GET, null, responseExtractor);
    }

Как видите: заголовки внешнего файла доступны на этапе ResponseExtractor. Но когда я возвращаю эти заголовки на сцену StreamingResponseBody, заголовки - это null.

Вопрос: возможно ли вообще получить удаленные HttpHeaders в случае прямого стриминга?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
351
1

Ответы 1

HttpHeaders необходимо записать непосредственно в HttpServletResponse перед записью основного потока:

private HttpHeaders download(OutputStream outputStream, HttpServletResponse response, String filename) {
    ResponseExtractor<Void> responseExtractor = clientHttpResponse -> {
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, clientHttpResponse.getHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION));

        InputStream inputStream = clientHttpResponse.getBody();
        StreamUtils.copy(inputStream, outputStream);
        return null;
    };
}

Другие вопросы по теме