Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Trabaje con resultados paginados mediante la versión 2.x de AWS SDK for Java
Muchas AWS operaciones devuelven resultados paginados cuando el objeto de respuesta es demasiado grande para mostrarlos en una sola respuesta. En la AWS SDK for Java versión 1.0, la respuesta contiene un token que se usa para recuperar la siguiente página de resultados. Por el contrario, la versión AWS SDK for Java 2.x cuenta con métodos de autopaginación que permiten realizar múltiples llamadas de servicio para obtener automáticamente la siguiente página de resultados. Solo tiene que escribir el código que procesa los resultados. La paginación automática está disponible para clientes síncronos y asíncronos.
Paginación síncrona
En los ejemplos siguientes, se muestran métodos de paginación síncrona para obtener una lista de los objetos en un bucket de Amazon S3 .
Iterar sobre páginas
El primer ejemplo demuestra el uso de un objeto listRes
paginador, una ListObjectsV2Iterable
stream
El código recorre las páginas de respuesta, convierte el flujo de respuesta en un flujo de S3Object
contenido y, a continuación, procesa el contenido del objeto. Amazon S3
Las importaciones siguientes se aplican a todos los ejemplos de esta sección de paginación síncrona.
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()));
Consulte el ejemplo completo
Iterar sobre objetos
Los ejemplos siguientes muestran formas de recorrer en iteración los objetos devueltos en la respuesta en lugar de las páginas de la respuesta. El método contents
de clase ListObjectsV2Iterable
devuelve un SdkIterable
Usar un stream
El siguiente fragmento de código utiliza el método stream
sobre el contenido de la respuesta para recorrer en iteración la colección de elementos paginados.
// Helper method to work with paginated collection of items directly. listRes.contents().stream() .forEach(content -> System.out .println(" Key: " + content.key() + " size = " + content.size()));
Consulte el ejemplo completo
Usar un buble for-each
Como SdkIterable
amplía la interfaz de Iterable
, puede procesar el contenido como cualquier otro Iterable
. El siguiente fragmento de código utiliza un bucle estándar for-each
para recorrer en iteración el contenido de la respuesta.
for (S3Object content : listRes.contents()) { System.out.println(" Key: " + content.key() + " size = " + content.size()); }
Consulte el ejemplo completo
Paginación manual
Si su caso de uso lo requiere, la paginación manual seguirá estando disponible. Utilice el siguiente token del objeto de respuesta para las solicitudes posteriores. En este ejemplo se usa un bucle 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(); }
Consulte el ejemplo completo
Paginación asíncrona
Los siguientes ejemplos muestran los métodos de paginación asíncrona para enumerar tablas. DynamoDB
Recorrer en iteración páginas de nombres de tablas
Los dos ejemplos siguientes utilizan un cliente DynamoDB asíncrono que llama listTablesPaginator
al método con una solicitud para obtener un. ListTablesPublisher
ListTablesPublisher
implementa dos interfaces, lo que proporciona muchas opciones para procesar las respuestas. Analizaremos los métodos de cada interfaz.
Utilizar un Subscriber
.
En el ejemplo de código siguiente se muestra cómo procesar los resultados paginados mediante la interfaz org.reactivestreams.Publisher
implementada por ListTablesPublisher
. Para obtener más información sobre el modelo de flujos reactivos, consulte el GitHub repositorio de flujos reactivos
Las importaciones siguientes se aplican a todos los ejemplos de esta sección de paginación asíncrona.
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;
El siguiente código adquiere una instancia 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);
El código siguiente utiliza una implementación anónima de org.reactivestreams.Subscriber
para procesar los resultados de cada página.
El método onSubscribe
llama al método Subscription.request
para iniciar las solicitudes de datos del publicador. Este método debe llamarse para empezar a obtener datos del publicador.
El método onNext
del suscriptor procesa una página de respuesta accediendo a todos los nombres de las tablas e imprimiendo cada una de ellas. Una vez procesada la página, se solicita otra página al publicador. Este es el método que se llama repetidamente hasta que se recuperan todas las páginas.
El método onError
se desencadena si se produce un error al recuperar los datos. Por último, se llama al método onComplete
cuando se han solicitado todas las páginas.
// 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. } });
Consulta el ejemplo completo
Utilizar un Consumer
.
La interfaz SdkPublisher
que ListTablesPublisher
implementa tiene un método subscribe
que toma un Consumer
y devuelve un CompletableFuture<Void>
.
El método subscribe
de esta interfaz se puede utilizar para casos de uso simples en los que un org.reactivestreams.Subscriber
puede resultar demasiado recargado. Como el siguiente código consume cada página, llama al método tableNames
en cada una de ellas. El método tableNames
devuelve un java.util.List
de nombres de tablas de DynamoDB que se procesan con el método forEach
.
// Use a Consumer for simple use cases. CompletableFuture<Void> future = publisher.subscribe( response -> response.tableNames() .forEach(System.out::println));
Consulte el ejemplo completo
Recorrer en iteración nombres de tablas
Los ejemplos siguientes muestran formas de recorrer en iteración los objetos devueltos en la respuesta en lugar de las páginas de la respuesta. De forma similar al ejemplo síncrono de Amazon S3 mostrado anteriormente con su método contents
, la clase de resultados asíncrona de DynamoDB, ListTablesPublisher
dispone del método de conveniencia tableNames
para interactuar con la colección de elementos subyacente. El tipo devuelto del método tableNames
es un SdkPublisher
Utilizar un Subscriber
.
El código siguiente adquiere un SdkPublisher
de las colecciones subyacentes de nombres de tablas.
// 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();
El código siguiente utiliza una implementación anónima de org.reactivestreams.Subscriber
para procesar los resultados de cada página.
El método del suscriptor onNext
procesa un elemento individual de la colección. En este caso, es el nombre de una tabla. Una vez procesada la página, se solicita otra página al publicador. Este es el método que se llama repetidamente hasta que se recuperan todas las páginas.
// 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() { } });
Consulte el ejemplo completo
Utilizar un Consumer
.
En el ejemplo siguiente, se utiliza el método subscribe
de SdkPublisher
que toma un Consumer
a para procesar cada elemento.
// Use a Consumer. CompletableFuture<Void> future = publisher.subscribe(System.out::println); future.get();
Consulte el ejemplo completo
Usar una biblioteca de terceros
Puede utilizar otras bibliotecas de terceros en lugar de implementar un suscriptor personalizado. Este ejemplo demuestra el uso de RxJava, pero se puede utilizar cualquier biblioteca que implemente las interfaces de flujo reactivo. Consulte la página RxJava wiki GitHub
Para utilizar la biblioteca, añádala como una dependencia. Si usas Maven, en el ejemplo se muestra el POM fragmento que debes usar.
POMEntrada
<dependency> <groupId>io.reactivex.rxjava3</groupId> <artifactId>rxjava</artifactId> <version>3.1.6</version> </dependency>
Código
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);
Vea el ejemplo completo