注意

本文档适用于 Ceph 的开发版本。

Java S3 示例

先决条件

所有示例均基于 AWS Java SDK 2.17.42 编写。使用其他客户端时,您可能需要更改某些代码。

设置

以下示例可能需要导入部分或全部以下 Java 类

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.file.Paths;
import java.util.List;
import java.util.ListIterator;
import java.time.Duration;

import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.Bucket;
import software.amazon.awssdk.services.s3.model.ListBucketsResponse;
import software.amazon.awssdk.services.s3.model.ListObjectsResponse;
import software.amazon.awssdk.services.s3.model.ObjectCannedACL;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Object;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;

如果您只是测试 Ceph 对象存储服务,请考虑使用 HTTP 协议而不是 HTTPS 协议。

首先,导入 AwsBasicCredentialsS3Client 类。

import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.services.s3.S3Client;

然后,使用客户端构建器创建一个 S3 客户端

AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);

S3Client client = S3Client.builder()
        .endpointOverride(new URI("https://endpoint.com"))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .serviceConfiguration(srvcConf -> {
                srvcConf.pathStyleAccessEnabled();
        })
        .region(Region.US_EAST_1) // this is not used, but the AWS SDK requires it
        .build();

列出拥有的存储桶

这会获取您拥有的存储桶列表。它还会打印出每个存储桶的名称和创建日期。

ListBucketsResponse lbResponse = client.listBuckets();
for (Bucket bucket : lbResponse.buckets()) {
        System.out.println(bucket.name() + "\t" + bucket.creationDate());
}

输出将类似于

mahbuckat1    2021-09-20T14:12:57.231Z
mahbuckat2    2021-09-20T14:12:59.402Z
mahbuckat3    2021-09-20T14:13:02.288Z

创建存储桶

这将创建一个名为 my-new-bucket 的新存储桶

client.createBucket(req -> {
        req.bucket("my-new-bucket");
});

列出存储桶的内容

这会获取存储桶中对象的列表。它还会打印出每个对象的名称、文件大小和上次修改日期。

ListObjectsResponse loResponse = client.listObjects(req -> {
        req.bucket("my-bucket");
});

for (S3Object object : loResponse.contents()) {
        System.out.println(
                object.key() + "\t" +
                object.size() + "\t" +
                object.lastModified()
        );
}

输出将类似于

myphoto1.jpg 251262  2021-09-20T17:47:07.317Z
myphoto2.jpg 262518  2021-09-20T17:49:46.872Z

删除存储桶

注意

存储桶必须为空!否则它将无法工作!

client.deleteBucket(req -> {
        req.bucket("my-new-bucket");
});

强制删除非空存储桶

注意

不可用

创建对象

这会创建一个包含字符串 "Hello World!" 的文件 hello.txt

ByteBuffer input = ByteBuffer.wrap("Hello World!".getBytes());
client.putObject(
        req -> {
                req.bucket("my-bucket").key("hello.txt");
        },
        RequestBody.fromByteBuffer(input)
);

更改对象的 ACL

这将使对象 hello.txt 公开可读,并使 secret_plans.txt 保持私有。

client.putObjectAcl(req -> {
        req.bucket("my-bucket").key("hello.txt").acl(ObjectCannedACL.PUBLIC_READ);
});
client.putObjectAcl(req -> {
        req.bucket("my-bucket").key("secret_plans.txt").acl(ObjectCannedACL.PRIVATE);
});

下载对象(到文件)

这会下载对象 perl_poetry.pdf 并将其保存到 /home/larry/documents

client.getObject(
        req -> {
                req.bucket("my-bucket").key("perl_poetry.pdf");
        },
        Paths.get("/home/larry/documents/perl_poetry.pdf")
);

删除对象

这会删除对象 goodbye.txt

client.deleteObject(req -> {
        req.bucket("my-bucket").key("goodbye.txt");
});

生成对象下载 URL(签名和未签名)

这会为 hello.txt 生成一个未签名的下载 URL。这之所以有效,是因为我们通过在上面设置 ACL 使 hello.txt 变为公开。然后,这会为 secret_plans.txt 生成一个签名的下载 URL,该 URL 将在 1 小时内有效。签名的下载 URL 在该时间段内即使对象是私有的也会有效(时间段结束后,URL 将停止工作)。

注意

Java 库没有用于生成未签名 URL 的方法,因此下面的示例只生成签名 URL。

S3Presigner presigner = S3Presigner.builder()
        .endpointOverride(new URI("https://endpoint.com"))
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .region(Region.US_EAST_1) // this is not used, but the AWS SDK requires it
        .build();

PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(preReq -> {
        preReq.getObjectRequest(req -> {
                req.bucket("my-bucket").key("secret_plans.txt");
        }).signatureDuration(
                Duration.ofMinutes(20)
        );
});
System.out.println(presignedRequest.url());

输出将类似于

https://endpoint.com/my-bucket/secret_plans.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210921T151408Z&X-Amz-SignedHeaders=host&X-Amz-Expires=1200&X-Amz-Credential=XXXXXXXXXXXX%2F20210921%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=yyyyyyyyyyyyyyyyyyyyyy

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入