通过 Java 下载 AWS S3 文件。身份验证调用失败

AWS S3 file download via Java. Failing on Authentication call

我正在尝试通过 Java 从 AWS S3 存储桶下载 JSON 文件。

该文件由名为 Zuora 的第 3 方计费应用程序创建。

第一步是使用 OAuth 凭据生成文件。然后我收到文件 URL 的响应。我可以通过浏览器访问它并将其下载到我的桌​​面,但是当我尝试通过 Java 处理文件时,我 运行 遇到了问题。

我在网上到处都看到人们似乎已经通过使用 AWS 库中的 AmazonS3Client 克服了类似的问题。参考:AWS S3 Java SDK - Download file help

我已经试过了,但是因为我是通过第三方访问存储桶的,所以我没有 Auth ID 和 Secret 来创建凭据来进行调用。

我是否需要这些凭据才能对 AWS S3 上的存储桶执行 GET 调用?我在想我不应该这样做,因为我没有尝试创建文件或存储桶等。我无法在没有凭据的情况下通过 java 下载文件。

下面我添加了我尝试从中下载文件的 URL 和 Java 代码。

Zuora 回复URL: { “数据”: { “id”:“fec47238-6a0f-48ef-9fb2-c7e24da886d5”, "query": "select i.AccountId, i.Amount, i.PostedDate, i.InvoiceNumber, i.Status, i.Id 来自发票 i, 订阅s 其中 i.Status = 'Posted' and i.Amount > 0 and i.AccountId = s.AccountId and s.Id = '8ad084a67d58433a017d5cd0682c0b89'", “useIndexJoin”:假的, “源数据”:“直播”, “queryStatus”:“完成”, “数据文件”:“**https://bucket-name.s3.us-west-2.amazonaws.com/file-name.jsonl?X-Amz-Security-Token=some-tokenX-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20211215T110928Z&X-Amz-SignedHeaders=host&X-Amz-Expires=14400&X-Amz-Credential=Some-Credential&X-Amz-Signature=some-Signature**", “输出行”:1, “处理时间”:1918年, “剩余重试次数”:3, “重试”:3, “更新时间”:“2021-12-15T11:09:28.123Z”, "createdBy": "some-id" }

2 Java:

private final AmazonS3 amazonS3Client = AmazonS3ClientBuilder.standard().withRegion(Regions.US_WEST_2).build();

        try (final S3Object s3Object = amazonS3Client.getObject("bucket-name.s3.us-west-2.amazonaws.com",
                                                                "file-name.jsonl");
                final InputStreamReader streamReader = new InputStreamReader(s3Object.getObjectContent(), StandardCharsets.UTF_8);
                final BufferedReader reader = new BufferedReader(streamReader)) {
                System.out.println(reader.lines().collect(Collectors.toSet()));
        }

错误:com.amazonaws.services.s3.model.AmazonS3Exception:拒绝访问(服务:Amazon S3;状态代码:403;错误代码:AccessDenied;

要使用 AWS SDK 公开的服务客户端,您需要 凭据。这在 开发人员指南 - Java 2.x:

的 AWS SDK 中指定

https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html

话虽如此 - 如果 S3 存储桶中的对象已使用 S3Presigner object 预签名并且存在预签名的 URL,您可以使用 Java URI 访问该对象对象而不使用信用(假设您在时间段内这样做)。

要了解有关预签名的更多信息 - 请参阅开发指南中的此主题:

Working with Amazon S3 presigned URLs

这是一个小 Java SWING 应用程序,它可以使用预签名 URL.

从 Amazon S3 存储桶中获取内容

这里不需要学分

import javax.swing.*;
 import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

class Swing implements ActionListener {
        JFrame frame=new JFrame();
        JButton button=new JButton("Click Me");

        Swing(){
            prepareGUI();
            buttonProperties();
        }

        public void prepareGUI(){
            frame.setTitle("My Window");
            frame.getContentPane().setLayout(null);
            frame.setVisible(true);
            frame.setBounds(200,200,400,400);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        public void buttonProperties(){
            button.setBounds(130,200,100,40);
            frame.add(button);
            button.addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            //Get a presigned PDF from an Amazon S3 bucket.
            try {
                URL url  =  new URL("<Specify PRESIGNED URL> ") ;
                InputStream in = null;
                in = url.openStream();
                FileOutputStream fos = new FileOutputStream(new File("C:\AWS\yourFile2.txt"));
                System.out.println("reading from resource and writing to file...");
                int length = -1;
                byte[] buffer = new byte[1024];// buffer for portion of data from connection
                while ((length = in.read(buffer)) > -1) {
                    fos.write(buffer, 0, length);
                }
                fos.close();
                in.close();
                 System.out.println("File downloaded");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public class HelloWorldSwing {
        public static void main(String[] args)
        {
            new Swing();
        }
    }