如何将Java对象上传至Amazon S3存储桶指定文件夹及代码验证
解答
S3指定文件夹上传逻辑
S3没有物理层面的文件夹概念,控制台里看到的文件夹都是通过对象键(Key)的名称前缀模拟出来的,完全支持指定路径上传,不需要提前手动创建文件夹。
只需要把目标文件夹路径作为前缀,拼接在对象Key前面就行,比如你要把文件存在api-response/2024/11/路径下,直接把这个前缀拼在文件名前面作为上传的Key即可。
现有代码的调整
你现在写的代码会把文件传到存储桶根目录,因为Key直接用了生成的UUID,没加路径前缀,调整后的参考实现如下:
private void s3Upload(MyObject myObject) throws Exception { // 仅当你需要自定义S3配置(指定区域、自定义凭证、超时、代理等)时,才需要显式创建S3客户端 // 走默认配置的话不需要手动建,TransferManagerBuilder会自动加载环境/本地配置里的凭证和区域 /* AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(Regions.CN_NORTH_1) .build(); TransferManager transferManager = TransferManagerBuilder.standard() .withS3Client(s3Client) .build(); */ TransferManager transferManager = TransferManagerBuilder.standard().build(); try { ObjectMapper objectMapper = new ObjectMapper(); byte[] bytesToWrite = objectMapper.writeValueAsBytes(myObject); ObjectMetadata omd = new ObjectMetadata(); omd.setContentLength(bytesToWrite.length); // 建议指定内容类型,不然默认是二进制流,后续访问下载会有类型识别问题 omd.setContentType("application/json"); String uniqueID = UUID.randomUUID().toString(); // 拼接目标文件夹前缀,建议给文件加上.json后缀,方便后续识别 String fileKey = "your/target/folder/path/" + uniqueID + ".json"; // upload是异步方法,调用waitForCompletion阻塞等待上传完成,避免程序提前退出导致上传失败 Upload upload = transferManager.upload("<bucketName>", fileKey, new ByteArrayInputStream(bytesToWrite), omd); upload.waitForCompletion(); } finally { // 用完关闭TransferManager,释放线程池资源,避免内存泄漏 transferManager.shutdownNow(); } }
关于是否需要显式创建S3客户端
- 如果你用默认的凭证加载规则(自动从环境变量、系统属性、本地AWS配置文件、EC2/ECS实例角色等位置读取凭证和默认区域),不需要显式创建S3客户端,
TransferManagerBuilder.standard().build()会在内部自动初始化默认的S3客户端实例。 - 如果你需要自定义配置(比如指定固定区域、自定义凭证提供者、设置连接超时、自定义S3接入点、配置代理等),就需要手动构建
AmazonS3客户端实例,通过withS3Client()方法传入TransferManagerBuilder。
注意事项
- 拼接文件Key的时候不要在最前面加
/,否则会生成一个名称为空的异常前缀层级,不符合路径预期。 - 记得给Key加上对应文件后缀,否则在控制台下载文件的时候没有后缀,无法直接识别文件类型。
upload()方法是异步执行的,如果方法执行完主线程就会退出,一定要调用返回的Upload对象的waitForCompletion()方法等上传结束,不然可能出现上传没完成程序就退出,导致文件丢失。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

