【发布时间】:2020-04-22 05:37:27
【问题描述】:
我正在开发一个 Spring Boot 应用程序,它应该允许用户通过指定的应用程序 REST 接口从 Amazon S3 间接下载文件。为此,我有一个 REST 控制器,它向用户返回一个 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会在下载成功后自动关闭吗?到目前为止,我的方法很成功,但我不确定未来可能产生的后果。
【问题讨论】:
标签: java spring-boot amazon-s3 aws-java-sdk