我正在开发一个Spring Boot应用程序,该应用程序应该允许用户通过指定的应用程序REST接口从Amazon S3间接下载文件。为此,我有一个REST-Controller,它向用户返回InputStreamResource,如下所示:
@GetMapping(path = "/download/{fileId}")
public ResponseEntity<InputStreamResource> downloadFileById(@PathVariable("fileId") Integer fileId) {
Optional<LocalizedFile> fileForDownload = fileService.getConcreteFileForDownload(fileId);
if (!fileForDownload.isPresent()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileForDownload.get().getFilename())
.body(new InputStreamResource(fileService.download(fileForDownload.get())));
}
文件服务中的下载方法如下所示:
@Override
public InputStream download(LocalizedFile file) {
S3Object obj = s3client.getObject(bucketName, file.getFilename());
return obj.getObjectContent();
}
我在这里担心的是,无法在控制器中显式关闭来自Amazon SDK的输入流。以下是warning in AWS documentation of the getObjectContent() method,使我对上述方法的成功感到怀疑:
如果检索到S3Object,则应以以下方式关闭此输入流:
尽快,因为对象内容未缓冲在其中
直接从Amazon S3进行存储和流传输。此外,无法关闭
此流可能导致请求池被阻塞。
因此我的问题是:
在控制器中返回
ResponseEntity<InputStreamResource>
是否安全?成功下载后,是否会自动关闭S3Object.getObjectContent()
中的InputStream?到目前为止,我的方法已经成功运行,但是我不确定将来可能会发生什么。 最佳答案
经过一些研究,我发现an answer,应该适用于我的问题。
Tl; dr版本:给定输入流的Spring MVC handles closing,这就是为什么我上面描述的方法应该安全的原因。