使用弹簧控制器,端点在主体响应中返回文件。我想确保不要使用“尝试资源”来获取资源泄漏,但是在邮递员中,我会收到一个错误:
“错误”:“内部服务器错误”,“ 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”,也可以,但是我担心那样会导致资源泄漏。
因为尝试资源将在close()
之前调用return
,将发生“流关闭”错误。一种简单的方法是将InputStreamResource
的实例直接放在.body()
中,Web上的大多数示例也都这样做。但是,我不确定是否会正确关闭资源以防止应用程序发生资源泄漏。
response = ResponseEntity.ok()
.contentLength(file.length())
.body(new InputStreamResource(new FileInputStream(file)));
return response;
另一种方法,如果要流式传输响应,则可以使用StreamingResponseBody
。
Interface StreamingResponseBody(从Spring网站引用)
这是一个功能接口,因此可以用作lambda表达式或方法引用的分配目标。
示例代码:
StreamingResponseBody responseBody = outputStream -> {
Files.copy(file.toPath(), outputStream);
};
response.ok()
.contentLength(file.length())
.body(responseBody);
return response;