我正在开发一个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,这就是为什么我上面描述的方法应该安全的原因。

10-06 08:46