

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS SDK for Java 2.x でページ分割された結果を使用する
<a name="pagination"></a>

多くの AWS オペレーションは、レスポンスオブジェクトが大きすぎて 1 回のレスポンスで返せない場合に、ページ分割された結果を返します。 AWS SDK for Java 1.0 では、レスポンスには結果の次のページを取得するために使用するトークンが含まれています。対照的に、 AWS SDK for Java 2.x には自動ページ分割メソッドがあり、複数のサービス呼び出しを行って結果の次のページを自動的に取得できます。この結果を処理するコードを記述するだけです。自動ページ分割は、同期クライアントと非同期クライアントの両方で使用できます。

**注記**  
これらのコードスニペットは、ユーザーが [SDK の使用の基本](using.md)を理解し、[シングルサインオンアクセス](get-started-auth.md#setup-credentials)で環境を設定していることを前提としています。

## 同期ページ割り
<a name="synchronous-pagination"></a>

次の例は、 Amazon S3 バケット内のオブジェクトを一覧表示する同期ページ分割メソッドを示しています。

### ページを反復処理する
<a name="iterate-pages"></a>

最初の例は、[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html) インスタンスである `listRes` ページネーターオブジェクトを使用して、`stream` メソッドですべてのレスポンスページをイテレーションする例です。コードはレスポンスページをストリーミングし、レスポンスストリームを`[S3Object](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Object.html)`コンテンツのストリームに変換して、 Amazon S3 オブジェクトのコンテンツを処理します。

以下のインポートは、この同期ページ分割セクションのすべての例に適用されます。

#### インポート
<a name="synchronous-pagination-ex-import"></a>

```
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()));
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L112) で完全な例をご覧ください。

### オブジェクトを反復処理する
<a name="iterate-objects"></a>

次の例では、レスポンスのページではなく、レスポンスで返るオブジェクトを反復処理する方法を示します。`ListObjectsV2Iterable` クラスの `contents` メソッドは、基になるコンテンツ要素を処理する複数のメソッドを提供する [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html) を返します。

#### ストリーミングを使用する
<a name="use-a-stream"></a>

以下のスニペットは、レスポンスコンテンツの `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()));
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L127) で完全な例をご覧ください。

#### for-each ループを使用する
<a name="for-loop"></a>

`SdkIterable` は `Iterable` インターフェースを拡張するので、他の `Iterable` と同じように内容を処理できます。次のスニペットでは、標準の `for-each` ループを使用してレスポンスの内容を反復処理しています。

```
        for (S3Object content : listRes.contents()) {
            System.out.println(" Key: " + content.key() + " size = " + content.size());
        }
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L133) で完全な例をご覧ください。

### 手動のページ割り
<a name="manual-pagination"></a>

手動のページ分割が必要なユースケースでは、従来どおり手動のページ分割を使用できます。それ以降のリクエストについては、応答オブジェクトの次のトークンを使用します。次の例では `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();
        }
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L90) で完全な例をご覧ください。

## 非同期ページ割り
<a name="asynchronous-pagination"></a>

次の例は、 DynamoDB テーブルを一覧表示する非同期ページ分割方法を示しています。

### テーブル名のページを反復処理する
<a name="iterate-pages-async"></a>

次の 2 つの例では、非同期の DynamoDB クライアントを使用して `listTablesPaginator` メソッドを呼び出し、[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html) を取得するリクエストを送信しています。`ListTablesPublisher` には 2 つのインターフェースが実装されており、レスポンスを処理するための多くのオプションが用意されています。各インターフェースのメソッドを見ていきます。

#### `Subscriber` を使用する
<a name="use-a-subscriber"></a>

次のコード例は、`ListTablesPublisher` で実装された `org.reactivestreams.Publisher` インターフェイスを使用してページ分割された結果を処理する方法を示しています。リアクティブなストリームのモデルの詳細については、「[Reactive Streams GitHub repo](https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md)」を参照してください。

以下のインポートは、この非同期ページ分割セクションのすべての例に適用されます。

##### インポート
<a name="use-a-subscriber-ex-imports"></a>

```
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.
            }
        });
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L83) で完全な例をご覧ください。

#### `Consumer` を使用する
<a name="id1pagination"></a>

`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));
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L96) で完全な例をご覧ください。

### テーブル名を反復処理する
<a name="iterate-objects-async"></a>

次の例では、レスポンスのページではなく、レスポンスで返るオブジェクトを反復処理する方法を示します。前に `contents` メソッドで示した同期 Amazon S3 の例と同様、DynamoDB 非同期結果クラス、`ListTablesPublisher` には、基になるアイテムコレクションを操作するための `tableNames` 便利なメソッドがあります。`tableNames` メソッドの戻り型は、すべてのページに項目をリクエストできる [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html) です。

#### `Subscriber` を使用する
<a name="id2"></a>

次のコードは、基になるテーブル名のコレクションの `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() {
            }
        });
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L147) で完全な例をご覧ください。

#### `Consumer` を使用する
<a name="for-loop-async"></a>

次の例では、各項目の処理に `Consumer` を要する `SdkPublisher` の `subscribe` メソッドを使用しています。

```
        // Use a Consumer.
        CompletableFuture<Void> future = publisher.subscribe(System.out::println);
        future.get();
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L161) で完全な例をご覧ください。

### サードパーティーライブラリを使用する
<a name="use-third-party-library"></a>

カスタムの受信者を実装せずに、その他のサードパーティーのライブラリを使用することができます。この例では、RxJava の使用を例に挙げていますが、リアクティブなストリームのインターフェイスを実装するライブラリを使用することもできます。上記ライブラリの詳細については、「[RxJava wiki page on GitHub](https://github.com/ReactiveX/RxJava/wiki)」を参照してください。

このライブラリを使用するには、依存関係として追加します。使用する POM スニペットの例を示します (Maven を使用している場合)。

 **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);
```

[GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L198) で完全な例をご覧ください。