AmazonS3Client(credentials)已不建议使用

77
我试图阅读Amazon S3上可用的文件,正如问题所解释的那样。我找不到代替已废弃的构造函数的替代调用。
以下是代码:
private String AccessKeyID = "xxxxxxxxxxxxxxxxxxxx";
private String SecretAccessKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static String bucketName     = "documentcontainer";
private static String keyName     = "test";
//private static String uploadFileName    = "/PATH TO FILE WHICH WANT TO UPLOAD/abc.txt";

AWSCredentials credentials = new BasicAWSCredentials(AccessKeyID, SecretAccessKey);

void downloadfile() throws IOException
{

    // Problem lies here - AmazonS3Client is deprecated
    AmazonS3 s3client = new AmazonS3Client(credentials);
        try {
        System.out.println("Downloading an object...");
        S3Object s3object = s3client.getObject(new GetObjectRequest(
                bucketName, keyName));
        System.out.println("Content-Type: "  +
                s3object.getObjectMetadata().getContentType());
        InputStream input = s3object.getObjectContent();

        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        while (true) {
            String line = reader.readLine();
            if (line == null) break;

            System.out.println("    " + line);
        }
        System.out.println();
    } catch (AmazonServiceException ase) {
          //do something
    } catch (AmazonClientException ace) {
        // do something
    }
 }

需要帮助吗?如果需要更多解释,请提出。我已经检查了SDK的.zip文件中提供的示例代码,并且它是相同的。


4
你需要使用 AwsClientBuilder 类作为替代方案。 - franklinsijo
@franklinsijo 有代码示例或源代码可以参考吗? - Asif Ali
你能把它添加为答案吗?我会在你的答案中编辑一小段代码并接受它。 - Asif Ali
1
https://aws.amazon.com/blogs/developer/client-constructors-now-deprecated/ - Priyadarshi Kunal
在这个文件中硬编码密钥对可以吗?当您公开部署Web应用程序时,这个文件会在哪里?这不是一个安全问题吗? - Jessica
7个回答

151

您可以选择使用AmazonS3ClientBuilderAwsClientBuilder作为替代方案。

对于S3,最简单的方法是使用AmazonS3ClientBuilder

BasicAWSCredentials creds = new BasicAWSCredentials("access_key", "secret_key"); 

AmazonS3 s3Client = AmazonS3ClientBuilder
    .standard()
    .withCredentials(new AWSStaticCredentialsProvider(creds))
    .build();

2
这个弃用的背后是否有任何原因,使用AmazonS3ClientBuilder.standard()与之前的SDK中的new AmazonS3Client相比有哪些好处? - rockstarjindal
2
最新的 .Net 4.0 NuGet 包中都没有 AmazonS3ClientBuilderAwsClientBuilder,同时也有多种方法被弃用,包括我目前正在使用的 StoredProfileAWSCredentials。有人知道在 .Net 4.0 中推荐的方法吗? - bikeman868
4
如果您使用AmazonS3ClientBuilder,那么myClient.setRegion()将不再起作用。您需要使用AmazonS3ClientBuilder.standard().withCredential().withRegion("eu-west-1").build();来替代它。 - user3526918
AWSStaticCredentialsProvider也已经过时了 @franklinsijo - Amit Kumar
1
@rockstarjindal,使用构建器创建客户端比旧的构造函数更好,因为:使用构建器创建的客户端是不可变的;客户端必须具有显式区域;构建器提供了更清晰的链接API。 - Priyadarshi Kunal

15

使用下面列出的代码创建一个无凭证的S3客户端:

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();

一个使用示例是lambda函数调用S3。


谢谢,但只有在我包含withRegion()时才对我起作用。 - Clive Sargeant
通过构建器创建的客户端必须具有明确定义的区域(即通过调用withRegion或作为DefaultAwsRegionProviderChain的一部分)。如果构建器无法确定客户端的区域,则会抛出SdkClientException异常。 - Priyadarshi Kunal

10
您需要通过标记传递区域信息。
com.amazonaws.regions.Region object.

Use AmazonS3Client(credentials, Region.getRegion(Regions.REPLACE_WITH_YOUR_REGION))

我从哪里获取区域信息?它的一个例子是什么?为什么需要区域信息? - android developer
请参考以下链接,在AWS中找到所在地区: https://dev59.com/em855IYBdhLWcg3wm1m3 - Abhay Pratap
如果我之前有这个:AmazonS3Client s3Client = new AmazonS3Client(new AnonymousAWSCredentials());?它没有区域,对吧? - android developer
您可以随时选择默认区域: https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/regions/Regions.html#DEFAULT_REGION - Andreas Panagiotidis

2
你可以使用以下方式创建S3默认客户端(使用aws-java-sdk-s3-1.11.232):
AmazonS3ClientBuilder.defaultClient();

1
它从哪里获取凭据的? - JaviOverflow
您可以通过以下方式执行此操作: 1.使用默认凭据提供程序链(建议)。 2.使用特定的凭据提供程序或提供程序链。 3.自己提供凭证。 建议使用IAM角色。例如,对于AWS Lambda,请创建一个具有访问S3权限的IAM角色,并在lambda代码中创建客户端。在配置Lambda时提供此角色,类似地,对于EC2实例或ECS等。 - Sach
1
能否详细解释一下这句话的意思?“1.使用默认凭证提供程序链”。 - JaviOverflow

2

如果只有凭据在构造函数中被弃用,你可以使用以下方法:

 val awsConfiguration = AWSConfiguration(context)
 val awsCreds = CognitoCachingCredentialsProvider(context, awsConfiguration)
 val s3Client = AmazonS3Client(awsCreds, Region.getRegion(Regions.EU_CENTRAL_1))

1
使用AWS SDK for Java 2.x,您也可以构建自己的credentialProvider,方法如下:
// 凭证提供者
package com.myproxylib.aws;

import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;

public class CustomCredentialsProvider implements AwsCredentialsProvider {

    private final String accessKeyId;
    private final String secretAccessKey;

    public CustomCredentialsProvider(String accessKeyId, String secretAccessKey) {
        this.secretAccessKey = secretAccessKey;
        this.accessKeyId = accessKeyId;
    }

    @Override
    public AwsCredentials resolveCredentials() {
        return new CustomAwsCredentialsResolver(accessKeyId, secretAccessKey);
    }

}

// 凭证解析器


package com.myproxylib.aws;

import software.amazon.awssdk.auth.credentials.AwsCredentials;

public class CustomAwsCredentialsResolver implements AwsCredentials {

    private final String accessKeyId;
    private final String secretAccessKey;

    CustomAwsCredentialsResolver(String accessKeyId, String secretAccessKey) {
        this.secretAccessKey = secretAccessKey;
        this.accessKeyId = accessKeyId;
    }

    @Override
    public String accessKeyId() {
        return accessKeyId;
    }

    @Override
    public String secretAccessKey() {
        return secretAccessKey;
    }
}

// 提供者的使用方法


package com.myproxylib.aws.s3;

public class S3Storage implements IS3StorageCapable {

    private final S3Client s3Client;

    public S3Storage(String accessKeyId, String secretAccessKey, String region) {

        this.s3Client = S3Client.builder().credentialsProvider(new CustomCredentialsProvider(accessKeyId, secretAccessKey)).region(of(region)).build();
    }

注意:

  1. 当然,库用户可以从任何地方获取凭据,在调用S3构造函数之前将其解析为Java属性。

  2. 在可能的情况下,请优先考虑其他答案和文档中提到的方法。我的用例需要这样做。


0
implementation 'com.amazonaws:aws-android-sdk-s3:2.16.12'

val key = "XXX"
val secret = "XXX"
val credentials = BasicAWSCredentials(key, secret)
val s3 = AmazonS3Client(
    credentials, com.amazonaws.regions.Region.getRegion(
        Regions.US_EAST_2
    )
)
val expires = Date(Date().time + 1000 * 60 * 60)

val keyFile = "13/thumbnail_800x600_13_photo.jpeg"
val generatePresignedUrlRequest = GeneratePresignedUrlRequest(
    "bucket_name",
    keyFile
)
generatePresignedUrlRequest.expiration = expires
val url: URL = s3.generatePresignedUrl(generatePresignedUrlRequest)

GlideApp.with(this)
    .load(url.toString())
    .apply(RequestOptions.centerCropTransform())
    .into(image)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接