本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 2.x 使用分頁結果 AWS SDK for Java
當響應對象太大而無法在單個響應中返回時,許多 AWS 操作都會返回分頁結果。在 AWS SDK for Java 1.0 中,響應包含一個令牌,用於檢索結果的下一頁。相比之下, AWS SDK for Java 2.x 具有自動分頁方法,可以進行多個服務調用,以自動為您獲取下一頁結果。您只需編寫處理結果的程式碼即可。自動分頁適用於同步和非同步用戶端。
注意
這些程式碼片段假設您瞭解使用 SDK 的基本概念,並且已將環境設定為單一登入存取權。
同步分頁
下列範例示範列出 Amazon S3 值區中物件的同步分頁方法。
迭代頁面
第一個範例示範如何使用 listRes
paginator 物件 (ListObjectsV2Iterable
stream
程式碼會透過回應頁面串流、將回應串流轉換為S3Object
內容串流,然後處理 Amazon S3 物件的內容。
下列匯入適用於此同步分頁區段中的所有範例。
import java.io.IOException; import java.nio.ByteBuffer; import java.util.Random; import software.amazon.awssdk.core.waiters.WaiterResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.ListObjectsV2Request; import software.amazon.awssdk.services.s3.model.ListObjectsV2Response; import software.amazon.awssdk.services.s3.model.S3Object; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.DeleteObjectRequest; import software.amazon.awssdk.services.s3.model.DeleteBucketRequest; import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest; import software.amazon.awssdk.services.s3.model.CreateMultipartUploadResponse; import software.amazon.awssdk.services.s3.model.CompletedMultipartUpload; import software.amazon.awssdk.services.s3.model.CreateBucketRequest; import software.amazon.awssdk.services.s3.model.CompletedPart; import software.amazon.awssdk.services.s3.model.CreateBucketConfiguration; import software.amazon.awssdk.services.s3.model.UploadPartRequest; import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest; import software.amazon.awssdk.services.s3.waiters.S3Waiter; import software.amazon.awssdk.services.s3.model.HeadBucketRequest; import software.amazon.awssdk.services.s3.model.HeadBucketResponse;
ListObjectsV2Request listReq = ListObjectsV2Request.builder() .bucket(bucketName) .maxKeys(1) .build(); ListObjectsV2Iterable listRes = s3.listObjectsV2Paginator(listReq); // Process response pages listRes.stream() .flatMap(r -> r.contents().stream()) .forEach(content -> System.out .println(" Key: " + content.key() + " size = " + content.size()));
請參閱(詳見)的完整實例
迭代對象
以下範例示範如何逐一查看回應傳回的物件,而非回應的頁面。ListObjectsV2Iterable
類的contents
方法返回一個,SdkIterable
使用串流
下列程式碼片段會使用回應內容上的stream
方法來遍歷分頁的項目集合。
// Helper method to work with paginated collection of items directly. listRes.contents().stream() .forEach(content -> System.out .println(" Key: " + content.key() + " size = " + content.size()));
請參閱(詳見)的完整實例
使用每個循環
由於SdkIterable
擴展了Iterable
界面,因此您可以像處理任何內容一樣Iterable
。下面的代碼片段使用標準for-each
循環遍歷響應的內容。
for (S3Object content : listRes.contents()) { System.out.println(" Key: " + content.key() + " size = " + content.size()); }
請參閱(詳見)的完整實例
手動分頁
如果您的使用案例有需要,也可以使用手動分頁。使用回應物件中的下一個符記以進行後續請求。下列範例使用while
迴圈。
ListObjectsV2Request listObjectsReqManual = ListObjectsV2Request.builder() .bucket(bucketName) .maxKeys(1) .build(); boolean done = false; while (!done) { ListObjectsV2Response listObjResponse = s3.listObjectsV2(listObjectsReqManual); for (S3Object content : listObjResponse.contents()) { System.out.println(content.key()); } if (listObjResponse.nextContinuationToken() == null) { done = true; } listObjectsReqManual = listObjectsReqManual.toBuilder() .continuationToken(listObjResponse.nextContinuationToken()) .build(); }
請參閱(詳見)的完整實例
非同步分頁
下面的實例演示了列出 DynamoDB 表的異步分頁方法。
遍歷表名的頁面
下列兩個範例使用非同步 DynamoDB 用戶端,該用戶端會透過要求呼叫listTablesPaginator
方法以取得. ListTablesPublisher
ListTablesPublisher
實現兩個接口,它提供了許多選項來處理響應。我們將看看每個接口的方法。
使用一個 Subscriber
下列程式碼範例示範如何使用實作的org.reactivestreams.Publisher
介面來處理分頁結果。ListTablesPublisher
要了解有關反應流模型的更多信息,請參閱反應流 GitHub 回購
下列匯入適用於此非同步分頁區段中的所有範例。
import io.reactivex.rxjava3.core.Flowable; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import reactor.core.publisher.Flux; import software.amazon.awssdk.core.async.SdkPublisher; import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest; import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; import software.amazon.awssdk.services.dynamodb.paginators.ListTablesPublisher; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException;
下列程式碼會取得ListTablesPublisher
執行個體。
// Creates a default client with credentials and region loaded from the // environment. final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create(); ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build(); ListTablesPublisher publisher = asyncClient.listTablesPaginator(listTablesRequest);
下列程式碼使用的匿名實作org.reactivestreams.Subscriber
來處理每個頁面的結果。
onSubscribe
方法會呼叫 Subscription.request
方法以啟動向發佈者請求資料。必須呼叫這個方法,才能開始從發佈者取得資料。
用戶的onNext
方法通過訪問所有的表名和打印出每一個處理響應頁。處理頁面後,發行者會要求另一個頁面。這種方法被重複調用,直到所有的頁面被檢索。
如果擷取資料時發生錯誤,會觸發 onError
方法。最後,所有頁面都已請求完,會呼叫 onComplete
方法。
// A Subscription represents a one-to-one life-cycle of a Subscriber subscribing // to a Publisher. publisher.subscribe(new Subscriber<ListTablesResponse>() { // Maintain a reference to the subscription object, which is required to request // data from the publisher. private Subscription subscription; @Override public void onSubscribe(Subscription s) { subscription = s; // Request method should be called to demand data. Here we request a single // page. subscription.request(1); } @Override public void onNext(ListTablesResponse response) { response.tableNames().forEach(System.out::println); // After you process the current page, call the request method to signal that // you are ready for next page. subscription.request(1); } @Override public void onError(Throwable t) { // Called when an error has occurred while processing the requests. } @Override public void onComplete() { // This indicates all the results are delivered and there are no more pages // left. } });
請參閱(詳見)的完整實例
使用一個 Consumer
ListTablesPublisher
實現的SdkPublisher
接口具有一個subscribe
方法,該方法需要 a Consumer
並返回一個CompletableFuture<Void>
.
從這個接口的subscribe
方法可以用於簡單的用例,當一個可org.reactivestreams.Subscriber
能是太多的開銷。由於下面的代碼消耗每個頁面,它會在每個頁面上調用該tableNames
方法。此方tableNames
法會傳回使用方法處理java.util.List
的 DynamoDB 資料表名稱。forEach
// Use a Consumer for simple use cases. CompletableFuture<Void> future = publisher.subscribe( response -> response.tableNames() .forEach(System.out::println));
請參閱(詳見)的完整實例
迭代表名
以下範例示範如何逐一查看回應傳回的物件,而非回應的頁面。與先前顯示的同步 Amazon S3 範例類似,DynamoDB 非同步結果類別ListTablesPublisher
具有與基礎項目集合互動的tableNames
便利方法。contents
該tableNames
方法的返回類型是一種SdkPublisher
使用一個 Subscriber
下列程式碼會取SdkPublisher
得資料表名稱的基礎集合。
// Create a default client with credentials and region loaded from the // environment. final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create(); ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build(); ListTablesPublisher listTablesPublisher = asyncClient.listTablesPaginator(listTablesRequest); SdkPublisher<String> publisher = listTablesPublisher.tableNames();
下列程式碼使用的匿名實作org.reactivestreams.Subscriber
來處理每個頁面的結果。
用戶的onNext
方法處理集合的單個元素。在這種情況下,它是一個表名。處理資料表名稱之後,會向發行者要求另一個資料表名稱。這種方法被重複調用,直到所有的表名被檢索。
// Use a Subscriber. publisher.subscribe(new Subscriber<String>() { private Subscription subscription; @Override public void onSubscribe(Subscription s) { subscription = s; subscription.request(1); } @Override public void onNext(String tableName) { System.out.println(tableName); subscription.request(1); } @Override public void onError(Throwable t) { } @Override public void onComplete() { } });
請參閱(詳見)的完整實例
使用一個 Consumer
下面的示例使用的subscribe
方SdkPublisher
法需Consumer
要處理每個項目。
// Use a Consumer. CompletableFuture<Void> future = publisher.subscribe(System.out::println); future.get();
請參閱(詳見)的完整實例
使用第三方程式
您可以使用其他第三方程式庫,而非實作自訂的訂閱者。這個例子演示了如何使用 RxJava,但任何實現反應流接口的庫都可以使用。如需有關該程式庫的 GitHub詳細資訊,請參閱上的 RxJava wiki 頁面
若要使用該程式庫,請將其新增做為相依性。如果使用 Maven,範例會顯示要使用的 POM 片段。
POM 項目
<dependency> <groupId>io.reactivex.rxjava3</groupId> <artifactId>rxjava</artifactId> <version>3.1.6</version> </dependency>
Code
DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create(); ListTablesPublisher publisher = asyncClient.listTablesPaginator(ListTablesRequest.builder() .build()); // The Flowable class has many helper methods that work with // an implementation of an org.reactivestreams.Publisher. List<String> tables = Flowable.fromPublisher(publisher) .flatMapIterable(ListTablesResponse::tableNames) .toList() .blockingGet(); System.out.println(tables);
請參閱(詳見)的完整實例