As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Trabalhar com resultados paginados usando o AWS SDK para Java
2.x
Muitas AWS operações retornam resultados paginados quando o objeto de resposta é muito grande para ser retornado em uma única resposta. Na AWS SDK para Java versão 1.0, a resposta contém um token que você usa para recuperar a próxima página de resultados. Por outro lado, o AWS SDK para Java 2.x tem métodos de autopaginação que fazem várias chamadas de serviço para obter automaticamente a próxima página de resultados para você. Você precisa somente escrever um código que processa os resultados. A autopaginação está disponível para clientes síncronos e assíncronos.
nota
Esses trechos de código pressupõem que você entenda os conceitos básicos do uso do SDK e tenha configurado seu ambiente com acesso de login único.
Paginação síncrona
Os exemplos a seguir demonstram métodos de paginação síncrona para listar objetos em um bucket do Amazon S3 .
Iterar sobre páginas
O primeiro exemplo demonstra o uso de um objeto listRes
paginador, uma ListObjectsV2Iterable
stream
O código é transmitido pelas páginas de resposta, converte o fluxo de resposta em um fluxo de S3Object
conteúdo e, em seguida, processa o conteúdo do Amazon S3 objeto.
As importações a seguir se aplicam a todos os exemplos nesta seção de paginação 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()));
Veja o exemplo completo
Iterar sobre objetos
Os exemplos a seguir mostram maneiras de iterar sobre os objetos retornados na resposta e não nas páginas de resposta. O método contents
da classe ListObjectsV2Iterable
retorna um SdkIterable
Usar um stream
O seguinte trecho usa o método stream
no conteúdo de resposta para iterar sobre a coleção de itens 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()));
Veja o exemplo completo
Usar um loop for-each
Como SdkIterable
estende a interface Iterable
, você pode processar o conteúdo como qualquer outro Iterable
. O trecho a seguir usa um loop for-each
padrão para percorrer o conteúdo da resposta.
for (S3Object content : listRes.contents()) {
System.out.println(" Key: " + content.key() + " size = " + content.size());
}
Veja o exemplo completo
Paginação manual
Se seu caso de uso exigir isto, a paginação manual ainda estará disponível. Use o próximo token no objeto de resposta para as solicitações subsequentes. O exemplo a seguir usa o loop 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();
}
Veja o exemplo completo
Paginação assíncrona
Os exemplos a seguir demonstram métodos de paginação assíncrona para listar tabelas. DynamoDB
Iterar sobre páginas de nomes de tabelas
Os dois exemplos a seguir usam um cliente assíncrono do DynamoDB que chama listTablesPaginator
o método com uma solicitação para obter um. ListTablesPublisher
ListTablesPublisher
implementa duas interfaces, que oferecem muitas opções para processar respostas. Examinaremos os métodos de cada interface.
Usar um Subscriber
O exemplo de código a seguir demonstra como processar resultados paginados usando a interface org.reactivestreams.Publisher
implementada pelo ListTablesPublisher
. Para saber mais sobre o modelo de fluxos reativos, consulte o repositório Reactive
As importações a seguir se aplicam a todos os exemplos nesta seção de paginação assí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;
O código a seguir adquire uma instância 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);
O código a seguir usa uma implementação anônima de org.reactivestreams.Subscriber
para processar os resultados de cada página.
O método onSubscribe
chama o método Subscription.request
para iniciar solicitações de dados do editor. Esse método deve ser chamado para iniciar a obtenção de dados do editor.
O método onNext
do assinante processa uma página de resposta acessando todos os nomes das tabelas e imprimindo cada um. Depois que a página é processada, outra página é solicitada ao publicador. Este método é chamado repetidamente até que todas as páginas sejam recuperadas.
O método onError
será acionado se ocorrer um erro durante a recuperação de dados. Por fim, o método onComplete
será chamado quando todas as páginas tiverem sido solicitadas.
// 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.
}
});
Veja o exemplo completo
Usar um Consumer
A interface do SdkPublisher
que ListTablesPublisher
implementa tem um método subscribe
que pega um Consumer
e retorna um CompletableFuture<Void>
.
O método subscribe
dessa interface pode ser usado para casos de uso simples, quando um org.reactivestreams.Subscriber
pode ser uma sobrecarga. Como o código abaixo consome cada página, ele chama o método tableNames
em cada uma. O método tableNames
retorna um java.util.List
dos nomes de tabela do DynamoDB que são processados com o método forEach
.
// Use a Consumer for simple use cases.
CompletableFuture<Void> future = publisher.subscribe(
response -> response.tableNames()
.forEach(System.out::println));
Veja o exemplo completo
Iterar sobre nomes de tabela
Os exemplos a seguir mostram maneiras de iterar sobre os objetos retornados na resposta e não nas páginas de resposta. Semelhante ao exemplo síncrono do Amazon S3 mostrado anteriormente com seu método contents
, a classe de resultados assíncronos do DynamoDB, ListTablesPublisher
tem o método conveniente tableNames
para interagir com a coleção de itens subjacente. O tipo de retorno do método tableNames
é um SdkPublisher
Usar um Subscriber
O código a seguir adquire um SdkPublisher
da coleção subjacente de nomes de tabelas.
// 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();
O código a seguir usa uma implementação anônima de org.reactivestreams.Subscriber
para processar os resultados de cada página.
O método onNext
do assinante processa um elemento individual da coleção. Nesse caso, é um nome de tabela. Depois que o nome da tabela é processado, outro nome de tabela é solicitado ao publicador. Este método é chamado repetidamente até que todos os nomes de tabelas sejam recuperados.
// 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() {
}
});
Veja o exemplo completo
Usar um Consumer
O exemplo a seguir usa o método subscribe
do SdkPublisher
que utiliza um Consumer
para processar cada item.
// Use a Consumer.
CompletableFuture<Void> future = publisher.subscribe(System.out::println);
future.get();
Veja o exemplo completo
Usar bibliotecas de terceiros
Você pode usar outras bibliotecas de terceiros em vez de implementar um assinante personalizado. Este exemplo demonstra o uso de RxJava, mas qualquer biblioteca que implemente as interfaces de fluxo reativo pode ser usada. Consulte a página RxJava wiki GitHub
Para usar a biblioteca, adicione-a como uma dependência. Se estiver usando o Maven, o exemplo mostra o trecho POM a ser usado.
Entrada POM
<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);
Veja o exemplo completo