使用Java AWS SDK 1.x通过S3访问点调用GetObject时遇InvalidBucketName错误
问题解决:AWS SDK 1.x 使用S3访问点执行GetObject时报InvalidBucketName错误
问题背景
使用AWS SDK for Java 1.x(版本1.12.348、1.11.1004),尝试直接将S3访问点ARN作为bucket名称传入GetObjectRequest执行GetObject操作,相关代码及依赖如下:
依赖配置:
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-s3</artifactId> <version>1.12.348</version> </dependency>
执行代码:
AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard().withRegion(awsRegion).build(); String bucketName= "arn:aws:s3:<bucket-region>:<accountNumber>:accesspoint:<access-point-name>"; String key = "bucket/path/filename.txt"; File to = // 目标文件; amazonS3.getObject(new GetObjectRequest(bucketName, key), to);
根据官方文档描述,bucket参数可传入存储桶名称或访问点ARN,但实际执行时抛出错误:
<Error><Code>InvalidBucketName</Code><Message>The specified bucket is not valid.</Message><BucketName>arn:aws:s3:<bucket-region>:<accountNumber>:accesspoint:<access-point-name></BucketName><RequestId>**********</RequestId><HostId>*******************</HostId></Error>
原因分析
AWS SDK for Java 1.x对bucket名称有格式校验规则,ARN中的冒号、斜杠等特殊字符不符合校验要求,因此直接传入ARN会触发InvalidBucketName错误。官方文档中提到的"支持传入ARN"更多针对REST API直接调用场景,SDK 1.x需要通过特定方式处理访问点。
解决方案
方案1:使用AccessPoint类构造请求
SDK 1.x提供了AccessPoint类专门用于处理访问点,通过该类构建请求即可绕过bucket名称校验:
import com.amazonaws.services.s3.model.AccessPoint; // 初始化S3客户端 AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard().withRegion(awsRegion).build(); // 构建访问点对象,依次传入访问点名称、AWS账号ID、访问点所在区域 AccessPoint accessPoint = new AccessPoint("<access-point-name>", "<accountNumber>", "<bucket-region>"); String key = "bucket/path/filename.txt"; File to = // 目标文件; // 使用访问点对象创建GetObjectRequest GetObjectRequest request = new GetObjectRequest(accessPoint, key); amazonS3.getObject(request, to);
方案2:使用访问点的域名格式作为bucket名称
将访问点转换为域名格式(而非ARN)传入bucket参数,域名格式为:{访问点名称}-{AWS账号ID}.s3-accesspoint.{区域}.amazonaws.com
代码示例:
AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard().withRegion(awsRegion).build(); // 替换为实际的访问点名称、账号ID和区域 String bucketName = "<access-point-name>-<accountNumber>.s3-accesspoint.<bucket-region>.amazonaws.com"; String key = "bucket/path/filename.txt"; File to = // 目标文件; amazonS3.getObject(new GetObjectRequest(bucketName, key), to);
注意事项
- 确保使用的SDK版本支持S3访问点操作(1.11.x及以上版本均支持);
- IAM权限策略中需明确允许通过该访问点执行
s3:GetObject操作,示例策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:<bucket-region>:<accountNumber>:accesspoint:<access-point-name>/object/bucket/path/filename.txt" } ] }
内容的提问来源于stack exchange,提问作者adesai
相关产品推荐
相关产品推荐

