Java Awssdk S3 Liệt kê các đối tượng trong S3 Bucket
Trong bài viết này tôi sẽ hướng dẫn bạn sử dụng Java S3Client để liệt kê các đối tượng trên một S3 Bucket. Cụ thể chúng ta sẽ tập trung vào việc sử dụng các phương thức listObjectsV2 và listObjectsV2Paginator, đây là các phương thức mới và tốt hơn so với sử dụng phương thức listObject.
Ngoài ra bạn cũng có thể lấy được các thông tin cơ bản trên mỗi đối tượng mà bạn đã liệt kê, chúng bao gồm:
- Kích thước file
- Chủ sở hữu của đối tượng
- Ngày sửa đổi cuối cùng.
- ...
Trước hết chúng ta tạo lớp MyUtils với phương thức tiện ích để tạo ra đối tượng S3Client, nó được sử dụng trong các ví dụ của bài viết này.
MyUtils.java
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
public class MyUtils {
public static S3Client createS3Client(Region region) {
AwsCredentials credentials = AwsBasicCredentials.create("accessKeyId", "secretAccessKey");
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(credentials);
S3Client client = S3Client.builder() //
.credentialsProvider(credentialsProvider) //
.region(region) //
.build();
return client;
}
}
Để tạo đối tượng S3Client bạn cần phải tạo một đối tượng AwsCredentialsProvider, đối tượng này cung cấp thông tin xác thực (Credentials) cho phép bạn tương tác với AWS. Xem thêm bài viết dưới đây để tạo một AwsCredentialsProvider phù hợp với mục đích sử dụng của bạn.
1. Thư viện
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/s3 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.21.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/s3-transfer-manager -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3-transfer-manager</artifactId>
<version>2.21.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk.crt/aws-crt -->
<dependency>
<groupId>software.amazon.awssdk.crt</groupId>
<artifactId>aws-crt</artifactId>
<version>0.28.0</version>
</dependency>
<!-- Log Library -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- Log Library -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
</dependency>
2. Liệt kê các đối tượng với nextContinuationToken
Theo thiết kế, mỗi yêu cầu của người dùng gửi tới S3 Service chỉ nhận được tối đa 1000 đối tượng. Vì vậy nếu bạn muốn lấy danh sách tất cả các đối tượng trên một Bucket bạn phải gửi nhiều yêu cầu (request). Mỗi yêu cầu bạn sẽ nhận được phản hồi bao gồm một danh sách con các đối tượng và một nextContinuationToken để tạo ra một yêu cầu tiếp theo cho danh sách con tiếp theo. Cách này có vẻ hơi thủ công, hãy xem ví dụ đầy đủ:
ListObjectV2TokenExample.java
package org.o7planning.java_14211_awssdk_s3;
import java.util.List;
import org.o7planning.awssdks3.utils.MyUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Object;
public class ListObjectV2TokenExample {
private static Region myRegion = Region.EU_CENTRAL_1;
private static String myBucket = "test1.o7planning.org"; // Change to your bucket name
private static final int MAX_KEYS_PER_REQUEST = 10;
private static void listAllObjectsInBucket(S3Client s3Client, String bucketName) {
String nextContinuationToken = null;
int requestNo = 0;
do {
requestNo++;
ListObjectsV2Request.Builder requestBuilder = ListObjectsV2Request.builder() //
.bucket(bucketName) //
.maxKeys(MAX_KEYS_PER_REQUEST) // Optional (Default 1000).
.continuationToken(nextContinuationToken);
ListObjectsV2Response response = s3Client.listObjectsV2(requestBuilder.build());
List<S3Object> s3Objects = response.contents();
nextContinuationToken = response.nextContinuationToken();
System.out.println("Request " + requestNo + " returns " + s3Objects.size() + " keys");
System.out.println(" - nextContinuationToken: " + nextContinuationToken);
} while (nextContinuationToken != null);
}
public static void main(String[] args) {
S3Client s3Client = MyUtils.createS3Client(myRegion);
try {
listAllObjectsInBucket(s3Client, myBucket);
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
e.printStackTrace();
System.exit(1);
}
}
}
Output:
Request 1 returns 10 keys
- nextContinuationToken: 1qVzSfeqc5jfInTSOGJoqaWoKqXcwgEdI2u+SuejyNNhjqg38Wf8Xhz/edWke6K2N8r21lARSBC0d1FTHzhN88CBU34f/cG2RtN6iPW4Y218=
Request 2 returns 10 keys
- nextContinuationToken: 1uWdHKsz+nTpAXihAPDJJRvXc5lXavGBdd71iEvJVwzQLtcJxu9A/Gh4eWwzbW+/ZphmE6xnNDRSkJPbJpSR1LSWYxR6k2QBe
Request 3 returns 10 keys
- nextContinuationToken: 1s2ypTkPxF9QpwD5t6815Nj+SNJanjsmMBGmQVTvb0thQ4n7+LsmGBAy79tajYSI4YspaQGlbNnlwySwuWxE1ZFRgeWK13vVf
Request 4 returns 10 keys
- nextContinuationToken: 1lX92l0uLSnJs2hed1U35Rf25oorI8qrgyunlUqdDdjnDIzqC1L4EWJbLNrV1aE5FVdyey7CA/Q6O1H3YqQLLT+OPkHO6CRxAkswi7/a+opg=
Request 5 returns 10 keys
- nextContinuationToken: 11pD2mJjgIwgOe1vDSbyitV4soW789+XL90xIr/grScGh3GxE9iSD/UlzXakWgtA2+l67g1WscfcN1WHM6kHoU5LuMAAU42aIjCvr+pJHWcs=
Request 6 returns 10 keys
- nextContinuationToken: 1sqhUsdzV5B4yizBd2SEIdOpnY5NtX+78a5ZRemPMa8gtR6yu1JZhzsIrt0ARsdMY6HzGgoAM4tA=
Request 7 returns 5 keys
- nextContinuationToken: null
3. Liệt kê các đối tượng với ListObjectsV2Iterable
Thay vì sử dụng s3Client.listObjectsV2(request) và nextContinuationToken như ở ví dụ trên, trong ví dụ này chúng ta sử dụng phương thức s3Client.listObjectsV2Paginator(request), đây là cách ngắn gọn và dễ hiểu hơn rất nhiều.
ListObjectsV2Example1.java
package org.o7planning.java_14211_awssdk_s3;
import java.util.Iterator;
import java.util.List;
import org.o7planning.awssdks3.utils.MyUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Object;
import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable;
public class ListObjectsV2Example1 {
private static Region myRegion = Region.EU_CENTRAL_1;
private static String myBucket = "test1.o7planning.org"; // Change to your bucket name
private static final int MAX_KEYS_PER_REQUEST = 10;
private static void listBucketObjects(S3Client s3Client, String bucketName) {
ListObjectsV2Request listV2Request = ListObjectsV2Request.builder() //
.bucket(bucketName) //
.maxKeys(MAX_KEYS_PER_REQUEST) //
.build();
ListObjectsV2Iterable listResponse = s3Client.listObjectsV2Paginator(listV2Request);
Iterator<ListObjectsV2Response> responseIterator = listResponse.iterator();
int requestNo = 0;
while (responseIterator.hasNext()) {
requestNo++;
ListObjectsV2Response response = responseIterator.next();
List<S3Object> s3Objects = response.contents();
System.out.println("Request " + requestNo + " returns " + s3Objects.size() + " keys");
}
}
public static void main(String[] args) {
S3Client s3Client = MyUtils.createS3Client(myRegion);
try {
listBucketObjects(s3Client, myBucket);
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
e.printStackTrace();
System.exit(1);
}
}
}
Output:
Request 1 returns 10 keys
Request 2 returns 10 keys
Request 3 returns 10 keys
Request 4 returns 10 keys
Request 5 returns 10 keys
Request 6 returns 10 keys
Request 7 returns 5 keys
4. Liệt kê các đối tượng theo tiếp đầu ngữ
Trong một số trường hợp bạn chỉ muốn liệt kê các đối tượng với một tiếp đầu ngữ được chỉ định chẳng hạn "static/images/".
ListObjectsV2Request listReq = ListObjectsV2Request.builder() //
.bucket(bucketName) //
.maxKeys(MAX_KEYS_PER_REQUEST) //
.prefix("static/images/") // Key Prefix
.build();
5. Lấy thông tin cơ bản về đối tượng
Ví dụ: Liệt kê các đối tượng trong một S3 Bucket và in ra các thông tin cơ bản của mỗi đối tượng.
- Kích thước file
- Chủ sở hữu của đối tượng
- Ngày sửa đổi cuối cùng.
- ...
ListObjectsV2Example2.java
package org.o7planning.java_14211_awssdk_s3;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.o7planning.awssdks3.utils.MyUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Object;
import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable;
public class ListObjectsV2Example2 {
private static Region myRegion = Region.EU_CENTRAL_1;
private static String myBucket = "test1.o7planning.org"; // Change to your bucket name
private static final int MAX_KEYS_PER_REQUEST = 10;
private static void listBucketObjects(S3Client s3Client, String bucketName) {
ListObjectsV2Request listV2Request = ListObjectsV2Request.builder() //
.bucket(bucketName) //
.maxKeys(MAX_KEYS_PER_REQUEST) //
.build();
ListObjectsV2Iterable listResponse = s3Client.listObjectsV2Paginator(listV2Request);
Iterator<ListObjectsV2Response> responseIterator = listResponse.iterator();
while (responseIterator.hasNext()) {
ListObjectsV2Response response = responseIterator.next();
List<S3Object> s3Objects = response.contents();
//
for (S3Object s3Object : s3Objects) {
System.out.println("\n\nObject Key: " + s3Object.key());
System.out.println("Size: " + toKB(s3Object.size()) + " KB");
System.out.println("Owner: " + s3Object.owner());
//
Instant instant = s3Object.lastModified();
LocalDateTime lastModified = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
System.out.println("Last Modified: " + lastModified);
//
moreInfo(s3Client, bucketName, s3Object.key());
}
}
}
private static void moreInfo(S3Client s3Client, String bucketName, String objectKey) {
HeadObjectRequest headObjectRequest = HeadObjectRequest.builder() //
.bucket(bucketName) //
.key(objectKey) //
.build();
HeadObjectResponse headObjectResponse = s3Client.headObject(headObjectRequest);
//
System.out.println(" - contentType: " + headObjectResponse.contentType());
System.out.println(" - cacheControl: " + headObjectResponse.cacheControl());
System.out.println(" - websiteRedirectLocation: " + headObjectResponse.websiteRedirectLocation());
//
Map<String, String> metadata = headObjectResponse.metadata();
System.out.println(" User Defined Metadata: " + metadata);
for (String metaKey : metadata.keySet()) {
System.out.println(" Metadata " + metaKey + " : " + metadata.get(metaKey));
}
}
// Convert bytes to KB.
private static long toKB(long bytes) {
return bytes / 1024;
}
public static void main(String[] args) {
S3Client s3Client = MyUtils.createS3Client(myRegion);
try {
listBucketObjects(s3Client, myBucket);
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
e.printStackTrace();
System.exit(1);
}
}
}
Output:
Object Key: icons/
Size: 0 KB
Owner: Owner(ID=d3c6d6ab076f6bfb589d38b23110f1890de07fbd613da51c075cc37800fd59d3)
Last Modified: 2023-11-09T17:04:35
- contentType: application/x-directory; charset=UTF-8
- cacheControl: null
- websiteRedirectLocation: null
User Defined Metadata: {}
Object Key: sample.png
Size: 2 KB
Owner: Owner(ID=d3c6d6ab076f6bfb589d38b23110f1890de07fbd613da51c075cc37800fd59d3)
Last Modified: 2023-11-09T18:06:27
- contentType: image/png
- cacheControl: null
- websiteRedirectLocation: null
User Defined Metadata: {my-meta=Some Value}
Metadata my-meta : Some Value
Object Key: static/
Size: 0 KB
Owner: Owner(ID=d3c6d6ab076f6bfb589d38b23110f1890de07fbd613da51c075cc37800fd59d3)
Last Modified: 2023-11-09T17:05:01
- contentType: application/x-directory; charset=UTF-8
- cacheControl: null
- websiteRedirectLocation: null
User Defined Metadata: {}
Object Key: static/icons/close.png
Size: 1 KB
Owner: Owner(ID=d3c6d6ab076f6bfb589d38b23110f1890de07fbd613da51c075cc37800fd59d3)
Last Modified: 2023-11-09T17:05:43
- contentType: image/png
- cacheControl: null
- websiteRedirectLocation: null
User Defined Metadata: {}
- Java Awssdk S3 Object Info
Các hướng dẫn Amazon Web Services
- Giới thiệu về Amazon Web Services (AWS)
- Giới thiệu về Amazon S3
- Giới thiệu về Amazon Cloudfront và kiến trúc của nó
- Làm sao để giảm chi phí Amazon Cloudfront?
- Vô hiệu hoá bộ nhớ đệm CloudFront
- Giới thiệu về DigitalOcean Spaces
- Hướng dẫn tạo DigitalOcean Spaces Bucket
- Giới thiệu về Amazon ACM
- Java Awssdk S3 Tải tệp lên S3 Bucket với S3Client
- Tạo AWS accessKeyId/secretAccessKey
- Java Awssdk S3 Liệt kê các đối tượng trong S3 Bucket
- Lưu trữ (host) một Website tĩnh trên Amazon S3
- Vô hiệu hoá bộ nhớ đệm của CloudFront với Java
- Tạo DigitalOcean Spaces Access Key
- Java Awssdk Các Credentials Provider thông dụng
- Java Awssdk Tạo và sử dụng ProfileCredentialsProvider
- Java Awssdk Tạo và sử dụng EnvironmentVariableCredentialsProvider
- Java Awssdk Tạo và sử dụng SystemPropertyCredentialsProvider
- Java Awssdk S3 Tải object lên với S3TransferManager
- Java Awssdk S3 Tải object xuống với S3TransferManager
- Java thao tác với DigitalOcean Spaces sử dụng S3TransferManager
- Java tạo, liệt kê và xoá S3 Bucket
- Aws Console Tạo tài khoản người dùng IAM
- Tạo một vùng chứa Amazon S3 (S3 Bucket)
- Các quy tắc chuyển hướng cho S3 Static Website
- Cấu hình tên miền tuỳ chỉnh cho website tĩnh Amazon S3
- Tạo bản phân phối CloudFront cho S3 Bucket
- Cấu hình các trang phản hồi lỗi cho CloudFront
- Tạo các chính sách S3 Bucket
- Công cụ tạo các chính sách cho AWS - policygen
- So sánh Amazon S3 Rest API Endpoint và S3 Web Endpoint
- Chuyển hướng trong S3 Website với x-amz-website-redirect-location
- Di chuyển (migrate) dịch vụ DNS tới Amazon Route 53
- Chuyển (transfer) đăng ký tên miền tới Amazon Route 53
- Yêu cầu chứng chỉ SSL từ Amazon ACM
Show More