翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
AWS SDK for Java 2.x を使用してページ分割された結果を処理する
多くの AWS オペレーションは、レスポンスオブジェクトが大きすぎて単一のレスポンスで返せない場合にページ分割された結果を返します。 AWS SDK for Java 1.0 では、レスポンスには結果の次のページを取得するために使用するトークンが含まれています。対照的に、 AWS SDK for Java 2.x には自動ページ分割メソッドがあり、複数のサービス呼び出しを実行して結果の次のページを自動的に取得します。この結果を処理するコードを記述するだけです。自動ページ分割は、同期クライアントと非同期クライアントの両方で使用できます。
注記
これらのコードスニペットは、 の使用の基本SDKを理解し、シングルサインオンアクセス で環境を設定していることを前提としています。
同期ページ割り
次の例は、 Amazon S3 バケット内のオブジェクトを一覧表示する同期ページ分割メソッドを示しています。
ページを反復処理する
最初の例は、 stream
メソッドですべてのレスポンスページを繰り返し実行する、 listRes
パジネーターオブジェクトであるListObjectsV2Iterable
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()));
の完全な例
for-each ループを使用する
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 テーブルを一覧表示する非同期ページ分割方法を示しています。
テーブル名のページを反復処理する
次の 2 つの例では、 を取得するリクエストで listTablesPaginator
メソッドを呼び出す非同期 DynamoDB クライアントを使用しますListTablesPublisher
ListTablesPublisher
を実装し、レスポンスを処理する多くのオプションを提供します。各インターフェースのメソッドを見ていきます。
Subscriber
を使用する
次のコード例は、ListTablesPublisher
で実装された org.reactivestreams.Publisher
インターフェイスを使用してページ分割された結果を処理する方法を示しています。リアクティブストリームモデルの詳細については、「リアクティブストリーム 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
インターフェースには、Consumer
を受け取って CompletableFuture<Void>
を返す subscribe
メソッドがあります。
このインターフェースの subscribe
メソッドは、org.reactivestreams.Subscriber
のオーバーヘッドが大きすぎるような単純なユースケースに使用できます。以下のコードは各ページを使用するため、それぞれの tableNames
メソッドを呼び出します。tableNames
メソッドは、forEach
メソッドで処理される DynamoDB テーブル名 の java.util.List
を返します。
// Use a Consumer for simple use cases. CompletableFuture<Void> future = publisher.subscribe( response -> response.tableNames() .forEach(System.out::println));
の完全な例
テーブル名を反復処理する
次の例では、レスポンスのページではなく、レスポンスで返るオブジェクトを反復処理する方法を示します。前に contents
メソッドで示した同期 Amazon S3 の例と同様、DynamoDB 非同期結果クラス、ListTablesPublisher
には、基になるアイテムコレクションを操作するための tableNames
便利なメソッドがあります。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
を使用する
次の例では、各項目の処理に Consumer
を要する SdkPublisher
の subscribe
メソッドを使用しています。
// Use a Consumer. CompletableFuture<Void> future = publisher.subscribe(System.out::println); future.get();
の完全な例
サードパーティーライブラリを使用する
カスタムの受信者を実装せずに、その他のサードパーティーのライブラリを使用することができます。この例では、 の使用を示していますが RxJava、リアクティブストリームインターフェイスを実装するライブラリを使用することができます。そのライブラリの詳細については、 RxJava の wiki ページ GitHub
このライブラリを使用するには、依存関係として追加します。Maven を使用している場合、この例は使用するPOMスニペットを示しています。
POM エントリ
<dependency> <groupId>io.reactivex.rxjava3</groupId> <artifactId>rxjava</artifactId> <version>3.1.6</version> </dependency>
コード
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);
の完全な例