Я создаю веб-сервис, который должен предлагать файл для загрузки. Сам файл запрашивается у другого внешнего веб-сервиса под капотом. Так что мой веб-сервис больше похож на прокси.
Поскольку файлы могут быть большими, вместо того, чтобы получать их полностью, я записываю файл напрямую как поток.
Проблема: внешний веб-сервис предоставляет 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 в случае прямого стриминга?




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;
};
}