AWS Amazon S3 Java SDK-上载大文件时在过期时刷新凭据/令牌

AWS Amazon S3 Java SDK-上载大文件时在过期时刷新凭据/令牌,java,amazon-web-services,amazon-s3,aws-sdk,aws-sdk-java-2.0,Java,Amazon Web Services,Amazon S3,Aws Sdk,Aws Sdk Java 2.0,我正在尝试将一个大文件上载到使用令牌的服务器,令牌在10分钟后过期,因此如果我上载一个小文件,它将正常工作。因此,如果文件太大,我将遇到一些问题,并将尝试在访问被拒绝时永久上载 因此,我需要刷新BasicAWSCredentials中的令牌,该令牌用于AWSStaticCredentialsProvider,因此我不确定如何进行刷新,请帮助=) 值得一提的是,我们使用本地服务器(而不是亚马逊云)提供令牌,为了方便起见,我们使用亚马逊的代码 这是我的密码: public void uploadMu

我正在尝试将一个大文件上载到使用令牌的服务器,令牌在10分钟后过期,因此如果我上载一个小文件,它将正常工作。因此,如果文件太大,我将遇到一些问题,并将尝试在访问被拒绝时永久上载

因此,我需要刷新BasicAWSCredentials中的令牌,该令牌用于AWSStaticCredentialsProvider,因此我不确定如何进行刷新,请帮助=)

值得一提的是,我们使用本地服务器(而不是亚马逊云)提供令牌,为了方便起见,我们使用亚马逊的代码

这是我的密码:

public void uploadMultipart(File file) throws Exception {
    //this method will give you a initial token for a given user, 
    //than calculates when a new token is needed and will refresh it just when necessary

    String token = getUsetToken();
    String existingBucketName = myTenant.toLowerCase() + ".package.upload";
    String endPoint = urlAPI + "s3/buckets/";
    String strSize = FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(file));
    System.out.println("File size: " + strSize);

    AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endPoint, null);//note: Region has to be null
    //AWSCredentialsProvider        
    BasicAWSCredentials sessionCredentials = new BasicAWSCredentials(token, "NOT_USED");//secretKey should be set to NOT_USED

    AmazonS3 s3 = AmazonS3ClientBuilder
            .standard()
            .withCredentials(new AWSStaticCredentialsProvider(sessionCredentials))
            .withEndpointConfiguration(endpointConfiguration)
            .enablePathStyleAccess()
            .build();

    int maxUploadThreads = 5;
    TransferManager tm = TransferManagerBuilder
            .standard()
            .withS3Client(s3)
            .withMultipartUploadThreshold((long) (5 * 1024 * 1024))
            .withExecutorFactory(() -> Executors.newFixedThreadPool(maxUploadThreads))
            .build();

    PutObjectRequest request = new PutObjectRequest(existingBucketName, file.getName(), file);
    //request.putCustomRequestHeader("Access-Token", token);
    ProgressListener progressListener = progressEvent -> System.out.println("Transferred bytes: " + progressEvent.getBytesTransferred());
    request.setGeneralProgressListener(progressListener);
    Upload upload = tm.upload(request);

    LocalDateTime uploadStartedAt = LocalDateTime.now();
    log.info("Starting upload at: " + uploadStartedAt);

    try {
        upload.waitForCompletion();
        //upload.waitForUploadResult();
        log.info("Upload completed. " + strSize);

    } catch (Exception e) {//AmazonClientException
        log.error("Error occurred while uploading file - " + strSize);
        e.printStackTrace();
    }
}
上载文件(或多部分文件的一部分)时,您使用的凭据必须持续足够长的时间才能完成上载。您无法刷新凭据,因为没有方法更新您正在为已签名的请求使用新凭据的AWS S3


你可以把上传的文件分成更小的文件,这样上传速度会更快。然后只上传X部分。刷新您的凭据并上载Y部分。重复此操作,直到上传所有部件。然后您需要通过组合这些部分(这是一个单独的命令)来完成。这不是一个完美的解决方案,因为传输速度无法精确控制,这意味着您必须编写自己的上传代码(这并不难)。

找到了解决方案

我找到了一种方法让它工作,老实说,我对结果很满意,我用大文件(50gd.zip)做了很多测试,在每种情况下都工作得很好

我的解决方案是,删除以下行:
BasicAWSCredentials sessionredentials=newbasicawscredentials(标记,“未使用”)

AWSCredentials
是一个接口,因此我们可以用动态的东西覆盖它,在getToken()方法中保存令牌过期并需要新令牌的逻辑,这意味着您可以在每次调用时都不受任何伤害

AWSCredentials sessionCredentials = new AWSCredentials() {
    @Override
    public String getAWSAccessKeyId() {
        try {
            return getToken(); //getToken() method return a string 
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public String getAWSSecretKey() {
        return "NOT_USED";
    }
};

值得一读:。尝试获取更长寿的凭据。@jarmod-感谢您的回复,这篇文章很好,可能是一个选项,因此这篇文章大约有3年了,我仍然希望使用aws java可以找到其他解决方法sdk@jarmod找到解决方案请看,谢谢回复hi@John Hanley非常感谢您的帖子,我找到了一种方法来实现这一点我怀疑您意外地恢复到使用另一组凭据,特别是长寿命凭据,例如在您的环境中配置的IAN用户,这就是为什么它现在可以工作的原因。我将尝试一下,因为它看起来正是我所需要的更新,类似于在网页上使用滚动过期令牌。如果它不起作用,我将直接与AWS合作,看看他们是否能修复它。@justdan23对我来说,它起作用了,事实上,代码每天都在运行,直到今天都没有问题,我希望这对你也起作用,一切顺利