InputStream закрыт в пружинном контроллере - PullRequest
0 голосов
/ 24 сентября 2019

Используя пружинный контроллер, конечная точка возвращает файл в ответе тела.Я хочу быть уверенным, что не получаю утечку ресурсов, используя "try with resources", но таким образом в почтальоне я получаю ошибку:

"error": "Internal Server Error", "message":" Поток закрыт ",

фрагмент кода в контроллере Spring:

InputStreamResource result;
ResponseEntity<Resource> response;
try(FileInputStream ios = new FileInputStream(file)){
    result = new InputStreamResource(ios);
    response = ResponseEntity.ok()
        .headers(/*some headers here*/)
        .contentLength(file.length())
        .contentType(/*some media type here*/)
        .body(result);
    logger.info("successfully created");
    return response;
} catch (IOException e) {
        //some code here..
}

Интересно, что в логах я получаю сообщение об успехе, но в почтальоне или в браузере (этоэто запрос GET) Я получил ошибку.

И это сработало бы, если бы не использовать "try-with-resource", но я боюсь утечек ресурсов таким образом.

1 Ответ

1 голос
/ 25 сентября 2019

Поскольку попытка с ресурсом вызовет close() до return, возникнет ошибка "Поток закрыт".
Простой способ - непосредственно поместить экземпляр InputStreamResource в .body(), и большинство примеров в Интернете также делают это.Однако я не уверен, будет ли ресурс закрыт правильно, чтобы предотвратить утечку ресурсов приложением.

response = ResponseEntity.ok()
    .contentLength(file.length())
    .body(new InputStreamResource(new FileInputStream(file)));
return response;

Другой способ, если вы хотите передать ответ, вы можете использовать StreamingResponseBody.

Интерфейс StreamingResponseBody (цитируется с веб-сайта Spring)

Это функциональный интерфейс, и поэтому его можно использовать в качестве цели назначения для лямбда-выражения или ссылки на метод.

Пример кода:

StreamingResponseBody responseBody = outputStream -> {
    Files.copy(file.toPath(), outputStream);
};

response.ok()
    .contentLength(file.length())
    .body(responseBody);
return response;
...