使用 Java 更新現有 Amazon S3 對象
1. 概述
Amazon Simple Storage Service (Amazon S3) 是一種廣泛使用的存儲服務,可提供可擴展、安全且持久的對象存儲。在某些用例中,我們需要更新現有的 Amazon S3 對象。在S3中,對像是不可變的,這意味著我們不能直接修改對象的內容。但是,我們可以用新內容覆蓋該對象,從而有效地“更新”它。
在本教程中,我們將學習如何使用 AWS Java SDK 將同一 AWS S3 路徑的現有文件內容替換為新內容。
2. 前提條件
首先,我們需要確保AWS SDK Maven依賴包已合併到項目中:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.12.530</version>
</dependency>
可以在線找到該軟件包的最新版本。
我們還需要設置 AWS 憑證。我們可以使用以下方法來做到這一點:
- 環境變量:
AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
- AWS 憑證文件:存儲在
~/.aws/credentials
- IAM 角色:在 Amazon EC2 實例上運行應用程序時,為 IAM 角色分配必要的 S3 權限
有關憑證設置的全面指南,請參閱官方 AWS 文檔
3. 更新 S3 對象的步驟
3.1.初始化S3客戶端
@PostConstruct
註釋來自javax.annotation
包,用於在容器(本例中為 Spring)設置 bean 的屬性後執行該方法。下面是初始化S3客戶端的代碼:
@PostConstruct
private void init(){
AWSCredentials credentials = new BasicAWSCredentials(
"AWS AccessKey",
"AWS secretKey"
);
this.amazonS3 = AmazonS3ClientBuilder.standard()
.withRegion(Regions.fromName("us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
}
3.2.將新對像上傳到 S3
現在我們可以使用 AWS Java SDK 在uploadDocument()
方法中將文件上傳到 S3 存儲桶:
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(multipartFile.getContentType());
Map<String, String> attributes = new HashMap<>();
attributes.put("document-content-size", String.valueOf(multipartFile.getSize()));
metadata.setUserMetadata(attributes);
InputStream documentStream = multipartFile.getInputStream();
PutObjectResult putObjectResult = this.awsS3Client.putObject(new PutObjectRequest(s3bucket, key, documentStream, metadata));
下面是調用上述代碼的代碼片段:
public String uploadFile(MultipartFile multipartFile) throws Exception {
String key = "/documents/" + multipartFile.getOriginalFilename();
return this.uploadDocument(this.awsS3Bucket, key, multipartFile);
}
3.3.上傳(覆蓋)對象
由於 S3 中的對像是不可變的,因此“更新”對象涉及用新內容覆蓋該對象。因此,為了更新,我們需要使用用於添加文檔的相同參數集調用相同的uploadDocument()
方法:
public String updateFile(MultipartFile multipartFile, String key) throws Exception {
return this.uploadDocument(this.awsS3Bucket, key, multipartFile);
}
此代碼將用提供的新內容替換現有對象。如果具有給定鍵的對像不存在,S3將創建一個新對象。
3.4. (可選)驗證更新
我們可能想要驗證對像是否已成功更新。實現此目的的一種方法是檢索對象的元數據並檢查LastModified
日期,或者計算對象的校驗和並將其與預期值進行比較。
S3Object s3Object = this.awsS3Client.getObject(s3bucket, key);
logger.info("Last Modified: " + s3Object.getObjectMetadata().getLastModified());
4. 重要考慮因素
我們還需要記住,在 S3 中,覆蓋對象實際上是 PUT 操作,這可能會產生成本。在 S3 上執行操作時,請始終注意成本影響。
如果存儲桶啟用了版本控制,則覆蓋對像不會刪除舊版本。相反,我們將擁有該對象的多個版本。每個版本都有唯一的ID;如果需要,我們可以檢索任何以前的版本。
最後,如果元數據與該對象關聯,請注意覆蓋該對象將使用 PUT 操作期間提供的新元數據替換舊元數據。如果我們想保留舊的元數據,我們必須在請求中顯式設置它。
5. 結論
雖然我們無法直接修改 S3 對象的內容,但使用適用於 Java 的 AWS 開發工具包可以直接用新內容覆蓋對象。始終牢記最佳實踐,例如不要對憑據進行硬編碼以及了解運營的成本影響。通過這些步驟,我們可以放心地使用 Java 管理和更新 S3 對象。
本文的完整實現可以在 GitHub 上找到。