AWS SDK for Java 2.x를 사용하여 페이지 매김된 결과 작업 - AWS SDK for Java 2.x

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

AWS SDK for Java 2.x를 사용하여 페이지 매김된 결과 작업

응답 객체가 너무 커서 단일 응답으로 반환할 수 없는 경우 많은 AWS 작업에서 페이지가 매겨진 결과를 반환합니다. AWS SDK for Java 1.0의 응답에는 다음 결과 페이지를 검색하는 데 사용하는 토큰이 포함되어 있습니다. 반면 AWS SDK for Java 2.x에는 자동 페이지 매김 메서드가 있어 여러 서비스를 호출하여 다음 결과 페이지를 자동으로 불러옵니다. 결과를 처리할 코드를 작성하기만 하면 됩니다. 자동 페이지 매김은 동기 클라이언트와 비동기 클라이언트 모두에서 사용할 수 있습니다.

동기식 페이지 매김

다음 예제에서는 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()));

전체 예제를 참조하십시오. GitHub

객체 반복

다음은 응답 페이지 대신 응답에서 반환된 객체에 대해 반복하는 방법을 설명한 예입니다. 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()));

에서 전체 예제를 참조하십시오 GitHub.

for-each 루프를 사용

SdkIterableIterable 인터페이스를 확장하므로 내용을 Iterable과 같이 처리할 수 있습니다. 다음 코드 조각은 표준 for-each 루프를 사용하여 응답 내용을 반복합니다.

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

에서 전체 예제를 참조하십시오 GitHub.

수동 페이지 매김

사용 사례에 따라 필요한 경우 수동 페이지 매김을 사용할 수도 있습니다. 후속 요청에 응답 객체의 다음 토큰을 사용합니다. 다음 예에는 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.

비동기 페이지 매김

다음 예제는 테이블을 나열하는 비동기 페이지 매김 방법을 보여줍니다. DynamoDB

테이블 이름 페이지 반복

다음 두 예제는 비동기 DynamoDB 클라이언트를 사용합니다. 이 클라이언트는 비동기 DynamoDB 클라이언트를 사용하여 메서드를 호출하고 listTablesPaginator a를 가져오도록 요청합니다. 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. } });

전체 예제는 에서 확인하세요. GitHub

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

에서 전체 예제를 참조하십시오 GitHub.

테이블 이름 반복

다음은 응답 페이지 대신 응답에서 반환된 객체에 대해 반복하는 방법을 설명한 예입니다. 이전에 해당 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() { } });

에서 전체 예제를 참조하십시오 GitHub.

Consumer 사용

다음 예제는 SdkPublishersubscribe 메서드를 사용해 Consumer로 각 항목을 처리합니다.

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

에서 전체 예제를 참조하십시오 GitHub.

타사 라이브러리 사용

사용자 지정 구독자를 구현하는 대신 타사 라이브러리를 사용할 수 있습니다. 이 RxJava 예제에서는 의 사용을 보여 주지만 반응형 스트림 인터페이스를 구현하는 모든 라이브러리를 사용할 수 있습니다. 해당 라이브러리에 GitHub 대한 자세한 내용은 의 RxJava Wiki 페이지를 참조하십시오.

라이브러리를 사용하려면 종속성으로 추가합니다. 이 예에서는 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);

에서 전체 예제를 참조하십시오. GitHub