【问题标题】:S3 download pdf - REST APIS3 下载 pdf - REST API
【发布时间】:2018-04-26 13:00:23
【问题描述】:

我正在尝试使用 Spring Boot Rest API 为我存储在 S3 上的 PDF 之一提供服务。

以下是我的代码:

        byte[] targetArray = null;

        InputStream is = null;

        S3Object object = s3Client
                    .getObject(new GetObjectRequest("S3_BUCKET_NAME", "prefixUrl"));

        InputStream objectData = object.getObjectContent();

    BufferedReader reader = new BufferedReader(new InputStreamReader(objectData));

    char[] charArray = new char[8 * 1024];
    StringBuilder builder = new StringBuilder();
    int numCharsRead;
    while ((numCharsRead = reader.read(charArray, 0, charArray.length)) != -1) {

        builder.append(charArray, 0, numCharsRead);
    }
    reader.close();

    objectData.close();
    object.close();
    targetArray = builder.toString().getBytes();

    is = new ByteArrayInputStream(targetArray);


    return ResponseEntity.ok().contentLength(targetArray.length).contentType(MediaType.APPLICATION_PDF)
                    .cacheControl(CacheControl.noCache()).header("Content-Disposition", "attachment; filename=" + "testing.pdf")
                    .body(new InputStreamResource(is));

当我使用邮递员访问我的 API 时,我可以下载 PDF 文件,但问题是它完全是空白的。可能是什么问题?

S3 流式传输数据,不保留缓冲区,数据为二进制 (PDF),因此如何使用 Rest API 将此类数据提供给服务器。

如何解决?

【问题讨论】:

标签: amazon-s3 aws-sdk aws-java-sdk


【解决方案1】:

以下简单代码应该适合您,不确定您为什么要尝试将字符转换为字节,反之亦然? 试试这个,效果很好。邮递员/浏览器。

@GET
@RequestMapping("/document")
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces("application/pdf")
public ResponseEntity<InputStreamResource> getDocument() throws IOException {

    final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();

    S3Object object = s3.getObject("BUCKET-NAME", "DOCUMENT-URL");
    S3ObjectInputStream s3is = object.getObjectContent();

    return ResponseEntity.ok()
                .contentType(org.springframework.http.MediaType.APPLICATION_PDF)
                .cacheControl(CacheControl.noCache())
                .header("Content-Disposition", "attachment; filename=" + "testing.pdf")
                .body(new InputStreamResource(s3is));
}

【讨论】:

  • 你值得一试。这就是我想要实现的,直接发送内容而不是存储在本地机器上然后读取和发送。我对 S3ObjectInputStream 和 InputStream 感到困惑,因为我直接从 S3 读取二进制数据。非常感谢。
  • 在控制器中返回 InputStreamResource 是否安全?下载成功后这个InputStream会自动关闭吗?因为在 getObjectContent() 方法的 AWS 文档中有一个警告,这让我对您的方法感到怀疑:“如果您检索 S3Object,您应该尽快关闭此输入流,因为对象内容没有缓冲在内存和流直接来自 Amazon S3。此外,未能关闭此流可能会导致请求池被阻塞。"
  • @ilja 你有这个问题的答案吗? (安全和流关闭)
  • @evgeniy44 还没有,我应该单独问这个问题吗?
  • @ilja 太好了,因为我也面临同样的问题,在我看来这是一个非常合理且不明显的问题
猜你喜欢
  • 2017-10-12
  • 2014-12-24
  • 2017-06-18
  • 2020-12-18
  • 2017-08-14
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多