InputStream 在 spring 控制器中关闭
InputStream is closed in spring controller
在正文响应中使用 spring 控制器、端点 returns 文件。
我想确保不要使用 "try with resources" 来获取资源泄漏,但是在邮递员中我会得到一个错误:
"error": "Internal Server Error",
"message": "Stream Closed",
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",它会起作用,但我担心那样会导致资源泄漏。
因为 try with resource 将在 return
之前调用 close()
,将发生“Stream Closed”错误。
一个简单的方法是直接把InputStreamResource
的实例放在.body()
中,网上的例子大多也是这样做的。但是我不确定是否会正确关闭资源以防止应用程序资源泄漏。
response = ResponseEntity.ok()
.contentLength(file.length())
.body(new InputStreamResource(new FileInputStream(file)));
return response;
另一种方式,如果你想流式传输响应,你可以使用StreamingResponseBody
。
Interface StreamingResponseBody (quoted from Spring website)
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
示例代码:
StreamingResponseBody responseBody = outputStream -> {
Files.copy(file.toPath(), outputStream);
};
response.ok()
.contentLength(file.length())
.body(responseBody);
return response;
在正文响应中使用 spring 控制器、端点 returns 文件。 我想确保不要使用 "try with resources" 来获取资源泄漏,但是在邮递员中我会得到一个错误:
"error": "Internal Server Error", "message": "Stream Closed",
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",它会起作用,但我担心那样会导致资源泄漏。
因为 try with resource 将在 return
之前调用 close()
,将发生“Stream Closed”错误。
一个简单的方法是直接把InputStreamResource
的实例放在.body()
中,网上的例子大多也是这样做的。但是我不确定是否会正确关闭资源以防止应用程序资源泄漏。
response = ResponseEntity.ok()
.contentLength(file.length())
.body(new InputStreamResource(new FileInputStream(file)));
return response;
另一种方式,如果你想流式传输响应,你可以使用StreamingResponseBody
。
Interface StreamingResponseBody (quoted from Spring website)
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
示例代码:
StreamingResponseBody responseBody = outputStream -> {
Files.copy(file.toPath(), outputStream);
};
response.ok()
.contentLength(file.length())
.body(responseBody);
return response;