使用 Java V2
IBM Cloud® Object Storage SDK for Java v2 提供了可充分利用 IBM Cloud Object Storage 的功能。
IBM Cloud Object Storage SDK for Java v2 功能全面,许多特性和功能超出了本指南的范围和篇幅。 有关详细的类和方法文档,请参阅 Java API 参考文档。 在 GitHub 存储库中可以找到源代码。
最新消息 v2
IBM Cloud Object Storage SDK for Java v2 是基于 AWS SDK v2 架构的现代化版本,带来了重大改进:
- 不可变构建器:所有请求和响应对象都使用不可变构建器模式,以提高线程安全性
- 现代软件包结构:新命名空间
com.ibm.cos.v2.*,组织更简洁 - 增强的异步支持:为非阻塞操作引入
S3AsyncClient - 改进的流媒体:更好的流媒体应用程序接口,包括
RequestBody和ResponseTransformer - 自动 IAM 令牌管理:SDK 自动处理 IAM 令牌刷新
- 类型安全使用构建器加强编译时类型检查
- 现代 HTTP 堆栈:支持 Apache HTTP 客户端和 Netty 异步操作
对于从 v1 迁移的开发人员,请参阅《 迁移指南 》。
获取 SDK
使用 IBM Cloud Object Storage Java SDK v2 的最简单方法是使用 Maven 管理依赖关系。 如果您不熟悉 Maven,可以使用《 Maven in 5-Minutes 指南》快速上手。
Maven 使用名为 pom.xml 的文件来指定 Java 项目所需的库(及其版本)。 以下是 pom.xml 文件示例,用于使用 IBM Cloud Object Storage Java SDK v2 连接 Object Storage。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cos</groupId>
<artifactId>docs</artifactId>
<packaging>jar</packaging>
<version>2.0-SNAPSHOT</version>
<name>docs</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.ibm.cos.v2</groupId>
<artifactId>cos-java-sdk</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
</project>
SDK 参考资料
核心类
- S3Client- 同步 S3 客户端
- S3AsyncClient- 异步 S3 客户端
- S3ClientBuilder- S3 客户端的建设者
凭证
- AwsCredentials- 基本凭据接口
- BasicIBMOAuthCredentials- IBM IAM 证书
- AwsBasicCredentials- HMAC 证书
- StaticCredentialsProvider- 静态证书提供者
- AwsCredentialsProvider- 凭证提供者接口
配置
- 地区- AWS 地区代表
- ClientOverrideConfiguration- 客户端配置覆盖
- S3Configuration- S3-specific 配置
流式方法
- RequestBody- 上传请求正文
- ResponseTransformer- 用于下载的响应变压器
- ResponseInputStream- 输入流响应
例外
- S3Exception- 基础 S3 例外
- NoSuchBucketException- 未找到水桶
- NoSuchKeyException- 未找到对象
- SdkClientException- 客户端异常
创建客户机和获取凭证
在以下示例中,将通过提供凭证信息(API 密钥和服务实例标识)来创建和配置客户机 cos。 这些值还可以自动从凭证文件或环境变量中获取。
生成服务凭证后,生成的 JSON 文档可以保存到 ~/.bluemix/cos_credentials。 除非在客户机创建期间显式设置了其他凭证,否则 SDK 会自动从此文件中获取凭证。 如果 cos_credentials 文件包含 HMAC 密钥,那么客户机会使用签名进行认证;如果不包含 HMAC 密钥,客户机将使用提供的 API 密钥通过不记名令牌进行认证。
如果是从 AWS S3 进行迁移,那么还可以从 ~/.aws/credentials 中获取以下格式的凭证数据:
[default]
aws_access_key_id = {API_KEY}
aws_secret_access_key = {SERVICE_INSTANCE_ID}
如果 ~/.bluemix/cos_credentials 和 ~/.aws/credentials 同时存在,那么 cos_credentials 优先。
有关客户端构建的更多详情,请参阅 Java API 参考文档。
代码示例
让我们从一个完整的示例类开始,了解一些基本功能。 该 CosExample 类可列出现有水桶中的对象,创建新水桶,然后列出服务实例中的所有水桶。
收集必需的信息
bucketName和newBucketName是唯一的 DNS 安全字符串。 因为存储区名称在整个系统中唯一,因此如果多次运行此示例,那么需要更改这些值。 删除后,名称会保留 10-15 分钟。apiKey是 服务证书 中的值,如apikey。serviceInstanceId是 服务证书 中的值,如resource_instance_id。endpointUrl是一个服务端点 URL,包括https://协议。 这不是 服务证书 中的endpoints值。 有关端点的更多信息,请参阅 端点和存储位置。location必须设置为storageClass的位置部分。 对于us-south-standard,这将是us-south。 此变量仅用于计算 HMAC 签名,但对于任何客户机,此变量都是必需的,包括使用 IAM API 密钥的此示例。
package com.cos;
import java.net.URI;
import java.util.List;
import com.ibm.cos.v2.auth.credentials.AwsCredentials;
import com.ibm.cos.v2.auth.credentials.StaticCredentialsProvider;
import com.ibm.cos.v2.auth.credentials.ibmOAuth.BasicIBMOAuthCredentials;
import com.ibm.cos.v2.regions.Region;
import com.ibm.cos.v2.services.s3.S3Client;
import com.ibm.cos.v2.services.s3.model.*;
public class CosExample {
private static String COS_ENDPOINT = "<endpoint>";
private static String COS_API_KEY_ID = "<api-key>";
private static String COS_SERVICE_INSTANCE_ID = "<service-instance-id>";
private static String COS_LOCATION = "<location>";
public static void main(String[] args) {
System.out.println("Current time: " + new java.util.Date());
// Create IBM COS credentials using API key
AwsCredentials credentials = new BasicIBMOAuthCredentials(COS_API_KEY_ID, COS_SERVICE_INSTANCE_ID);
// Create the S3 client
S3Client cosClient = S3Client.builder()
.endpointOverride(URI.create(COS_ENDPOINT))
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.region(Region.of(COS_LOCATION))
.build();
listObjects("my-bucket", cosClient);
createBucket("my-new-bucket", cosClient);
listBuckets(cosClient);
cosClient.close();
}
public static void listObjects(String bucketName, S3Client cosClient) {
System.out.println("Listing objects in bucket: " + bucketName);
ListObjectsV2Request request = ListObjectsV2Request.builder()
.bucket(bucketName)
.build();
ListObjectsV2Response response = cosClient.listObjectsV2(request);
List<S3Object> objects = response.contents();
for (S3Object object : objects) {
System.out.println("Item: " + object.key() + " (" + object.size() + " bytes)");
}
}
public static void createBucket(String bucketName, S3Client cosClient) {
System.out.println("Creating bucket: " + bucketName);
CreateBucketRequest request = CreateBucketRequest.builder()
.bucket(bucketName)
.build();
cosClient.createBucket(request);
System.out.println("Bucket created: " + bucketName);
}
public static void listBuckets(S3Client cosClient) {
System.out.println("Listing buckets:");
ListBucketsResponse response = cosClient.listBuckets();
List<Bucket> buckets = response.buckets();
for (Bucket bucket : buckets) {
System.out.println("Bucket Name: " + bucket.name());
}
}
}
主要参考资料
确定端点
有关端点的更多信息,请参阅端点和存储位置。
端点也遵循这一模式:https://s3.{region}.cloud-object-storage.appdomain.cloud
示例:
- 美国南部:
https://s3.us-south.cloud-object-storage.appdomain.cloud - 美国东部:
https://s3.us-east.cloud-object-storage.appdomain.cloud - 欧盟 英国
https://s3.eu-gb.cloud-object-storage.appdomain.cloud
创建新存储区
public static void createBucket(String bucketName, S3Client cosClient) {
System.out.println("Creating new bucket: " + bucketName);
CreateBucketRequest request = CreateBucketRequest.builder()
.bucket(bucketName)
.build();
cosClient.createBucket(request);
System.out.println("Bucket: " + bucketName + " created!");
}
密钥引用
创建使用其他存储类的存储区
public static void createBucketWithStorageClass(String bucketName, String storageClass, String location, S3Client cosClient) {
System.out.println("Creating bucket: " + bucketName + " with storage class: " + storageClass);
CreateBucketRequest request = CreateBucketRequest.builder()
.bucket(bucketName)
.ibmServiceInstanceId(COS_SERVICE_INSTANCE_ID)
.build();
cosClient.createBucket(request);
System.out.println("Bucket: " + bucketName + " created with " + storageClass + " class storage!");
}
存储类选项包括
us-south-standard/us-east-standard/eu-gb-standard- 标准存储us-south-vault/us-east-vault/eu-gb-vault- 金库存储us-south-cold/us-east-cold/eu-gb-cold- 冷库储存us-south-flex/us-east-flex/eu-gb-flex- 灵活存储
密钥引用
创建新的文本文件
public static void createTextFile(String bucketName, String itemName, String fileText, S3Client cosClient) {
System.out.println("Creating new item: " + itemName);
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
cosClient.putObject(request, RequestBody.fromString(fileText));
System.out.println("Item: " + itemName + " created!");
}
主要参考资料
通过文件上传对象
public static void putObject(String bucketName, String itemName, String filePath, S3Client cosClient) {
System.out.println("Creating new item: " + itemName);
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
cosClient.putObject(request, RequestBody.fromFile(new File(filePath)));
System.out.println("Item: " + itemName + " created!");
}
主要参考资料
使用流上传对象
public static void putObjectStream(String bucketName, String itemName, InputStream inputStream, long contentLength, S3Client cosClient) {
System.out.println("Creating new item: " + itemName + " from input stream");
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.contentLength(contentLength)
.build();
cosClient.putObject(request, RequestBody.fromInputStream(inputStream, contentLength));
System.out.println("Item: " + itemName + " created!");
}
主要参考资料
将对象下载到文件
public static void getObject(String bucketName, String itemName, String filePath, S3Client cosClient) {
System.out.println("Retrieving item: " + itemName);
GetObjectRequest request = GetObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
cosClient.getObject(request, ResponseTransformer.toFile(new File(filePath)));
System.out.println("Item: " + itemName + " downloaded to: " + filePath);
}
主要参考资料
使用流下载对象
public static void getObjectStream(String bucketName, String itemName, S3Client cosClient) {
System.out.println("Retrieving item: " + itemName + " as stream");
GetObjectRequest request = GetObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
ResponseInputStream<GetObjectResponse> response = cosClient.getObject(request);
try (InputStream inputStream = response) {
// Process the input stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
// Process bytes
System.out.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
System.err.println("Error reading object: " + e.getMessage());
}
System.out.println("\nItem: " + itemName + " retrieved!");
}
主要参考资料
复制对象
public static void copyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey, S3Client cosClient) {
System.out.println("Copying item: " + sourceKey + " from bucket: " + sourceBucketName +
" to: " + destinationKey + " in bucket: " + destinationBucketName);
CopyObjectRequest request = CopyObjectRequest.builder()
.sourceBucket(sourceBucketName)
.sourceKey(sourceKey)
.destinationBucket(destinationBucketName)
.destinationKey(destinationKey)
.build();
cosClient.copyObject(request);
System.out.println("Item: " + sourceKey + " copied!");
}
主要参考资料
列出可用存储区
public static void listBuckets(S3Client cosClient) {
System.out.println("Listing buckets:");
ListBucketsResponse response = cosClient.listBuckets();
List<Bucket> buckets = response.buckets();
for (Bucket bucket : buckets) {
System.out.println("Bucket Name: " + bucket.name());
}
}
主要参考资料
获取特定项的文件内容
public static void getItem(String bucketName, String itemName, S3Client cosClient) {
System.out.println("Retrieving item: " + itemName);
GetObjectRequest request = GetObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
ResponseInputStream<GetObjectResponse> response = cosClient.getObject(request);
try {
String content = new String(response.readAllBytes(), StandardCharsets.UTF_8);
System.out.println("File Contents:\n" + content);
} catch (IOException e) {
System.err.println("Error reading object: " + e.getMessage());
}
}
主要参考资料
从存储区中删除一个项
public static void deleteItem(String bucketName, String itemName, S3Client cosClient) {
System.out.println("Deleting item: " + itemName);
DeleteObjectRequest request = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
cosClient.deleteObject(request);
System.out.println("Item: " + itemName + " deleted!");
}
主要参考资料
从存储区中删除多个项
public static void deleteMultipleItems(String bucketName, List<String> itemNames, S3Client cosClient) {
System.out.println("Deleting multiple items from bucket: " + bucketName);
List<ObjectIdentifier> objectsToDelete = itemNames.stream()
.map(key -> ObjectIdentifier.builder().key(key).build())
.collect(Collectors.toList());
Delete delete = Delete.builder()
.objects(objectsToDelete)
.build();
DeleteObjectsRequest request = DeleteObjectsRequest.builder()
.bucket(bucketName)
.delete(delete)
.build();
DeleteObjectsResponse response = cosClient.deleteObjects(request);
System.out.println("Deleted " + response.deleted().size() + " items!");
}
主要参考资料
删除存储区
水桶必须清空后才能删除。
public static void deleteBucket(String bucketName, S3Client cosClient) {
System.out.println("Deleting bucket: " + bucketName);
DeleteBucketRequest request = DeleteBucketRequest.builder()
.bucket(bucketName)
.build();
cosClient.deleteBucket(request);
System.out.println("Bucket: " + bucketName + " deleted!");
}
主要参考资料
检查对象是否公共可读
public static boolean isObjectPubliclyReadable(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Checking if object is publicly readable: " + objectKey);
try {
GetObjectAclRequest request = GetObjectAclRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
GetObjectAclResponse response = cosClient.getObjectAcl(request);
for (Grant grant : response.grants()) {
if (grant.grantee().type() == Type.GROUP &&
grant.grantee().uri() != null &&
grant.grantee().uri().contains("AllUsers") &&
grant.permission() == Permission.READ) {
System.out.println("Object is publicly readable");
return true;
}
}
System.out.println("Object is not publicly readable");
return false;
} catch (S3Exception e) {
System.err.println("Error checking object ACL: " + e.getMessage());
return false;
}
}
主要参考资料
执行分块上传
使用较大的对象时,建议使用分块上传操作将对象写入 IBM Cloud Object Storage。 可以将单个对象的上传作为一组分块来执行,这些分块可以按任意顺序单独上传,也可以并行上传。 上传完成后,IBM Cloud Object Storage 会将所有分块显示为单个对象。
分块上传仅可用于大于 5 MB 的对象。 对于小于 50 GB 的对象,建议的分块大小为 20 MB 到 100 MB,以实现最佳性能。 对于更大的对象,可以增大分块大小,而不会对性能产生重大影响。
public static void multipartUpload(String bucketName, String itemName, String filePath, S3Client cosClient) {
System.out.println("Starting multipart upload for: " + itemName);
// Step 1: Initiate multipart upload
CreateMultipartUploadRequest initiateRequest = CreateMultipartUploadRequest.builder()
.bucket(bucketName)
.key(itemName)
.build();
CreateMultipartUploadResponse initiateResponse = cosClient.createMultipartUpload(initiateRequest);
String uploadId = initiateResponse.uploadId();
System.out.println("Upload ID: " + uploadId);
// Step 2: Upload parts
int partNumber = 1;
List<CompletedPart> completedParts = new ArrayList<>();
ByteBuffer buffer = ByteBuffer.allocate(5 * 1024 * 1024); // 5 MB parts
try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
long fileSize = file.length();
long position = 0;
while (position < fileSize) {
file.seek(position);
long bytesRead = file.getChannel().read(buffer);
buffer.flip();
UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
.bucket(bucketName)
.key(itemName)
.uploadId(uploadId)
.partNumber(partNumber)
.build();
UploadPartResponse partResponse = cosClient.uploadPart(
uploadPartRequest,
RequestBody.fromByteBuffer(buffer)
);
CompletedPart part = CompletedPart.builder()
.partNumber(partNumber)
.eTag(partResponse.eTag())
.build();
completedParts.add(part);
System.out.println("Uploaded part " + partNumber);
buffer.clear();
position += bytesRead;
partNumber++;
}
} catch (IOException e) {
System.err.println("Error during multipart upload: " + e.getMessage());
// Abort the multipart upload on error
AbortMultipartUploadRequest abortRequest = AbortMultipartUploadRequest.builder()
.bucket(bucketName)
.key(itemName)
.uploadId(uploadId)
.build();
cosClient.abortMultipartUpload(abortRequest);
return;
}
// Step 3: Complete multipart upload
CompletedMultipartUpload completedUpload = CompletedMultipartUpload.builder()
.parts(completedParts)
.build();
CompleteMultipartUploadRequest completeRequest = CompleteMultipartUploadRequest.builder()
.bucket(bucketName)
.key(itemName)
.uploadId(uploadId)
.multipartUpload(completedUpload)
.build();
cosClient.completeMultipartUpload(completeRequest);
System.out.println("Multipart upload completed for: " + itemName);
}
主要参考资料
使用不可变对象存储器
用户可以配置具有不可变 Object Storage 策略的存储桶,以防止对象在规定时间内被修改或删除。 保留期可以按对象指定,也可以继承在数据桶上设置的默认保留期。
为水桶添加保护配置
此 PUT 操作实现使用 protection 查询参数来设置现有存储区的保留时间参数。 此操作允许您设置或更改最短保留期、缺省保留期和最长保留期。 此操作还允许您更改存储区的保护状态。
对于写入受保护存储区的对象,在保护时间段到期并且除去了对象上的所有合法保留之前,无法删除这些对象。 除非在创建对象时提供了特定于对象的值,否则将向对象提供存储区的缺省保留时间值。 受保护存储桶中不再保留的对象(保留期已过,且对象没有任何合法保留),在被覆盖后将再次被保留。 可以在对象覆盖请求中提供新的保留期,否则会为对象提供存储区的缺省保留时间。
保留期设置 MinimumRetention、DefaultRetention 和 MaximumRetention 的最小和最大支持值分别为 0 天和 365243 天(1000 年)。
public static void addProtectionConfigurationToBucket(String bucketName, S3Client cosClient) {
System.out.println("Adding protection configuration to bucket: " + bucketName);
BucketProtectionConfiguration protectionConfig = BucketProtectionConfiguration.builder()
.status(BucketProtectionStatus.RETENTION)
.minimumRetention(BucketProtectionMinimumRetention.builder()
.days(10)
.build())
.defaultRetention(BucketProtectionDefaultRetention.builder()
.days(100)
.build())
.maximumRetention(BucketProtectionMaximumRetention.builder()
.days(1000)
.build())
.build();
PutBucketProtectionConfigurationRequest request = PutBucketProtectionConfigurationRequest.builder()
.bucket(bucketName)
.protectionConfiguration(protectionConfig)
.build();
cosClient.putBucketProtectionConfiguration(request);
System.out.println("Protection configuration added!");
}
获取水桶的保护配置
public static void getProtectionConfigurationOnBucket(String bucketName, S3Client cosClient) {
System.out.println("Retrieving protection configuration for bucket: " + bucketName);
GetBucketProtectionConfigurationRequest request = GetBucketProtectionConfigurationRequest.builder()
.bucket(bucketName)
.build();
GetBucketProtectionConfigurationResponse response = cosClient.getBucketProtectionConfiguration(request);
System.out.println("Status: " + response.status());
System.out.println("Minimum Retention (days): " + response.minimumRetention().days());
System.out.println("Default Retention (days): " + response.defaultRetention().days());
System.out.println("Maximum Retention (days): " + response.maximumRetention().days());
}
上传带保留功能的受保护对象
受保护存储桶中不再保留的对象(保留期已过,且对象没有任何合法保留),在被覆盖后将再次被保留。 可以在对象覆盖请求中提供新的保留期,否则会为对象提供存储区的缺省保留时间。
在将对象上传到受保护的存储桶时,可以使用自定义标头指定保留参数:
| 头 | 类型 | 描述 |
|---|---|---|
Retention-Period |
非负整数(秒) | 要在对象上存储的保留期(以秒为单位)。 在保留期中指定的时间长度到期之前,无法覆盖也无法删除对象。 如果指定了该字段和 Retention-Expiration-Date,则会返回 400 错误。 如果这两项均未指定,将使用存储区的 DefaultRetention 时间段。 0 (0) 是一个合法值,前提是数据桶的最短保留时间也是 0。 |
Retention-Expiration-Date |
日期(ISO 8601 格式) | 合法删除或修改对象的日期。 只能指定此项或 Retention-Period 标头。 如果同时指定这两个参数,将返回 400 错误。 如果这两项均未指定,将使用存储区的 DefaultRetention 时间段。 |
Retention-Legal-Hold-Id |
string | 要应用于对象的单个合法保留。 合法保留是一个 Y 字符长字符串。 在除去与对象关联的所有合法保留之前,无法覆盖或删除对象。 |
public static void uploadProtectedObject(String bucketName, String objectKey, String filePath, S3Client cosClient) {
System.out.println("Uploading protected object with retention: " + objectKey);
// Option 1: Upload with retention period (in seconds)
PutObjectRequest requestWithPeriod = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.retentionPeriod(2592000L) // 30 days in seconds
.build();
cosClient.putObject(requestWithPeriod, RequestBody.fromFile(new File(filePath)));
System.out.println("Object uploaded with 30-day retention period");
}
public static void uploadProtectedObjectWithExpirationDate(String bucketName, String objectKey, String filePath, S3Client cosClient) {
System.out.println("Uploading protected object with expiration date: " + objectKey);
// Option 2: Upload with retention expiration date
Instant expirationDate = Instant.now().plus(90, ChronoUnit.DAYS);
PutObjectRequest requestWithDate = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.retentionExpirationDate(expirationDate)
.build();
cosClient.putObject(requestWithDate, RequestBody.fromFile(new File(filePath)));
System.out.println("Object uploaded with expiration date: " + expirationDate);
}
public static void uploadProtectedObjectWithLegalHold(String bucketName, String objectKey, String filePath, String legalHoldId, S3Client cosClient) {
System.out.println("Uploading protected object with legal hold: " + objectKey);
// Option 3: Upload with legal hold
PutObjectRequest requestWithLegalHold = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.retentionLegalHoldId(legalHoldId)
.build();
cosClient.putObject(requestWithLegalHold, RequestBody.fromFile(new File(filePath)));
System.out.println("Object uploaded with legal hold: " + legalHoldId);
}
public static void uploadProtectedObjectWithMultipleRetentionOptions(String bucketName, String objectKey, String filePath, String legalHoldId, S3Client cosClient) {
System.out.println("Uploading protected object with retention period and legal hold: " + objectKey);
// Option 4: Combine retention period with legal hold
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.retentionPeriod(2592000L) // 30 days
.retentionLegalHoldId(legalHoldId)
.build();
cosClient.putObject(request, RequestBody.fromFile(new File(filePath)));
System.out.println("Object uploaded with retention and legal hold");
}
重要说明:
- 不能在同一请求中同时指定
Retention-Period和Retention-Expiration-Date。 - 如果两个保留参数都未指定,则会应用数据桶的默认保留期。
- 法律保留可与保留期相结合。
- 在保留期满和所有法律保留取消之前,不能删除或覆盖保留中或法律保留中的对象。
主要参考资料
为受保护对象添加合法持有
一个对象可以支持 100 个合法保留:
合法持有标识符是一个字符串,最大长度为 64 个字符,最小长度为 1 个字符。 有效字符为字母、数字、!, _, ., *, (, ), - 和 '。 如果添加给定合法保留将导致对象上的合法保留总数超过 100 个,那么不会添加新的合法保留,并且将返回 400 错误。 如果标识符太长,将无法添加到对象中,并返回 400 错误。 如果标识包含无效字符,那么不会将其添加到对象,并且将返回 400 错误。 如果标识已在对象上使用,那么不会修改现有合法保留,响应会指示该标识已在使用,并返回 409 错误。 如果对象没有保留期元数据,那么将返回 400 错误,并且不允许添加或除去合法保留。 保留期头必须存在,否则会返回 400 错误。
添加或除去合法保留的用户必须具有对此存储区的Manager许可权。
public static void addLegalHoldToObject(String bucketName, String objectKey, String legalHoldId, S3Client cosClient) {
System.out.println("Adding legal hold to object: " + objectKey);
AddLegalHoldRequest request = AddLegalHoldRequest.builder()
.bucket(bucketName)
.key(objectKey)
.legalHoldId(legalHoldId)
.build();
cosClient.addLegalHold(request);
System.out.println("Legal hold added!");
}
延长受保护对象的保留期限
对象的保留期只能延长。 不能在当前配置值的基础上缩短。
保留时间延长值可通过以下三种方式之一进行设置:
- 当前值的额外时间 (
additionalRetentionPeriod或类似方法) - 新的延长时间(秒 (
extendRetentionFromCurrentTime或类似方法) - 对象的新保留到期日 (
newRetentionExpirationDate或类似方法)
根据 extendRetention 请求中设置的参数,对象元数据中存储的当前保留期可通过给定额外时间延长,也可替换为新值。 在任何情况下,都会对照当前保留期检查扩展保留参数,只有当更新的保留期大于当前保留期时,才会接受扩展参数。
受保护存储桶中不再保留的对象(保留期已过,且对象没有任何合法保留),在被覆盖后将再次被保留。 可以在对象覆盖请求中提供新的保留期,否则会为对象提供存储区的缺省保留时间。
public static void extendRetentionPeriodOnObject(String bucketName, String objectName, Long additionalSeconds, S3Client cosClient) {
System.out.printf("Extending the retention period on %s in bucket %s by %s seconds.%n", objectName, bucketName, additionalSeconds);
ExtendObjectRetentionRequest request = ExtendObjectRetentionRequest.builder()
.bucket(bucketName)
.key(objectName)
.additionalRetentionPeriod(additionalSeconds)
.build();
cosClient.extendObjectRetention(request);
System.out.printf("Retention period extended on %s by %s seconds%n", objectName, additionalSeconds);
}
主要参考资料
列出受保护对象的合法持有状态
此操作会返回以下内容:
- 对象创建日期
- 对象保留期(秒)
- 根据期限和创建日期计算保留到期日
- 合法保留的列表
- 合法保留标识
- 应用合法保留时的时间戳记
重要说明:
- 如果对象上没有合法持有,则返回空
LegalHoldSet - 如果没有为对象指定保留期,将返回
404错误
public static void listLegalHoldsOnObject(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Listing legal holds for object: " + objectKey);
ListLegalHoldsRequest request = ListLegalHoldsRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
ListLegalHoldsResponse response = cosClient.listLegalHolds(request);
for (LegalHold hold : response.legalHolds()) {
System.out.println("Legal Hold ID: " + hold.id());
System.out.println("Date: " + hold.date());
}
}
删除受保护对象的法律保留
public static void deleteLegalHoldFromObject(String bucketName, String objectKey, String legalHoldId, S3Client cosClient) {
System.out.println("Deleting legal hold from object: " + objectKey);
DeleteLegalHoldRequest request = DeleteLegalHoldRequest.builder()
.bucket(bucketName)
.key(objectKey)
.legalHoldId(legalHoldId)
.build();
cosClient.deleteLegalHold(request);
System.out.println("Legal hold deleted!");
}
主要参考资料
使用 Key Protect
可以将 Key Protect 添加到存储区,以对云中的敏感数据进行静态加密。
用 Key Protect
public static void createBucketWithKeyProtect(String bucketName, String kpRootKeyCrn, S3Client cosClient) {
System.out.println("Creating bucket with Key Protect: " + bucketName);
CreateBucketRequest request = CreateBucketRequest.builder()
.bucket(bucketName)
.ibmSSEKPEncryptionAlgorithm("AES256")
.ibmSSEKPCustomerRootKeyCrn(kpRootKeyCrn)
.build();
cosClient.createBucket(request);
System.out.println("Bucket created with Key Protect encryption!");
}
将对象上传到启用了 Key Protect 的邮筒
public static void putObjectToKPBucket(String bucketName, String objectKey, String filePath, S3Client cosClient) {
System.out.println("Uploading object to Key Protect enabled bucket");
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
cosClient.putObject(request, RequestBody.fromFile(new File(filePath)));
System.out.println("Object uploaded with Key Protect encryption!");
}
使用传输管理器上传更大的对象
传输管理器提供了一个简单的应用程序接口,用于向 IBM Cloud Object Storage 上传和下载对象。
import com.ibm.cos.v2.transfer.s3.S3TransferManager;
import com.ibm.cos.v2.transfer.s3.model.*;
public static void uploadWithTransferManager(String bucketName, String objectKey, String filePath, S3Client cosClient) {
System.out.println("Uploading with Transfer Manager: " + objectKey);
// Create Transfer Manager
S3TransferManager transferManager = S3TransferManager.builder()
.s3Client(cosClient)
.build();
try {
// Upload file
UploadFileRequest uploadRequest = UploadFileRequest.builder()
.putObjectRequest(req -> req.bucket(bucketName).key(objectKey))
.source(Paths.get(filePath))
.build();
FileUpload upload = transferManager.uploadFile(uploadRequest);
// Wait for upload to complete
CompletedFileUpload completedUpload = upload.completionFuture().join();
System.out.println("Upload completed: " + completedUpload.response().eTag());
} finally {
transferManager.close();
}
}
主要参考资料
更新元数据
更新现有对象的元数据
public static void updateObjectMetadata(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Updating metadata for object: " + objectKey);
// Create new metadata
Map<String, String> newMetadata = new HashMap<>();
newMetadata.put("updated-by", "admin");
newMetadata.put("update-date", LocalDate.now().toString());
// Copy object to itself with new metadata
CopyObjectRequest request = CopyObjectRequest.builder()
.sourceBucket(bucketName)
.sourceKey(objectKey)
.destinationBucket(bucketName)
.destinationKey(objectKey)
.metadata(newMetadata)
.metadataDirective(MetadataDirective.REPLACE)
.build();
cosClient.copyObject(request);
System.out.println("Metadata updated!");
}
主要参考资料
使用 Aspera 高速传输
Aspera 高速传输集成可通过 IBM Aspera SDK 实现。 有关与 IBM Cloud Object Storage 集成的详细信息,请参阅 Aspera 文档。
对于 Java 应用程序,您可以将 Aspera Transfer SDK 与 IBM Cloud Object Storage SDK v2 并用,以实现大文件的高速传输。
使用对象锁定
对象锁允许你使用“一次写入-多次读取”(WORM)模式来存储对象。 对象锁可在一定时间内或无限期防止对象被删除或覆盖。
创建启用对象锁的水桶
对象锁定必须在创建数据桶时启用,并且不能添加到现有的数据桶中。
public static void createBucketWithObjectLock(String bucketName, S3Client cosClient) {
System.out.println("Creating bucket with Object Lock: " + bucketName);
CreateBucketRequest request = CreateBucketRequest.builder()
.bucket(bucketName)
.objectLockEnabledForBucket(true)
.build();
cosClient.createBucket(request);
System.out.println("Bucket created with Object Lock enabled!");
}
设置对象锁定保留
您可以设置对象的保留时间,以防止其被删除或覆盖。 有两种保留模式可供选择:
- 符合性:任何用户(包括 root 用户)都不能覆盖或删除对象。
- 管理:拥有特殊权限的用户可以更改保留设置或删除对象。
public static void putObjectRetention(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Setting object retention for: " + objectKey);
// Create retention period of 90 days
Instant retainUntil = Instant.now().plus(90, ChronoUnit.DAYS);
// Create object lock retention with COMPLIANCE mode
ObjectLockRetention retention = ObjectLockRetention.builder()
.mode(ObjectLockRetentionMode.COMPLIANCE)
.retainUntilDate(retainUntil)
.build();
// Apply retention to object
PutObjectRetentionRequest request = PutObjectRetentionRequest.builder()
.bucket(bucketName)
.key(objectKey)
.retention(retention)
.build();
cosClient.putObjectRetention(request);
System.out.println("Object retention set until: " + retainUntil);
}
获取对象锁保留信息
public static void getObjectRetention(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Getting object retention for: " + objectKey);
GetObjectRetentionRequest request = GetObjectRetentionRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
GetObjectRetentionResponse response = cosClient.getObjectRetention(request);
System.out.println("Retention Mode: " + response.retention().mode());
System.out.println("Retain Until: " + response.retention().retainUntilDate());
}
设置对象锁定合法保持
法律保留提供的保护与保留期相同,但没有终止日期。 法律保留在明确取消之前一直有效。
public static void putObjectLegalHold(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Setting legal hold on: " + objectKey);
ObjectLockLegalHold legalHold = ObjectLockLegalHold.builder()
.status(ObjectLockLegalHoldStatus.ON)
.build();
PutObjectLegalHoldRequest request = PutObjectLegalHoldRequest.builder()
.bucket(bucketName)
.key(objectKey)
.legalHold(legalHold)
.build();
cosClient.putObjectLegalHold(request);
System.out.println("Legal hold applied!");
}
获取对象锁的合法保留状态
public static void getObjectLegalHold(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Getting legal hold status for: " + objectKey);
GetObjectLegalHoldRequest request = GetObjectLegalHoldRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
GetObjectLegalHoldResponse response = cosClient.getObjectLegalHold(request);
System.out.println("Legal Hold Status: " + response.legalHold().status());
}
主要参考资料
使用水桶生命周期配置
生命周期配置可让您定义 IBM Cloud Object Storage 适用于一组对象的操作。 您可以使用生命周期策略将对象过渡到不同的存储类别,或在指定时间段后使对象过期。
在水桶上设置生命周期配置
public static void putBucketLifecycle(String bucketName, S3Client cosClient) {
System.out.println("Setting lifecycle configuration on bucket: " + bucketName);
// Create a transition to move objects to GLACIER after 30 days
Transition transition = Transition.builder()
.days(30)
.storageClass(StorageClass.GLACIER)
.build();
// Create lifecycle rule filter
LifecycleRuleFilter ruleFilter = LifecycleRuleFilter.builder()
.prefix("archive/") // Apply to objects with this prefix
.build();
// Create lifecycle rule
LifecycleRule rule = LifecycleRule.builder()
.id("archive-old-objects")
.filter(ruleFilter)
.transitions(transition)
.status(ExpirationStatus.ENABLED)
.build();
// Create lifecycle configuration
BucketLifecycleConfiguration lifecycleConfig = BucketLifecycleConfiguration.builder()
.rules(rule)
.build();
// Apply lifecycle configuration to bucket
PutBucketLifecycleConfigurationRequest request = PutBucketLifecycleConfigurationRequest.builder()
.bucket(bucketName)
.lifecycleConfiguration(lifecycleConfig)
.build();
cosClient.putBucketLifecycleConfiguration(request);
System.out.println("Lifecycle configuration applied!");
}
获取水桶的生命周期配置
public static void getBucketLifecycle(String bucketName, S3Client cosClient) {
System.out.println("Getting lifecycle configuration for bucket: " + bucketName);
GetBucketLifecycleConfigurationRequest request = GetBucketLifecycleConfigurationRequest.builder()
.bucket(bucketName)
.build();
GetBucketLifecycleConfigurationResponse response = cosClient.getBucketLifecycleConfiguration(request);
System.out.println("Found " + response.rules().size() + " lifecycle rules:");
for (LifecycleRule rule : response.rules()) {
System.out.println(" Rule ID: " + rule.id());
System.out.println(" Status: " + rule.status());
if (rule.hasTransitions()) {
for (Transition t : rule.transitions()) {
System.out.println(" Transition after " + t.days() + " days to " + t.storageClass());
}
}
}
}
删除水桶的生命周期配置
public static void deleteBucketLifecycle(String bucketName, S3Client cosClient) {
System.out.println("Deleting lifecycle configuration from bucket: " + bucketName);
DeleteBucketLifecycleRequest request = DeleteBucketLifecycleRequest.builder()
.bucket(bucketName)
.build();
cosClient.deleteBucketLifecycle(request);
System.out.println("Lifecycle configuration deleted!");
}
主要参考资料
使用水桶版本控制
版本管理可让你在同一个数据桶中保存一个对象的多个版本。 这可以帮助您从意外的用户操作和应用程序故障中恢复。
在水桶上启用版本控制
public static void enableBucketVersioning(String bucketName, S3Client cosClient) {
System.out.println("Enabling versioning on bucket: " + bucketName);
VersioningConfiguration versioningConfig = VersioningConfiguration.builder()
.status(BucketVersioningStatus.ENABLED)
.build();
PutBucketVersioningRequest request = PutBucketVersioningRequest.builder()
.bucket(bucketName)
.versioningConfiguration(versioningConfig)
.build();
cosClient.putBucketVersioning(request);
System.out.println("Versioning enabled!");
}
获取水桶版本状态
public static void getBucketVersioning(String bucketName, S3Client cosClient) {
System.out.println("Getting versioning status for bucket: " + bucketName);
GetBucketVersioningRequest request = GetBucketVersioningRequest.builder()
.bucket(bucketName)
.build();
GetBucketVersioningResponse response = cosClient.getBucketVersioning(request);
System.out.println("Versioning Status: " + response.status());
}
列出对象版本
public static void listObjectVersions(String bucketName, S3Client cosClient) {
System.out.println("Listing object versions in bucket: " + bucketName);
ListObjectVersionsRequest request = ListObjectVersionsRequest.builder()
.bucket(bucketName)
.build();
ListObjectVersionsResponse response = cosClient.listObjectVersions(request);
System.out.println("Versions:");
for (ObjectVersion version : response.versions()) {
System.out.println(" Key: " + version.key());
System.out.println(" Version ID: " + version.versionId());
System.out.println(" Is Latest: " + version.isLatest());
System.out.println(" Last Modified: " + version.lastModified());
System.out.println();
}
}
删除特定对象版本
public static void deleteObjectVersion(String bucketName, String objectKey, String versionId, S3Client cosClient) {
System.out.println("Deleting version " + versionId + " of object: " + objectKey);
DeleteObjectRequest request = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.versionId(versionId)
.build();
cosClient.deleteObject(request);
System.out.println("Object version deleted!");
}
主要参考资料
- VersioningConfiguration.Builder
- PutBucketVersioningRequest.Builder
- ListObjectVersionsRequest.Builder
使用扩展水桶列表
IBM Cloud Object Storage 提供了一个扩展的列表 API,可返回有关存储桶的其他元数据,包括位置和存储类别信息。
public static void listBucketsExtended(S3Client cosClient) {
System.out.println("Listing buckets with extended information:");
ListBucketsExtendedRequest request = ListBucketsExtendedRequest.builder().build();
ListBucketsExtendedResponse response = cosClient.listBucketsExtended(request);
for (Bucket bucket : response.buckets()) {
System.out.println("Bucket Name: " + bucket.name());
System.out.println(" Creation Date: " + bucket.creationDate());
// Extended metadata (IBM-specific)
if (bucket.locationConstraint() != null) {
System.out.println(" Location: " + bucket.locationConstraint());
}
}
}
主要参考资料
使用存档层和对象还原
IBM Cloud Object Storage 提供归档存储类(Glacier),以较低的成本实现长期数据保留。 必须先恢复存档存储中的对象,然后才能访问它们。
将对象过渡到存档存储
您可以使用生命周期策略,在指定时间段后自动将对象过渡到存档存储。
public static void setArchiveRule(String bucketName, S3Client cosClient) {
System.out.println("Setting archive rule on bucket: " + bucketName);
// Create transition to Glacier after 30 days
Transition transition = Transition.builder()
.days(30)
.storageClass(StorageClass.GLACIER)
.build();
// Create lifecycle rule
LifecycleRuleFilter filter = LifecycleRuleFilter.builder()
.prefix("archive/")
.build();
LifecycleRule rule = LifecycleRule.builder()
.id("archive-rule")
.filter(filter)
.transitions(transition)
.status(ExpirationStatus.ENABLED)
.build();
// Apply lifecycle configuration
BucketLifecycleConfiguration config = BucketLifecycleConfiguration.builder()
.rules(rule)
.build();
PutBucketLifecycleConfigurationRequest request = PutBucketLifecycleConfigurationRequest.builder()
.bucket(bucketName)
.lifecycleConfiguration(config)
.build();
cosClient.putBucketLifecycleConfiguration(request);
System.out.println("Archive rule configured!");
}
恢复存档对象
必须先还原存档存储中的对象,然后才能下载。 您可以指定已还原副本的可用天数。
public static void restoreArchivedObject(String bucketName, String objectKey, int days, S3Client cosClient) {
System.out.println("Restoring archived object: " + objectKey);
// Create restore request with duration
RestoreRequest restoreRequest = RestoreRequest.builder()
.days(days)
.glacierJobParameters(GlacierJobParameters.builder()
.tier(Tier.STANDARD) // Options: STANDARD (12 hours), EXPEDITED (2 hours), BULK (5-12 hours)
.build())
.build();
RestoreObjectRequest request = RestoreObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.restoreRequest(restoreRequest)
.build();
cosClient.restoreObject(request);
System.out.println("Restore initiated. Object will be available for " + days + " days once restored.");
}
检查恢复状态
public static void checkRestoreStatus(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Checking restore status for: " + objectKey);
HeadObjectRequest request = HeadObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
HeadObjectResponse response = cosClient.headObject(request);
if (response.restore() != null) {
System.out.println("Restore Status: " + response.restore());
// Parse restore status
String restoreStatus = response.restore();
if (restoreStatus.contains("ongoing-request=\"true\"")) {
System.out.println("Restoration in progress...");
} else if (restoreStatus.contains("ongoing-request=\"false\"")) {
System.out.println("Object has been restored and is available for download");
}
} else {
System.out.println("Object is not archived or no restore in progress");
}
}
加速档案检索
IBM Cloud Object Storage 支持加速存档检索,以更快地访问存档数据:
- 加急:2 小时检索时间
- 标准:3-5 小时检索时间(默认值)
- 散装:5-12 小时检索时间(成本最低)
public static void restoreWithExpeditedRetrieval(String bucketName, String objectKey, S3Client cosClient) {
System.out.println("Restoring with expedited retrieval: " + objectKey);
RestoreRequest restoreRequest = RestoreRequest.builder()
.days(1)
.glacierJobParameters(GlacierJobParameters.builder()
.tier(Tier.EXPEDITED) // 2-hour retrieval
.build())
.build();
RestoreObjectRequest request = RestoreObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.restoreRequest(restoreRequest)
.build();
cosClient.restoreObject(request);
System.out.println("Expedited restore initiated (2-hour retrieval)");
}
主要参考资料
使用 CORS (跨源资源共享)
CORS 配置允许在一个域中运行的网络应用程序从另一个域访问 IBM Cloud Object Storage 中的资源。
在水桶上设置 CORS 配置
public static void setCorsConfiguration(String bucketName, S3Client cosClient) {
System.out.println("Setting CORS configuration on bucket: " + bucketName);
// Create CORS rule
CORSRule corsRule = CORSRule.builder()
.allowedMethods("GET", "PUT", "POST", "DELETE")
.allowedOrigins("https://example.com")
.allowedHeaders("*")
.maxAgeSeconds(3000)
.exposeHeaders("ETag", "x-amz-request-id")
.build();
// Create CORS configuration
CORSConfiguration corsConfig = CORSConfiguration.builder()
.corsRules(corsRule)
.build();
PutBucketCorsRequest request = PutBucketCorsRequest.builder()
.bucket(bucketName)
.corsConfiguration(corsConfig)
.build();
cosClient.putBucketCors(request);
System.out.println("CORS configuration applied!");
}
获取 CORS 配置
public static void getCorsConfiguration(String bucketName, S3Client cosClient) {
System.out.println("Getting CORS configuration for bucket: " + bucketName);
GetBucketCorsRequest request = GetBucketCorsRequest.builder()
.bucket(bucketName)
.build();
GetBucketCorsResponse response = cosClient.getBucketCors(request);
System.out.println("CORS Rules:");
for (CORSRule rule : response.corsRules()) {
System.out.println(" Allowed Methods: " + rule.allowedMethods());
System.out.println(" Allowed Origins: " + rule.allowedOrigins());
System.out.println(" Allowed Headers: " + rule.allowedHeaders());
System.out.println(" Max Age: " + rule.maxAgeSeconds());
}
}
删除 CORS 配置
public static void deleteCorsConfiguration(String bucketName, S3Client cosClient) {
System.out.println("Deleting CORS configuration from bucket: " + bucketName);
DeleteBucketCorsRequest request = DeleteBucketCorsRequest.builder()
.bucket(bucketName)
.build();
cosClient.deleteBucketCors(request);
System.out.println("CORS configuration deleted!");
}
主要参考资料
使用水桶策略
存储桶策略为存储桶和对象提供访问控制管理。 它们以 JSON 格式编写,可以授予或拒绝授予用户和服务权限。
设置水桶政策
public static void setBucketPolicy(String bucketName, S3Client cosClient) {
System.out.println("Setting bucket policy on: " + bucketName);
// Create policy document (JSON format)
String policyText = "{"
+ "\"Version\": \"2012-10-17\","
+ "\"Statement\": [{"
+ " \"Effect\": \"Allow\","
+ " \"Principal\": {\"AWS\": \"*\"},"
+ " \"Action\": \"s3:GetObject\","
+ " \"Resource\": \"arn:aws:s3:::" + bucketName + "/*\""
+ "}]"
+ "}";
PutBucketPolicyRequest request = PutBucketPolicyRequest.builder()
.bucket(bucketName)
.policy(policyText)
.build();
cosClient.putBucketPolicy(request);
System.out.println("Bucket policy applied!");
}
获取水桶政策
public static void getBucketPolicy(String bucketName, S3Client cosClient) {
System.out.println("Getting bucket policy for: " + bucketName);
GetBucketPolicyRequest request = GetBucketPolicyRequest.builder()
.bucket(bucketName)
.build();
GetBucketPolicyResponse response = cosClient.getBucketPolicy(request);
System.out.println("Policy: " + response.policy());
}
删除水桶策略
public static void deleteBucketPolicy(String bucketName, S3Client cosClient) {
System.out.println("Deleting bucket policy from: " + bucketName);
DeleteBucketPolicyRequest request = DeleteBucketPolicyRequest.builder()
.bucket(bucketName)
.build();
cosClient.deleteBucketPolicy(request);
System.out.println("Bucket policy deleted!");
}
主要参考资料
创建托管静态网站
IBM Cloud Object Storage 支持直接从桶托管静态网站。 您可以通过指定索引文档和错误文档来配置水桶,以便为静态内容提供服务。
该操作需要以下导入语句:
import com.ibm.cos.v2.services.s3.model.BucketWebsiteConfiguration;
设置水桶网站配置
此操作在配置后可提供以下功能,并需要正确配置的客户端:
- 后缀桶配置 (索引文件)
- 密钥桶配置 (错误文件)
public static void setBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
System.out.println("Setting website configuration for bucket: " + bucketName);
// Create website configuration with index and error documents
IndexDocument indexDocument = IndexDocument.builder()
.suffix("index.html")
.build();
ErrorDocument errorDocument = ErrorDocument.builder()
.key("error.html")
.build();
WebsiteConfiguration websiteConfig = WebsiteConfiguration.builder()
.indexDocument(indexDocument)
.errorDocument(errorDocument)
.build();
PutBucketWebsiteRequest request = PutBucketWebsiteRequest.builder()
.bucket(bucketName)
.websiteConfiguration(websiteConfig)
.build();
cosClient.putBucketWebsite(request);
System.out.println("Website configuration set successfully!");
}
获取水桶网站配置
public static void getBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
System.out.println("Getting website configuration for bucket: " + bucketName);
GetBucketWebsiteRequest request = GetBucketWebsiteRequest.builder()
.bucket(bucketName)
.build();
GetBucketWebsiteResponse response = cosClient.getBucketWebsite(request);
System.out.println("Index Document: " + response.indexDocument().suffix());
System.out.println("Error Document: " + response.errorDocument().key());
}
删除水桶网站配置
public static void deleteBucketWebsiteConfiguration(String bucketName, S3Client cosClient) {
System.out.println("Deleting website configuration from bucket: " + bucketName);
DeleteBucketWebsiteRequest request = DeleteBucketWebsiteRequest.builder()
.bucket(bucketName)
.build();
cosClient.deleteBucketWebsite(request);
System.out.println("Website configuration deleted!");
}
主要参考资料
错误处理和最佳做法
处理 SDK 异常
v2 SDK 针对不同的错误情况使用特定的异常类型。
import com.ibm.cos.v2.services.s3.model.S3Exception;
import com.ibm.cos.v2.services.s3.model.NoSuchBucketException;
import com.ibm.cos.v2.services.s3.model.NoSuchKeyException;
public static void handleExceptions(String bucketName, String objectKey, S3Client cosClient) {
try {
GetObjectRequest request = GetObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
cosClient.getObject(request, ResponseTransformer.toBytes());
} catch (NoSuchBucketException e) {
System.err.println("Bucket does not exist: " + bucketName);
System.err.println("Error Code: " + e.awsErrorDetails().errorCode());
} catch (NoSuchKeyException e) {
System.err.println("Object does not exist: " + objectKey);
System.err.println("Error Code: " + e.awsErrorDetails().errorCode());
} catch (S3Exception e) {
System.err.println("S3 Error: " + e.awsErrorDetails().errorMessage());
System.err.println("Error Code: " + e.awsErrorDetails().errorCode());
System.err.println("Status Code: " + e.statusCode());
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
}
}
v2 SDK 的最佳实践
- 重复使用 S3Client 实例:创建客户端的成本很高。 在不同请求中重复使用它们。
// Good: Create once, reuse
S3Client client = S3Client.builder()
.endpointOverride(URI.create(endpoint))
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.region(Region.of(region))
.build();
// Use client for multiple operations
client.listBuckets();
client.putObject(...);
client.getObject(...);
// Close when done
client.close();
- 使用资源尝试:确保适当的资源清理。
try (S3Client client = S3Client.builder()
.endpointOverride(URI.create(endpoint))
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.region(Region.of(region))
.build()) {
// Perform operations
client.listBuckets();
} // Client automatically closed
-
使用多部分上传处理大文件:对于超过 5 MB 的文件,请使用多部分上传。
-
使用传输管理器进行大型传输:提供自动多部分上传、重试逻辑和进度跟踪功能。
-
设置适当的超时:根据使用情况配置客户端超时。
S3Client client = S3Client.builder()
.endpointOverride(URI.create(endpoint))
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.region(Region.of(region))
.overrideConfiguration(ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.ofMinutes(5))
.apiCallAttemptTimeout(Duration.ofMinutes(2))
.build())
.build();
主要参考资料
其他资源
获取帮助
- 在 Stack Overflow 上提问,标签为
ibm和object-storage - 向 IBM Cloud 支持中心 发送支持邮件
- 在 GitHub Issues 上报告错误或申请功能
本文档提供了 IBM Cloud Object Storage Java SDK v2 的结构和 SDK 参考资料。 有关所有操作的完整工作代码示例,请参阅 GitHub 资源库中的 示例目录 和 迁移指南。