求助:AWS Java SDK 2.0生成S3预签名URL的示例代码
解决AWS Java SDK 2.0生成S3预签名URL的问题
刚帮团队里的人踩过这个坑,SDK 2.0的预签名URL生成逻辑和1.x版本差异挺大的,官方旧文档确实没及时更新对应的2.0示例。下面给你整理了完整的实现代码和注意事项:
第一步:确认依赖配置
首先确保你的项目里引入了AWS SDK 2.0的S3相关依赖,以Maven为例:
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.20.0</version> <!-- 替换成最新稳定版即可 --> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> <version>2.20.0</version> </dependency>
生成预签名URL(GET下载场景)
这个场景用于生成让用户下载S3对象的预签名链接:
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Presigner; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.PresignedGetObjectRequest; import java.net.URL; import java.time.Duration; public class GeneratePresignedUrlForGet { public static void main(String[] args) { String bucketName = "your-bucket-name"; String objectKey = "path/to/your/object.txt"; Region region = Region.US_EAST_1; // 替换成你的桶所在区域 // 初始化S3Presigner,注意用完要关闭 try (S3Presigner presigner = S3Presigner.builder() .region(region) .build()) { // 创建Get请求 GetObjectRequest getObjectRequest = GetObjectRequest.builder() .bucket(bucketName) .key(objectKey) .build(); // 生成预签名请求,设置有效期(比如1小时) PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(r -> r .signatureDuration(Duration.ofHours(1)) .getObjectRequest(getObjectRequest)); // 获取最终的预签名URL URL presignedUrl = presignedRequest.url(); System.out.println("预签名下载URL: " + presignedUrl.toString()); } } }
生成预签名URL(PUT上传场景)
如果需要让用户通过预签名URL上传文件到S3,用这个示例:
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Presigner; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.PresignedPutObjectRequest; import java.net.URL; import java.time.Duration; public class GeneratePresignedUrlForPut { public static void main(String[] args) { String bucketName = "your-bucket-name"; String objectKey = "path/to/upload/object.txt"; Region region = Region.US_EAST_1; try (S3Presigner presigner = S3Presigner.builder() .region(region) .build()) { PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket(bucketName) .key(objectKey) .build(); PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(r -> r .signatureDuration(Duration.ofHours(1)) .putObjectRequest(putObjectRequest)); URL presignedUrl = presignedRequest.url(); System.out.println("预签名上传URL: " + presignedUrl.toString()); // 额外提示:用户可以用这个URL直接发起PUT请求上传文件,比如用curl: // curl -X PUT -T "local-file.txt" "presigned-url-here" } } }
关键注意事项
- 资源清理:
S3Presigner是需要关闭的资源,一定要用try-with-resources语法,避免连接泄漏 - 有效期设置:
signatureDuration可以根据需求调整,最长不能超过7天(AWS的限制) - 权限问题:生成预签名URL的IAM账号必须拥有对应的S3操作权限(比如
s3:GetObject或s3:PutObject) - 区域匹配:一定要确保S3Presigner的区域和你的桶所在区域一致,否则会报错
内容的提问来源于stack exchange,提问作者luanlucas




