在 Spring Boot 中将 AWS S3 文件作为流下载

Abh*_*ash 3 java amazon-s3 java-8 spring-boot

我想公开一个 API,以将 S3 存储桶文件内容作为流下载给其使用者。API URL 就像 /downloadfile/** 这是 GET 请求。

  1. 现在我的返回类型应该是什么我尝试使用 accept header= application/octet-stream 但它不起作用。
  2. 我不想将文件的内容写入任何文件并发送。它应该作为一个流返回,就是这样。

这是我写到现在的控制器伪代码,它一直给我 406 错误。

 @GetMapping(value = "/downloadfile/**", produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
    public ResponseEntity<Object> downloadFile(HttpServletRequest request) {
       //reads the content from S3 bucket and returns a S3ObjectInputStream
       S3ObjectInputStream object = null;
       object = publishAmazonS3.getObject("12345bucket", "/logs/file1.log").getObjectContent();
       return object
    }
Run Code Online (Sandbox Code Playgroud)

这里有什么关于这样做的建议以及我做错了什么?

Abh*_*ash 7

我能够通过使用StreamingResponseBodySpring 中的类将文件作为流下载。

这是我使用的代码:

    @GetMapping(value = "/downloadfile/**", produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
    public ResponseEntity<S3ObjectInputStream> downloadFile(HttpServletRequest request) {
       //reads the content from S3 bucket and returns a S3ObjectInputStream
       S3Object object = publishAmazonS3.getObject("12345bucket", "/logs/file1.log");
       S3ObjectInputStream finalObject = object.getObjectContent();

        final StreamingResponseBody body = outputStream -> {
            int numberOfBytesToWrite = 0;
            byte[] data = new byte[1024];
            while ((numberOfBytesToWrite = finalObject.read(data, 0, data.length)) != -1) {
                System.out.println("Writing some bytes..");
                outputStream.write(data, 0, numberOfBytesToWrite);
            }
            finalObject.close();
        };
        return new ResponseEntity<>(body, HttpStatus.OK);
    }
Run Code Online (Sandbox Code Playgroud)

测试流媒体是否正确完成的方法是下载一个大约 400mb 的文件。通过传入 vm 选项将 Xmx 减少到 256mb。现在,比较使用和不使用 using 的下载功能StreamingResponseBody,您将OutofMemoryError在使用传统的 OutputStreams 编写内容时得到

  • 当我尝试这样做时,我得到以下信息:错误:不兼容的类型:无法推断 ResponseEntity&lt;&gt; 的类型参数返回新的 ResponseEntity&lt;&gt;(streamingResponseBody, HttpStatus.OK); ^ 原因:推理变量 T 具有不兼容的边界等式约束:InputStream 下限:StreamingResponseBody (2认同)