

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 o Amazon S3
<a name="examples-s3"></a>

Esta seção fornece informações básicas para trabalhar com o Amazon S3 usando o AWS SDK for Java 2.x. Esta seção complementa os [exemplos do Java v2 do Amazon S3](java_s3_code_examples.md) apresentados na seção *Exemplos de código* deste guia.

## Clientes S3 no AWS SDK for Java 2.x
<a name="s3-clients"></a>

 AWS SDK for Java 2.x Ele fornece diferentes tipos de clientes S3. A tabela a seguir mostra as diferenças e pode ajudar você a decidir o que é melhor para seus casos de uso.


**Diferentes tipos de clientes do Amazon S3**  

| Cliente do S3 | Descrição breve | Quando usar | Limitação/desvantagem | 
| --- | --- | --- | --- | 
|  **AWS Cliente S3 baseado em CRT** Interface: [S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Construtor: [S3 CrtAsyncClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html) Consulte [Use um cliente S3 de alto desempenho: cliente S3 baseado em AWS CRT](crt-based-s3-client.md).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  | 
|  **Cliente assíncrono do S3 baseado em Java *com* várias partes habilitadas** Interface: [S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Construtor: [S3 AsyncClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html) Consulte [Configurar o cliente assíncrono do S3 baseado em Java para usar transferências paralelas](s3-async-client-multipart.md).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  | Menos desempenho do que o cliente S3 AWS baseado em CRT. | 
|  **Cliente assíncrono do S3 baseado em Java *sem* várias partes habilitadas** Interface: [S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Construtor: [S3 AsyncClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  |  Sem otimização do desempenho.  | 
|  **Cliente síncrono do S3 baseado em Java** Interface: [S3Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) Construtor: [S3 ClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3ClientBuilder.html) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/examples-s3.html)  |  Sem otimização do desempenho.  | 

**nota**  
A partir da versão 2.18.x, o AWS SDK for Java 2.x usa [endereçamento no estilo hospedado virtual ao incluir uma substituição de](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#virtual-hosted-style-access) endpoint. Isso se aplica desde que o nome do bucket seja um rótulo DNS válido.   
Chame o método [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3BaseClientBuilder.html#forcePathStyle(java.lang.Boolean](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3BaseClientBuilder.html#forcePathStyle(java.lang.Boolean) com `true` no seu construtor de clientes para forçar o cliente a usar o endereçamento no estilo de caminho para os buckets.  
O exemplo a seguir mostra um cliente de serviço configurado com uma substituição de endpoint e usando o endereçamento no estilo de caminho.  

```
S3Client client = S3Client.builder()
                          .region(Region.US_WEST_2)
                          .endpointOverride(URI.create("https://s3.us-west-2.amazonaws.com"))
                          .forcePathStyle(true)
                          .build();
```

**Topics**
+ [Clientes do S3 no SDK](#s3-clients)
+ [Fazer upload de fluxos para o S3](best-practices-s3-uploads.md)
+ [Pré-assinado URLs](examples-s3-presign.md)
+ [Acesso entre regiões](s3-cross-region.md)
+ [Proteção da integridade de dados com somas de verificação](s3-checksums.md)
+ [Usar um cliente do S3 de alta performance](crt-based-s3-client.md)
+ [Configuração de suporte de transferência paralela](s3-async-client-multipart.md)
+ [Transferir arquivos e diretórios](transfer-manager.md)
+ [Notificações de eventos do S3](examples-s3-event-notifications.md)

# Fazendo upload de streams para o Amazon S3 usando o AWS SDK for Java 2.x
<a name="best-practices-s3-uploads"></a>

Quando você usa um fluxo para fazer upload de conteúdo para o S3 usando [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest,software.amazon.awssdk.core.sync.RequestBody)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest,software.amazon.awssdk.core.sync.RequestBody)) ou [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#uploadPart(software.amazon.awssdk.services.s3.model.UploadPartRequest,software.amazon.awssdk.core.sync.RequestBody)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#uploadPart(software.amazon.awssdk.services.s3.model.UploadPartRequest,software.amazon.awssdk.core.sync.RequestBody)), é utilizada uma classe de fábrica `RequestBody` para a API síncrona a fim de fornecer o fluxo. Para a API assíncrona, `AsyncRequestBody` é a classe de fábrica equivalente.

## Quais métodos fazem upload de fluxos?
<a name="s3-stream-upload-methods"></a>

Para a API síncrona, é possível usar os seguintes métodos de fábrica `RequestBody` para fornecer o fluxo:
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/sync/RequestBody.html#fromInputStream(java.io.InputStream,long))(InputStream inputStream, long contentLength)`

  `[fromContentProvider](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/sync/RequestBody.html#fromContentProvider(software.amazon.awssdk.http.ContentStreamProvider,long,java.lang.String))(ContentStreamProvider provider, long contentLength, String mimeType)`
  + `ContentStreamProvider` tem o método de fábrica `fromInputStream(InputStream inputStream)`
+ `[fromContentProvider](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/sync/RequestBody.html#fromContentProvider(software.amazon.awssdk.http.ContentStreamProvider,java.lang.String))(ContentStreamProvider provider, String mimeType)`

Para a API assíncrona, é possível usar os seguintes métodos de fábrica de `AsyncRequestBody`:
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#fromInputStream(java.io.InputStream,java.lang.Long,java.util.concurrent.ExecutorService))(InputStream inputStream, Long contentLength, ExecutorService executor)` 
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#fromInputStream(software.amazon.awssdk.core.async.AsyncRequestBodyFromInputStreamConfiguration))(AsyncRequestBodyFromInputStreamConfiguration configuration)`
  + Você usa o AsyncRequestBodyFromInputStreamConfiguration .Builder para fornecer o fluxo
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#fromInputStream(java.util.function.Consumer))(Consumer<AsyncRequestBodyFromInputStreamConfiguration.Builder> configuration)`
+ `[forBlockingInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#forBlockingInputStream(java.lang.Long))(Long contentLength)`
  + O resultado `[BlockingInputStreamAsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.html)` contém o método `writeInputStream(InputStream inputStream)` que você pode usar para fornecer o fluxo

## Realizar o upload
<a name="s3-upload-stream-perform"></a>

### Se você sabe o tamanho do fluxo
<a name="s3-stream-upload-supply-content-length"></a>

Como você pode ver na assinatura dos métodos mostrados anteriormente, a maioria deles aceita um parâmetro de tamanho do conteúdo. 

Se você souber o tamanho do conteúdo em bytes, forneça o valor exato:

```
// Always provide the exact content length when it's available.
long contentLength = 1024; // Exact size in bytes.
s3Client.putObject(req -> req
    .bucket("amzn-s3-demo-bucket")
    .key("my-key"),
RequestBody.fromInputStream(inputStream, contentLength));
```

**Atenção**  
 Ao fazer upload de um fluxo de entrada, se o tamanho do conteúdo especificado não corresponder à contagem real de bytes, poderá ocorrer:  
Objetos truncados se o comprimento especificado for muito pequeno
Falha nos uploads ou conexões interrompidas se o tamanho especificado for muito grande

### Se você não sabe o tamanho do fluxo
<a name="s3-stream-upload-unknown-length"></a>

#### Usar a API síncrona
<a name="s3-upload-unknown-sync-client"></a>

Use o`fromContentProvider(ContentStreamProvider provider, String mimeType)`:

```
public PutObjectResponse syncClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3Client s3Client = S3Client.create();

    RequestBody body = RequestBody.fromContentProvider(ContentStreamProvider.fromInputStream(inputStream), "text/plain");
    PutObjectResponse putObjectResponse = s3Client.putObject(b -> b.bucket(BUCKET_NAME).key(KEY_NAME), body);
    return putObjectResponse;
}
```

Como o SDK armazena em buffer todo o fluxo na memória para calcular a duração do conteúdo, podem ocorrer problemas de memória com fluxos grandes. Se você precisar fazer upload de fluxos grandes com o cliente síncrono, considere usar a API de várias partes:

##### Faça upload de um fluxo usando a API do cliente síncrono e a API de várias partes
<a name="sync-multipart-upload-stream"></a>

```
public static void uploadStreamToS3(String bucketName, String key, InputStream inputStream) {
    // Create S3 client
    S3Client s3Client = S3Client.create();
    try {
        // Step 1: Initiate the multipart upload
        CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        CreateMultipartUploadResponse createResponse = s3Client.createMultipartUpload(createMultipartUploadRequest);
        String uploadId = createResponse.uploadId();
        System.out.println("Started multipart upload with ID: " + uploadId);

        // Step 2: Upload parts
        List<CompletedPart> completedParts = new ArrayList<>();
        int partNumber = 1;
        byte[] buffer = new byte[PART_SIZE];
        int bytesRead;

        try {
            while ((bytesRead = readFullyOrToEnd(inputStream, buffer)) > 0) {
                // Create request to upload a part
                UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                        .bucket(bucketName)
                        .key(key)
                        .uploadId(uploadId)
                        .partNumber(partNumber)
                        .build();

                // If we didn't read a full buffer, create a properly sized byte array
                RequestBody requestBody;
                if (bytesRead < PART_SIZE) {
                    byte[] lastPartBuffer = new byte[bytesRead];
                    System.arraycopy(buffer, 0, lastPartBuffer, 0, bytesRead);
                    requestBody = RequestBody.fromBytes(lastPartBuffer);
                } else {
                    requestBody = RequestBody.fromBytes(buffer);
                }

                // Upload the part and save the response's ETag
                UploadPartResponse uploadPartResponse = s3Client.uploadPart(uploadPartRequest, requestBody);
                CompletedPart part = CompletedPart.builder()
                        .partNumber(partNumber)
                        .eTag(uploadPartResponse.eTag())
                        .build();
                completedParts.add(part);

                System.out.println("Uploaded part " + partNumber + " with size " + bytesRead + " bytes");
                partNumber++;
            }

            // Step 3: Complete the multipart upload
            CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder()
                    .parts(completedParts)
                    .build();

            CompleteMultipartUploadRequest completeRequest = CompleteMultipartUploadRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .multipartUpload(completedMultipartUpload)
                    .build();

            CompleteMultipartUploadResponse completeResponse = s3Client.completeMultipartUpload(completeRequest);
            System.out.println("Multipart upload completed. Object URL: " + completeResponse.location());

        } catch (Exception e) {
            // If an error occurs, abort the multipart upload
            System.err.println("Error during multipart upload: " + e.getMessage());
            AbortMultipartUploadRequest abortRequest = AbortMultipartUploadRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .build();
            s3Client.abortMultipartUpload(abortRequest);
            System.err.println("Multipart upload aborted");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                System.err.println("Error closing input stream: " + e.getMessage());
            }
        }
    } finally {
        s3Client.close();
    }
}

/**
 * Reads from the input stream into the buffer, attempting to fill the buffer completely
 * or until the end of the stream is reached.
 *
 * @param inputStream the input stream to read from
 * @param buffer      the buffer to fill
 * @return the number of bytes read, or -1 if the end of the stream is reached before any bytes are read
 * @throws IOException if an I/O error occurs
 */
private static int readFullyOrToEnd(InputStream inputStream, byte[] buffer) throws IOException {
    int totalBytesRead = 0;
    int bytesRead;

    while (totalBytesRead < buffer.length) {
        bytesRead = inputStream.read(buffer, totalBytesRead, buffer.length - totalBytesRead);
        if (bytesRead == -1) {
            break; // End of stream
        }
        totalBytesRead += bytesRead;
    }

    return totalBytesRead > 0 ? totalBytesRead : -1;
}
```

**nota**  
Para a maioria dos casos de uso, recomendamos usar a API do cliente assíncrono para fluxos de tamanho desconhecido. Essa abordagem permite fazer transferências paralelas e oferece uma interface de programação mais simples, porque o SDK gerencia a segmentação do fluxo em fragmentos de várias partes caso o fluxo seja grande.   
Tanto o cliente assíncrono do S3 padrão com várias partes habilitadas quanto o cliente do S3 baseado no AWS CRT implementam essa abordagem. Mostramos exemplos dessa abordagem na seção a seguir.

#### Usar a API assíncrona
<a name="s3-stream-upload-unknown-async-client"></a>

Você pode fornecer `null` para o argumento `contentLength` do `fromInputStream(InputStream inputStream, Long contentLength, ExecutorService executor)`

**Example usando o cliente AWS assíncrono baseado em CRT:**  

```
public PutObjectResponse crtClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor);  // 'null' indicates that the
                                                                                            // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null){
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

**Example usar o cliente assíncrono padrão com a opção de várias partes ativada.**  

```
public PutObjectResponse asyncClient_multipart_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.builder().multipartEnabled(true).build();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); // 'null' indicates that the
                                                                                           // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null) {
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

# Trabalhe com Amazon S3 pré-assinados URLs
<a name="examples-s3-presign"></a>

Os pré-assinados URLs fornecem acesso temporário a objetos privados do S3 sem exigir que os usuários tenham AWS credenciais ou permissões. 

Por exemplo, vamos supor que Alice tenha acesso a um objeto do S3 e queira compartilhar temporariamente o acesso a esse objeto com Bob. A Alice pode gerar uma solicitação GET pré-assinada para compartilhar com o Bob, para que ele possa baixar o objeto sem exigir acesso às credenciais da Alice. Você pode gerar solicitações pré-assinadas URLs para HTTP GET e HTTP PUT.

## Gere um URL pré-assinado para um objeto e baixe-o (solicitação GET).
<a name="get-presignedobject"></a>

O exemplo a seguir consiste em duas partes.
+ Parte 1: A Alice gera o URL pré-assinado de um objeto.
+ Parte 2: O Bob baixa o objeto usando o URL pré-assinado.

### Parte 1: Gerar o URL
<a name="get-presigned-object-part1"></a>

A Alice já tem um objeto em um bucket do S3. Ela usa o código a seguir para gerar uma string de URL que o Bob pode usar em uma solicitação GET subsequente.

#### Importações
<a name="get-presigned-example-imports"></a>

```
import com.example.s3.util.PresignUrlUtils;
import org.slf4j.Logger;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.HttpExecuteResponse;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.utils.IoUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.UUID;
```

```
    /* Create a pre-signed URL to download an object in a subsequent GET request. */
    public String createPresignedGetUrl(String bucketName, String keyName) {
        try (S3Presigner presigner = S3Presigner.create()) {

            GetObjectRequest objectRequest = GetObjectRequest.builder()
                    .bucket(bucketName)
                    .key(keyName)
                    .build();

            GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
                    .signatureDuration(Duration.ofMinutes(10))  // The URL will expire in 10 minutes.
                    .getObjectRequest(objectRequest)
                    .build();

            PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(presignRequest);
            logger.info("Presigned URL: [{}]", presignedRequest.url().toString());
            logger.info("HTTP method: [{}]", presignedRequest.httpRequest().method());

            return presignedRequest.url().toExternalForm();
        }
    }
```

### Parte 2: Baixar o objeto
<a name="get-presigned-object-part2"></a>

O Bob usa uma das três opções de código a seguir para baixar o objeto. Como alternativa, ele pode usar um navegador para realizar a solicitação GET.

#### Usar o JDK `HttpURLConnection` (desde a v1.1)
<a name="get-presigned-example-useHttpUrlConnection"></a>

```
    /* Use the JDK HttpURLConnection (since v1.1) class to do the download. */
    public byte[] useHttpUrlConnectionToGet(String presignedUrlString) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array.

        try {
            URL presignedUrl = new URL(presignedUrlString);
            HttpURLConnection connection = (HttpURLConnection) presignedUrl.openConnection();
            connection.setRequestMethod("GET");
            // Download the result of executing the request.
            try (InputStream content = connection.getInputStream()) {
                IoUtils.copy(content, byteArrayOutputStream);
            }
            logger.info("HTTP response code is " + connection.getResponseCode());

        } catch (S3Exception | IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArrayOutputStream.toByteArray();
    }
```

#### Usar o JDK `HttpClient` (desde a v11)
<a name="get-presigned-example-useHttpClient"></a>

```
    /* Use the JDK HttpClient (since v11) class to do the download. */
    public byte[] useHttpClientToGet(String presignedUrlString) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array.

        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder();
        HttpClient httpClient = HttpClient.newHttpClient();
        try {
            URL presignedUrl = new URL(presignedUrlString);
            HttpResponse<InputStream> response = httpClient.send(requestBuilder
                            .uri(presignedUrl.toURI())
                            .GET()
                            .build(),
                    HttpResponse.BodyHandlers.ofInputStream());

            IoUtils.copy(response.body(), byteArrayOutputStream);

            logger.info("HTTP response code is " + response.statusCode());

        } catch (URISyntaxException | InterruptedException | IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArrayOutputStream.toByteArray();
    }
```

#### Usar `SdkHttpClient` do SDK para Java
<a name="get-presigned-example-useSdkHttpClient"></a>

```
    /* Use the AWS SDK for Java SdkHttpClient class to do the download. */
    public byte[] useSdkHttpClientToGet(String presignedUrlString) {

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array.
        try {
            URL presignedUrl = new URL(presignedUrlString);
            SdkHttpRequest request = SdkHttpRequest.builder()
                    .method(SdkHttpMethod.GET)
                    .uri(presignedUrl.toURI())
                    .build();

            HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
                    .request(request)
                    .build();

            try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
                HttpExecuteResponse response = sdkHttpClient.prepareRequest(executeRequest).call();
                response.responseBody().ifPresentOrElse(
                        abortableInputStream -> {
                            try {
                                IoUtils.copy(abortableInputStream, byteArrayOutputStream);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        },
                        () -> logger.error("No response body."));

                logger.info("HTTP Response code is {}", response.httpResponse().statusCode());
            }
        } catch (URISyntaxException | IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArrayOutputStream.toByteArray();
    }
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedGetUrlAndRetrieve.java) e [faça o teste](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/test/java/com/example/s3/presignurl/GeneratePresignedGetUrlTests.java) GitHub.

## Gerar um URL pré-assinado para um upload e, depois, fazer upload de um arquivo (solicitação PUT)
<a name="put-presignedobject"></a>

O exemplo a seguir consiste em duas partes.
+ Parte 1: A Alice gera o URL pré-assinado para fazer upload de um objeto.
+ Parte 2: O Bob faz upload de um arquivo usando o URL pré-assinado.

### Parte 1: Gerar o URL
<a name="put-presigned-object-part1"></a>

A Alice já tem um bucket do S3. Ela usa o código a seguir para gerar uma string de URL que o Bob pode usar em uma solicitação PUT subsequente.

#### Importações
<a name="put-presigned-example-imports"></a>

```
import com.example.s3.util.PresignUrlUtils;
import org.slf4j.Logger;
import software.amazon.awssdk.core.internal.sync.FileContentStreamProvider;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.HttpExecuteResponse;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Map;
import java.util.UUID;
```

```
    /* Create a presigned URL to use in a subsequent PUT request */
    public String createPresignedUrl(String bucketName, String keyName, Map<String, String> metadata) {
        try (S3Presigner presigner = S3Presigner.create()) {

            PutObjectRequest objectRequest = PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(keyName)
                    .metadata(metadata)
                    .build();

            PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
                    .signatureDuration(Duration.ofMinutes(10))  // The URL expires in 10 minutes.
                    .putObjectRequest(objectRequest)
                    .build();


            PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);
            String myURL = presignedRequest.url().toString();
            logger.info("Presigned URL to upload a file to: [{}]", myURL);
            logger.info("HTTP method: [{}]", presignedRequest.httpRequest().method());

            return presignedRequest.url().toExternalForm();
        }
    }
```

### Parte 2: Fazer upload de um objeto de arquivo
<a name="put-presigned-object-part2"></a>

O Bob usa uma das três opções de código a seguir para fazer upload de um arquivo.

#### Usar o JDK `HttpURLConnection` (desde a v1.1)
<a name="put-presigned-example-useHttpUrlConnection"></a>

```
    /* Use the JDK HttpURLConnection (since v1.1) class to do the upload. */
    public void useHttpUrlConnectionToPut(String presignedUrlString, File fileToPut, Map<String, String> metadata) {
        logger.info("Begin [{}] upload", fileToPut.toString());
        try {
            URL presignedUrl = new URL(presignedUrlString);
            HttpURLConnection connection = (HttpURLConnection) presignedUrl.openConnection();
            connection.setDoOutput(true);
            metadata.forEach((k, v) -> connection.setRequestProperty("x-amz-meta-" + k, v));
            connection.setRequestMethod("PUT");
            OutputStream out = connection.getOutputStream();

            try (RandomAccessFile file = new RandomAccessFile(fileToPut, "r");
                 FileChannel inChannel = file.getChannel()) {
                ByteBuffer buffer = ByteBuffer.allocate(8192); //Buffer size is 8k

                while (inChannel.read(buffer) > 0) {
                    buffer.flip();
                    for (int i = 0; i < buffer.limit(); i++) {
                        out.write(buffer.get());
                    }
                    buffer.clear();
                }
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }

            out.close();
            connection.getResponseCode();
            logger.info("HTTP response code is " + connection.getResponseCode());

        } catch (S3Exception | IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
```

#### Usar o JDK `HttpClient` (desde a v11)
<a name="put-presigned-example-useHttpClient"></a>

```
    /* Use the JDK HttpClient (since v11) class to do the upload. */
    public void useHttpClientToPut(String presignedUrlString, File fileToPut, Map<String, String> metadata) {
        logger.info("Begin [{}] upload", fileToPut.toString());

        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder();
        metadata.forEach((k, v) -> requestBuilder.header("x-amz-meta-" + k, v));

        HttpClient httpClient = HttpClient.newHttpClient();
        try {
            final HttpResponse<Void> response = httpClient.send(requestBuilder
                            .uri(new URL(presignedUrlString).toURI())
                            .PUT(HttpRequest.BodyPublishers.ofFile(Path.of(fileToPut.toURI())))
                            .build(),
                    HttpResponse.BodyHandlers.discarding());

            logger.info("HTTP response code is " + response.statusCode());

        } catch (URISyntaxException | InterruptedException | IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
```

#### Usar `SdkHttpClient` do SDK para Java
<a name="put-presigned-example-useSdkHttpClient"></a>

```
    /* Use the AWS SDK for Java V2 SdkHttpClient class to do the upload. */
    public void useSdkHttpClientToPut(String presignedUrlString, File fileToPut, Map<String, String> metadata) {
        logger.info("Begin [{}] upload", fileToPut.toString());

        try {
            URL presignedUrl = new URL(presignedUrlString);

            SdkHttpRequest.Builder requestBuilder = SdkHttpRequest.builder()
                    .method(SdkHttpMethod.PUT)
                    .uri(presignedUrl.toURI());
            // Add headers
            metadata.forEach((k, v) -> requestBuilder.putHeader("x-amz-meta-" + k, v));
            // Finish building the request.
            SdkHttpRequest request = requestBuilder.build();

            HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
                    .request(request)
                    .contentStreamProvider(new FileContentStreamProvider(fileToPut.toPath()))
                    .build();

            try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
                HttpExecuteResponse response = sdkHttpClient.prepareRequest(executeRequest).call();
                logger.info("Response code: {}", response.httpResponse().statusCode());
            }
        } catch (URISyntaxException | IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
```

Veja o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedUrlAndPutFileWithMetadata.java) e [faça o teste](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/test/java/com/example/s3/presignurl/GeneratePresignedPutUrlTests.java) GitHub.

# Acesso entre regiões para o Amazon S3
<a name="s3-cross-region"></a>

Quando você trabalha com os buckets do Amazon Simple Storage Service (Amazon S3), você geralmente conhece a Região da AWS do bucket. A região com a qual você trabalha é determinada quando você cria o cliente do S3. 

No entanto, às vezes você pode precisar trabalhar com um bucket específico, mas não sabe se ele está localizado na mesma região definida para o cliente do S3. 

Em vez de fazer mais chamadas para determinar a região do bucket, você pode usar o SDK para permitir o acesso aos buckets do S3 entre diferentes regiões.

## Configuração
<a name="s3-cross-region-setup"></a>

O suporte para acesso entre regiões foi disponibilizado com a versão `2.20.111` do SDK. Use essa versão ou uma versão posterior em seu arquivo de compilação do Maven para a dependência do `s3`, conforme mostrado no trecho a seguir.

```
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.27.21</version>
</dependency>
```

Em seguida, ao criar seu cliente do S3, habilite o acesso entre regiões conforme mostrado no trecho. O acesso não está habilitado por padrão.

```
S3AsyncClient client = S3AsyncClient.builder()
                                    .crossRegionAccessEnabled(true)
                                    .build();
```

## Como o SDK fornece acesso entre regiões
<a name="s3-cross-region-routing"></a>

Quando você faz referência a um bucket existente em uma solicitação, como ao usar o método `putObject`, o SDK inicia uma solicitação para a região configurada para o cliente. 

Se o bucket não existir nessa região específica, a resposta de erro incluirá a região real em que o bucket reside. Em seguida, o SDK usa a região correta em uma segunda solicitação:

Para otimizar futuras solicitações para o mesmo bucket, o SDK armazena em cache no cliente esse mapeamento de região.

## Considerações
<a name="s3-cross-region-considerations"></a>

Ao habilitar o acesso ao bucket entre regiões, saiba que a primeira chamada de API pode resultar em maior latência se o bucket não estiver na região configurada do cliente. No entanto, as chamadas subsequentes se beneficiam das informações da região em cache, resultando em melhor desempenho.

Quando você ativa o acesso entre regiões, o acesso ao bucket não é afetado. O usuário deve estar autorizado a acessar o bucket em qualquer região em que ele resida.

# Proteção da integridade de dados com somas de verificação
<a name="s3-checksums"></a>

O Amazon Simple Storage Service (Amazon S3) oferece a capacidade de especificar uma soma de verificação ao fazer upload de um objeto. Quando você especifica uma soma de verificação, ela é armazenada com o objeto e pode ser validada quando o objeto é baixado.

As somas de verificação fornecem uma camada adicional de integridade de dados quando você transfere arquivos. Com somas de verificação, você pode verificar a consistência de dados confirmando que o arquivo recebido corresponde ao arquivo original. Consulte mais informações sobre as somas de verificação no Amazon S3 no [Guia do usuário do Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html), incluindo os [algoritmos compatíveis](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#using-additional-checksums).

Você tem a flexibilidade de escolher o algoritmo mais adequado às suas necessidades e deixar que o SDK calcule a soma de verificação. Como alternativa, você pode fornecer um valor de soma de verificação pré-computado usando um dos algoritmos compatíveis. 

**nota**  
A partir da versão 2.30.0 do AWS SDK for Java 2.x, o SDK fornece proteções de integridade padrão calculando automaticamente uma soma de verificação `CRC32` para uploads. O SDK calcula essa soma de verificação se você não fornecer um valor de soma de verificação pré-calculado ou se não especificar um algoritmo que o SDK deva usar para calcular uma soma de verificação.   
O SDK também fornece configurações globais para proteções de integridade de dados que você pode definir externamente, sobre as quais você pode ler no Guia de referência de [ferramentas AWS SDKs e ferramentas](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html).

Discutimos somas de verificação em duas fases de solicitação: upload de um objeto e download de um objeto. 

## Fazer upload de um objeto
<a name="use-service-S3-checksum-upload"></a>

Quando você faz upload de um objeto com o método `putObject` e fornece um algoritmo de soma de verificação, o SDK calcula a soma de verificação para o algoritmo especificado.

O trecho de código a seguir mostra uma solicitação para fazer upload de um objeto com uma soma de verificação `SHA256`. Quando o SDK envia a solicitação, ele calcula a soma de verificação `SHA256` e carrega o objeto. O Amazon S3 valida a integridade do conteúdo calculando a soma de verificação e comparando-a com a soma de verificação fornecida pelo SDK. Depois, o Amazon S3 armazena a soma de verificação com o objeto.

```
public void putObjectWithChecksum() {
        s3Client.putObject(b -> b
                .bucket(bucketName)
                .key(key)
                .checksumAlgorithm(ChecksumAlgorithm.SHA256),
            RequestBody.fromString("This is a test"));
}
```

Se você não fornecer um algoritmo de soma de verificação na solicitação, o comportamento da soma de verificação varia conforme a versão do SDK utilizado, conforme mostrado na tabela a seguir.

**Comportamento da soma de verificação quando nenhum algoritmo de soma de verificação é fornecido**


| Versão do Java SDK | Comportamento da soma de verificação | 
| --- | --- | 
| anterior à versão 2.30.0 | O SDK não calcula automaticamente uma soma de verificação baseada em CRC e a fornece na solicitação. | 
| 2.30.0 ou posterior | O SDK usa o algoritmo `CRC32` para calcular a soma de verificação e a fornece na solicitação. O Amazon S3 valida a integridade da transferência computando sua própria soma de verificação `CRC32` e a compara com a soma de verificação fornecida pelo SDK. Se as somas de verificação corresponderem, a soma de verificação será salva com o objeto. | 

### Usar um valor de soma de verificação pré-calculado
<a name="use-service-S3-checksum-upload-pre"></a>

Um valor de soma de verificação pré-calculado fornecido com a solicitação desabilita a computação automática pelo SDK e, em vez disso, usa o valor fornecido.

O exemplo a seguir mostra uma solicitação com uma soma de SHA256 verificação pré-calculada.

```
    public void putObjectWithPrecalculatedChecksum(String filePath) {
        String checksum = calculateChecksum(filePath, "SHA-256");

        s3Client.putObject((b -> b
                .bucket(bucketName)
                .key(key)
                .checksumSHA256(checksum)),
            RequestBody.fromFile(Paths.get(filePath)));
    }
```

Se o Amazon S3 determinar que o valor da soma de verificação está incorreto para o algoritmo especificado, o serviço retornará uma resposta de erro.

### Carregamentos fracionados
<a name="use-service-S3-checksum-upload-multi"></a>

Você também pode usar somas de verificação com carregamentos fracionados.

 O SDK para Java 2.x fornece duas opções para usar somas de verificação com carregamentos fracionados. A primeira opção usa o `S3TransferManager`.

O exemplo de gerenciador de transferência a seguir especifica o SHA1 algoritmo para o upload.

```
    public void multipartUploadWithChecksumTm(String filePath) {
        S3TransferManager transferManager = S3TransferManager.create();
        UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
            .putObjectRequest(b -> b
                .bucket(bucketName)
                .key(key)
                .checksumAlgorithm(ChecksumAlgorithm.SHA1))
            .source(Paths.get(filePath))
            .build();
        FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);
        fileUpload.completionFuture().join();
        transferManager.close();
    }
```

Se você não fornecer um algoritmo de soma de verificação ao usar o gerenciador de transferências para uploads, o SDK calculará automaticamente a soma de verificação com base no algoritmo `CRC32`. O SDK executa esse cálculo para todas as versões do SDK.

A segunda opção usa a [API `S3Client`](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) (ou a [API `S3AsyncClient`](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)) para executar o carregamento fracionado. Se você especificar uma soma de verificação com essa abordagem, deverá indicar o algoritmo a ser usado no início do carregamento. Você também deve especificar o algoritmo para a solicitação de cada parte e fornecer a soma de verificação calculada para cada parte após o carregamento.

```
    public void multipartUploadWithChecksumS3Client(String filePath) {
        ChecksumAlgorithm algorithm = ChecksumAlgorithm.CRC32;

        // Initiate the multipart upload.
        CreateMultipartUploadResponse createMultipartUploadResponse = s3Client.createMultipartUpload(b -> b
            .bucket(bucketName)
            .key(key)
            .checksumAlgorithm(algorithm)); // Checksum specified on initiation.
        String uploadId = createMultipartUploadResponse.uploadId();

        // Upload the parts of the file.
        int partNumber = 1;
        List<CompletedPart> completedParts = new ArrayList<>();
        ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer

        try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
            long fileSize = file.length();
            long position = 0;
            while (position < fileSize) {
                file.seek(position);
                long read = file.getChannel().read(bb);

                bb.flip(); // Swap position and limit before reading from the buffer.
                UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .checksumAlgorithm(algorithm) // Checksum specified on each part.
                    .partNumber(partNumber)
                    .build();

                UploadPartResponse partResponse = s3Client.uploadPart(
                    uploadPartRequest,
                    RequestBody.fromByteBuffer(bb));

                CompletedPart part = CompletedPart.builder()
                    .partNumber(partNumber)
                    .checksumCRC32(partResponse.checksumCRC32()) // Provide the calculated checksum.
                    .eTag(partResponse.eTag())
                    .build();
                completedParts.add(part);

                bb.clear();
                position += read;
                partNumber++;
            }
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }

        // Complete the multipart upload.
        s3Client.completeMultipartUpload(b -> b
            .bucket(bucketName)
            .key(key)
            .uploadId(uploadId)
            .multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build()));
    }
```

O [código para os exemplos e [testes](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/test/java/com/example/s3/PerformMultiPartUploadTests.java) completos](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/PerformMultiPartUpload.java) está no repositório GitHub de exemplos de código.

## Fazer download de um objeto
<a name="use-service-S3-checksum-download"></a>

Quando você usa o método [getObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(software.amazon.awssdk.services.s3.model.GetObjectRequest)) para baixar um objeto, o SDK valida automaticamente a soma de verificação  quando o método `checksumMode` do compilador do `GetObjectRequest` está definido como `ChecksumMode.ENABLED`. 

A solicitação no trecho a seguir direciona o SDK a validar a soma de verificação na resposta calculando a soma de verificação e comparando os valores.

```
    public GetObjectResponse getObjectWithChecksum() {
        return s3Client.getObject(b -> b
                        .bucket(bucketName)
                        .key(key)
                        .checksumMode(ChecksumMode.ENABLED))
                .response();
    }
```

**nota**  
Se o objeto não tiver sido carregado com uma soma de verificação, nenhuma validação ocorrerá. 

## Outras opções de cálculo da soma de verificação
<a name="S3-checsum-calculation-options"></a>

**nota**  
Para verificar a integridade dos dados transmitidos e identificar quaisquer erros de transmissão, recomendamos que os usuários mantenham as configurações padrão do SDK para as opções de cálculo da soma de verificação. Por padrão, o SDK adiciona essa verificação importante para muitas operações do S3, incluindo `PutObject` e `GetObject`.

No entanto, se o uso do Amazon S3 exigir uma validação mínima da soma de verificação, você poderá desativar muitas verificações alterando as configurações padrão. 

### Desative o cálculo automático da soma de verificação, a menos que seja necessário
<a name="S3-minimize-checksum-calc-global"></a>

É possível desativar o cálculo automático da soma de verificação pelo SDK para operações compatíveis, por exemplo e `PutObject` e `GetObject`. No entanto, algumas operações do S3 exigem um cálculo de soma de verificação. E não é possível desativá-lo nessas operações.

O SDK fornece configurações separadas para o cálculo de uma soma de verificação para a carga útil de uma solicitação e para a carga útil de uma resposta.

A lista a seguir descreve as configurações que você pode usar para minimizar os cálculos de soma de verificação nos diferentes escopos.
+ **Escopo de todos os aplicativos** — Ao alterar as configurações nas variáveis de ambiente ou em um perfil nos `credentials` arquivos AWS `config` compartilhados, todos os aplicativos podem usar essas configurações. Essas configurações afetam todos os clientes de serviço em todos os aplicativos do AWS SDK, a menos que sejam substituídas no escopo do aplicativo ou do cliente de serviço.
  + Adicione as configurações em um perfil:

    ```
    [default]
    request_checksum_calculation = WHEN_REQUIRED
    response_checksum_validation = WHEN_REQUIRED
    ```
  + Adicione variáveis de ambiente:

    ```
    AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
    AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
    ```
+ **Escopo atual da aplicação**: é possível definir a propriedade do sistema Java `aws.requestChecksumCalculation` como `WHEN_REQUIRED` para limitar o cálculo da soma de verificação. A propriedade do sistema correspondente para respostas é `aws.responseChecksumValidation`.

  Essas configurações afetam todos os clientes de serviço do SDK em todas as aplicações, a menos que sejam substituídas durante a criação do cliente de serviço.

  Defina a propriedade do sistema no início da aplicação:

  ```
  import software.amazon.awssdk.core.SdkSystemSetting;
  import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
  import software.amazon.awssdk.core.checksums.ResponseChecksumValidation;
  import software.amazon.awssdk.services.s3.S3Client;
  
  class DemoClass {
      public static void main(String[] args) {
  
          System.setProperty(SdkSystemSetting.AWS_REQUEST_CHECKSUM_CALCULATION.property(), // Resolves to "aws.requestChecksumCalculation".
                  "WHEN_REQUIRED");
          System.setProperty(SdkSystemSetting.AWS_RESPONSE_CHECKSUM_VALIDATION.property(), // Resolves to "aws.responseChecksumValidation".
                  "WHEN_REQUIRED");
  
          S3Client s3Client = S3Client.builder().build();
  
          // Use s3Client.
      }
  }
  ```
+ **Escopo de cliente de serviço único do S3**: é possível configurar um único cliente de serviço do S3 para calcular a quantidade mínima de somas de verificação usando os métodos do compilador:

  ```
  import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
  import software.amazon.awssdk.services.s3.S3Client;
  
  public class RequiredChecksums {
      public static void main(String[] args) {
          S3Client s3 = S3Client.builder()
                  .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                  .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
                  .build();
  
          // Use s3Client. 
      }
  // ...
  }
  ```

### Use o `LegacyMd5Plugin` para simplificar a MD5 compatibilidade
<a name="S3-checksum-legacy-md5"></a>

Junto com o lançamento do comportamento de CRC32 soma de verificação com a versão 2.30.0, o SDK parou de calcular MD5 somas de verificação nas operações necessárias.

Se precisar de um comportamento de MD5 soma de verificação legado para operações do S3, você pode usar o`LegacyMd5Plugin`, que foi lançado com a versão 2.31.32 do SDK.

Isso `LegacyMd5Plugin` é particularmente útil quando você precisa manter a compatibilidade com aplicativos que dependem do comportamento antigo da MD5 soma de verificação, especialmente ao trabalhar com provedores de armazenamento de terceiros compatíveis com S3, como aqueles usados com conectores de sistema de arquivos S3A (Apache Spark, Iceberg).

Para usar o `LegacyMd5Plugin`, adicione-o ao compilador de clientes do S3:

```
// For synchronous S3 client.
S3Client s3Client = S3Client.builder()
                           .addPlugin(LegacyMd5Plugin.create())
                           .build();

// For asynchronous S3 client.
S3AsyncClient asyncClient = S3AsyncClient.builder()
                                       .addPlugin(LegacyMd5Plugin.create())
                                       .build();
```

Se você quiser adicionar somas de MD5 verificação às operações que exigem somas de verificação e não adicionar somas de verificação padrão do SDK para operações que oferecem suporte a somas de verificação, mas não são obrigatórias, você pode ativar as opções e como. `ClientBuilder` `requestChecksumCalculation` `responseChecksumValidation` `WHEN_REQUIRED` Isso adicionará somas de verificação padrão do SDK somente às operações que as exigem:

```
// Use the `LegacyMd5Plugin` with `requestChecksumCalculation` and `responseChecksumValidation` set to WHEN_REQUIRED.
S3AsyncClient asyncClient = S3AsyncClient.builder()
                                       .addPlugin(LegacyMd5Plugin.create())
                                       .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                                       .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
                                       .build();
```

Essa configuração é particularmente útil ao trabalhar com sistemas de armazenamento de terceiros compatíveis com S3 que podem não suportar totalmente os algoritmos de soma de verificação mais recentes, mas ainda exigem somas de MD5 verificação para determinadas operações.

# Use um cliente S3 de alto desempenho: cliente S3 baseado em AWS CRT
<a name="crt-based-s3-client"></a>

O cliente S3 AWS baseado em CRT, construído com base no [AWS Common Runtime (CRT), é um cliente assíncrono](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html) S3 alternativo. Ele transfere objetos de e para o Amazon Simple Storage Service (Amazon S3) com desempenho e confiabilidade aprimorados usando automaticamente a [API de upload de várias partes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) e as [buscas de intervalo de bytes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range) do Amazon S3. 

O cliente S3 AWS baseado em CRT melhora a confiabilidade da transferência caso haja uma falha na rede. A confiabilidade é aprimorada ao realizar novas tentativas de partes individuais com falha em uma transferência de arquivos sem reiniciar a transferência desde o início.

Além disso, o cliente S3 AWS baseado em CRT oferece pool de conexões aprimorado e balanceamento de carga do Sistema de Nomes de Domínio (DNS), o que também melhora a taxa de transferência.

Você pode usar o cliente S3 AWS baseado em CRT no lugar do cliente assíncrono S3 padrão do SDK e aproveitar imediatamente sua taxa de transferência aprimorada.

**Importante**  
Atualmente, o cliente S3 AWS baseado em CRT não oferece suporte à [coleta de métricas do SDK](metrics.md) no nível do cliente nem no nível da solicitação.

**AWS Componentes baseados em CRT no SDK**

O cliente *S3 AWS * baseado em CRT, descrito neste tópico, e o cliente *HTTP AWS * baseado em CRT são componentes diferentes no SDK. 

O **cliente S3 AWS baseado em CRT** é uma implementação da AsyncClient interface [S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) e é usado para trabalhar com o serviço Amazon S3. Ele é uma alternativa à implementação da interface `S3AsyncClient` baseada em Java e oferece vários benefícios.

O [cliente HTTP AWS baseado em CRT](http-configuration-crt.md) é uma implementação da [SdkAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/async/SdkAsyncHttpClient.html)interface e é usado para comunicação HTTP geral. Essa é uma alternativa à implementação da interface `SdkAsyncHttpClient` do Netty e oferece várias vantagens.

Embora ambos os componentes usem bibliotecas do [AWS Common Runtime](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html), o cliente S3 AWS baseado em CRT usa a [biblioteca aws-c-s 3 e oferece suporte aos recursos](https://github.com/awslabs/aws-c-s3) da API de upload de [várias partes do S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html). Como o cliente HTTP AWS baseado em CRT é destinado ao uso geral, ele não oferece suporte aos recursos da API de upload de várias partes do S3.

## Adicione dependências para usar o cliente S3 baseado em AWS CRT
<a name="crt-based-s3-client-depend"></a>

Para usar o cliente S3 AWS baseado em CRT, adicione as duas dependências a seguir ao seu arquivo de projeto Maven. O exemplo mostra as versões mínimas a serem usadas. Pesquisar no repositório central do Maven as versões mais recentes dos artefatos [s3](https://central.sonatype.com/artifact/software.amazon.awssdk/s3) e [aws-crt](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt).

```
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.27.21</version>
</dependency>
<dependency>
  <groupId>software.amazon.awssdk.crt</groupId>
  <artifactId>aws-crt</artifactId>
  <version>0.30.11</version>
</dependency>
```

## Crie uma instância do cliente S3 AWS baseado em CRT
<a name="crt-based-s3-client-create"></a>

 Crie uma instância do cliente S3 AWS baseado em CRT com as configurações padrão, conforme mostrado no trecho de código a seguir.

```
S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
```

Para configurar o cliente, use o AWS CRT Client Builder. Você pode alternar do cliente assíncrono S3 padrão para o cliente AWS baseado em CRT alterando o método builder.

```
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;


S3AsyncClient s3AsyncClient = 
        S3AsyncClient.crtBuilder()
                     .credentialsProvider(DefaultCredentialsProvider.create())
                     .region(Region.US_WEST_2)
                     .targetThroughputInGbps(20.0)
                     .minimumPartSizeInBytes(8 * 1025 * 1024L)
                     .build();
```

**nota**  
Algumas das configurações no construtor padrão podem não ser suportadas atualmente no construtor de clientes CRT da AWS . Obtenha o construtor padrão chamando `S3AsyncClient#builder()`.

## Use o cliente AWS S3 baseado em CRT
<a name="crt-based-s3-client-use"></a>

Use o cliente S3 AWS baseado em CRT para chamar as operações de API do Amazon S3. O exemplo a seguir demonstra as [GetObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#getObject(java.util.function.Consumer,software.amazon.awssdk.core.async.AsyncResponseTransformer))operações [PutObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#putObject(java.util.function.Consumer,software.amazon.awssdk.core.async.AsyncRequestBody))e disponíveis por meio do AWS SDK para Java.

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;


S3AsyncClient s3Client = S3AsyncClient.crtCreate();

// Upload a local file to Amazon S3.
PutObjectResponse putObjectResponse = 
      s3Client.putObject(req -> req.bucket(<BUCKET_NAME>)
                                   .key(<KEY_NAME>),
                        AsyncRequestBody.fromFile(Paths.get(<FILE_NAME>)))
              .join();

// Download an object from Amazon S3 to a local file.
GetObjectResponse getObjectResponse = 
      s3Client.getObject(req -> req.bucket(<BUCKET_NAME>)
                                   .key(<KEY_NAME>),
                        AsyncResponseTransformer.toFile(Paths.get(<FILE_NAME>)))
              .join();
```

## Upload de fluxos de tamanho desconhecido
<a name="crt-stream-unknown-size"></a>

Uma vantagem significativa do cliente S3 AWS AWS baseado em CRT é sua capacidade de lidar com fluxos de entrada de tamanho desconhecido com eficiência. Isso é útil principalmente quando você precisa carregar dados de uma origem em que o tamanho total não pode ser determinado com antecedência.

```
public PutObjectResponse crtClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor);  // 'null' indicates that the
                                                                                            // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null){
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

Esse recurso ajuda a evitar problemas comuns com os carregamentos tradicionais, nos quais uma especificação incorreta do tamanho do conteúdo pode resultar em objetos truncados ou em uploads malsucedidos.

## Limitações de configuração
<a name="crt-based-s3-client-limitations"></a>

O cliente S3 AWS baseado em CRT e o cliente assíncrono S3 baseado em Java [fornecem recursos comparáveis](examples-s3.md#s3-clients), com o cliente S3 baseado em CRT oferecendo uma vantagem de desempenho. AWS No entanto, o cliente S3 AWS baseado em CRT não tem as configurações que o cliente assíncrono S3 baseado em Java tem. Essas configurações incluem:
+ *Configuração no nível de cliente:* tempo limite de tentativa de chamada de API, interceptores de execução de compressão, publicadores de métricas, atributos de execução personalizados, opções avançadas personalizadas, serviço de executor programado personalizado, cabeçalhos personalizados
+ *Configuração em nível de solicitação:* assinantes personalizados, tempo limite de tentativa de chamada de API

Consulte uma lista completa das diferenças de configuração na referência da API.


| Cliente assíncrono do S3 baseado em Java | AWS Cliente S3 baseado em CRT | 
| --- | --- | 
| Configurações no nível do cliente[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)Configurações no nível de solicitação[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | Configurações no nível do cliente[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)Configurações no nível de solicitação[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | 

# Configurar o cliente assíncrono do S3 baseado em Java para usar transferências paralelas
<a name="s3-async-client-multipart"></a>

Desde a versão 2.27.5, o cliente assíncrono do S3 padrão baseado em Java permite transferências paralelas automáticas (uploads e downloads de várias partes). Você configura o suporte para transferências paralelas ao criar o cliente assíncrono do S3 baseado em Java. 

Esta seção mostra como habilitar transferências paralelas e como personalizar a configuração.

## Crie uma instância de `S3AsyncClient`
<a name="s3-async-client-multipart-create"></a>

Quando você cria uma instância `S3AsyncClient` sem chamar nenhum dos métodos `multipart*` no [construtor](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html), as transferências paralelas não são habilitadas. Cada uma das declarações a seguir cria um cliente assíncrono do S3 baseado em Java sem suporte para uploads e downloads de várias partes.

### Criar *sem suporte* a várias partes
<a name="s3-async-client-mp-off"></a>

**Example**  

```
import software.amazon.awssdk.auth.credentials.ProcessCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;


S3AsyncClient s3Client = S3AsyncClient.create();

S3AsyncClient s3Client2 = S3AsyncClient.builder().build();

S3AsyncClient s3Client3 = S3AsyncClient.builder()
        .credentialsProvider(ProcessCredentialsProvider.builder().build())
        .region(Region.EU_NORTH_1)
        .build();
```

### Criar *com suporte* a várias partes
<a name="s3-async-client-mp-on"></a>

Para habilitar transferências paralelas com configurações padrão, chame o `multipartEnabled` no compilador e transmita `true` conforme mostrado no exemplo a seguir.

**Example**  

```
S3AsyncClient s3AsyncClient2 = S3AsyncClient.builder()
        .multipartEnabled(true)
        .build();
```

O valor padrão é 8 MiB para as configurações `thresholdInBytes` e `minimumPartSizeInBytes`.

Se você personalizar as configurações de várias partes, as transferências paralelas serão ativadas automaticamente, conforme mostrado a seguir.

**Example**  

```
import software.amazon.awssdk.services.s3.S3AsyncClient;
import static software.amazon.awssdk.transfer.s3.SizeConstant.MB;


S3AsyncClient s3AsyncClient2 = S3AsyncClient.builder()
        .multipartConfiguration(b -> b
                .thresholdInBytes(16 * MB)
                .minimumPartSizeInBytes(10 * MB))
        .build();
```

## Upload de fluxos de tamanho desconhecido
<a name="java-async-client-stream-unknown-size"></a>

O cliente assíncrono do S3 baseado em Java com várias partes habilitadas pode lidar com eficiência com fluxos de entrada em que o tamanho total não é conhecido com antecedência:

```
public PutObjectResponse asyncClient_multipart_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.builder().multipartEnabled(true).build();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); // 'null' indicates that the
                                                                                           // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null) {
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

Essa abordagem evita problemas que podem ocorrer ao especificar manualmente um tamanho de conteúdo incorreto, como objetos truncados ou uploads malsucedidos.

# Transfira arquivos e diretórios com o Gerenciador de transferências do Amazon S3
<a name="transfer-manager"></a>

O gerenciador de transferências do S3 é um utilitário de transferência de arquivos de alto nível e de código aberto para o AWS SDK for Java 2.x. Use-o para transferir arquivos e diretórios de e para o Amazon Simple Storage Service (Amazon S3). 

Quando criado com base no [cliente do S3 com base no AWS CRT](crt-based-s3-client.md) ou no [cliente assíncrono do S3 baseado em Java padrão com várias partes habilitadas](s3-async-client-multipart.md), o Gerenciador de Transferências do S3 pode aproveitar as melhorias de desempenho, como a [API de upload de várias partes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) e [buscas por intervalo de bytes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range). 

Com o gerenciador de transferências do S3, você também pode monitorar o progresso de uma transferência em tempo real e pausar a transferência para execução posterior.

## Conceitos básicos
<a name="transfer-manager-prerequisites"></a>

### Adicionar dependências ao seu arquivo de compilação
<a name="transfer-manager-add-dependency"></a>

Para usar o Gerenciador de Transferências do S3 com desempenho aprimorado em várias partes, configure o arquivo de compilação com as dependências necessárias.

------
#### [ Use the AWS CRT-based S3 client ]

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.27.211</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-transfer-manager</artifactId>
    </dependency>
    <dependency>
        <groupId>software.amazon.awssdk.crt</groupId>
        <artifactId>aws-crt</artifactId>
        <version>0.29.1432</version>
    </dependency>
</dependencies>
```

1 [Versão mais recente](https://central.sonatype.com/artifact/software.amazon.awssdk/bom). 2[Versão mais recente](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt).

------
#### [ Use the Java-based S3 async client ]

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.27.211</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-transfer-manager</artifactId>
    </dependency>
</dependencies>
```

1 [Versão mais recente](https://central.sonatype.com/artifact/software.amazon.awssdk/bom).

------

### Criar uma instância do gerenciador de transferências do S3
<a name="transfer-manager-create"></a>

Para habilitar a transferência paralela, você deve transmitir um cliente S3 AWS baseado em CRT OU um cliente assíncrono S3 baseado em Java com multipartes habilitado. Os exemplos a seguir mostra como configurar um gerenciador de transferências do S3 com configurações personalizadas. 

------
#### [ Use the AWS CRT-based S3 client ]

```
        S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder()
                .credentialsProvider(DefaultCredentialsProvider.create())
                .region(Region.US_EAST_1)
                .targetThroughputInGbps(20.0)
                .minimumPartSizeInBytes(8 * MB)
                .build();

        S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();
```

------
#### [ Use the Java-based S3 async client ]

Se a dependência `aws-crt` não estiver incluída no arquivo de compilação, o Gerenciador de Transferências do S3 será criado com base no cliente assíncrono do S3 baseado em Java padrão usado no SDK para Java 2.x. 

**Configuração personalizada do cliente do S3: requer a ativação de várias partes**

```
        S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
                .multipartEnabled(true)
                .credentialsProvider(DefaultCredentialsProvider.create())
                .region(Region.US_EAST_1)
                .build();

        S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();
```

**Sem configuração do cliente do S3: suporte de várias partes ativado automaticamente**

```
S3TransferManager transferManager = S3TransferManager.create();
```

------

## Carregar um arquivo em um bucket do S3
<a name="transfer-manager-upload"></a>

O exemplo a seguir mostra um exemplo de upload de arquivo junto com o uso opcional de um [LoggingTransferListener](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/LoggingTransferListener.html), que registra o progresso do upload.

Para carregar um arquivo para o Amazon S3 usando o gerenciador de transferências do S3, passe um objeto [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadFileRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadFileRequest.html) para o método [uploadFile](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#uploadFile(software.amazon.awssdk.transfer.s3.model.UploadFileRequest)) do `S3TransferManager`.

O [FileUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/FileUpload.html)objeto retornado do `uploadFile` método representa o processo de upload. Depois que a solicitação for concluída, o [CompletedFileUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedFileUpload.html)objeto conterá informações sobre o upload.

```
    public void trackUploadFile(S3TransferManager transferManager, String bucketName,
                             String key, URI filePathURI) {
        UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
                .putObjectRequest(b -> b.bucket(bucketName).key(key))
                .addTransferListener(LoggingTransferListener.create())  // Add listener.
                .source(Paths.get(filePathURI))
                .build();

        FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);

        fileUpload.completionFuture().join();
        /*
            The SDK provides a LoggingTransferListener implementation of the TransferListener interface.
            You can also implement the interface to provide your own logic.

            Configure log4J2 with settings such as the following.
                <Configuration status="WARN">
                    <Appenders>
                        <Console name="AlignedConsoleAppender" target="SYSTEM_OUT">
                            <PatternLayout pattern="%m%n"/>
                        </Console>
                    </Appenders>

                    <Loggers>
                        <logger name="software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener" level="INFO" additivity="false">
                            <AppenderRef ref="AlignedConsoleAppender"/>
                        </logger>
                    </Loggers>
                </Configuration>

            Log4J2 logs the progress. The following is example output for a 21.3 MB file upload.
                Transfer initiated...
                |                    | 0.0%
                |====                | 21.1%
                |============        | 60.5%
                |====================| 100.0%
                Transfer complete!
        */
    }
```

### Importações
<a name="transfer-manager-upload-imports"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileUpload;
import software.amazon.awssdk.transfer.s3.model.FileUpload;
import software.amazon.awssdk.transfer.s3.model.UploadFileRequest;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.UUID;
```

## Baixar um arquivo de um bucket do S3
<a name="transfer-manager-download"></a>

O exemplo a seguir mostra um exemplo de download junto com o uso opcional de um [LoggingTransferListener](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/LoggingTransferListener.html), que registra o progresso do download.

Para baixar um objeto de um bucket do S3 usando o S3 Transfer Manager, crie um [DownloadFileRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DownloadFileRequest.html)objeto e passe-o para o método [downloadFile](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#downloadFile(software.amazon.awssdk.transfer.s3.model.DownloadFileRequest)).

O [FileDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/FileDownload.html)objeto retornado pelo `downloadFile` método `S3TransferManager`'s representa a transferência do arquivo. Após a conclusão do download, ele [CompletedFileDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedFileDownload.html)contém acesso às informações sobre o download.

```
    public void trackDownloadFile(S3TransferManager transferManager, String bucketName,
                             String key, String downloadedFileWithPath) {
        DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
                .getObjectRequest(b -> b.bucket(bucketName).key(key))
                .addTransferListener(LoggingTransferListener.create())  // Add listener.
                .destination(Paths.get(downloadedFileWithPath))
                .build();

        FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest);

        CompletedFileDownload downloadResult = downloadFile.completionFuture().join();
        /*
            The SDK provides a LoggingTransferListener implementation of the TransferListener interface.
            You can also implement the interface to provide your own logic.

            Configure log4J2 with settings such as the following.
                <Configuration status="WARN">
                    <Appenders>
                        <Console name="AlignedConsoleAppender" target="SYSTEM_OUT">
                            <PatternLayout pattern="%m%n"/>
                        </Console>
                    </Appenders>

                    <Loggers>
                        <logger name="software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener" level="INFO" additivity="false">
                            <AppenderRef ref="AlignedConsoleAppender"/>
                        </logger>
                    </Loggers>
                </Configuration>

            Log4J2 logs the progress. The following is example output for a 21.3 MB file download.
                Transfer initiated...
                |=======             | 39.4%
                |===============     | 78.8%
                |====================| 100.0%
                Transfer complete!
        */
    }
```

### Importações
<a name="transfer-manager-download-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.exception.SdkException;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileDownload;
import software.amazon.awssdk.transfer.s3.model.DownloadFileRequest;
import software.amazon.awssdk.transfer.s3.model.FileDownload;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
```

## Adicionar um objeto a um bucket do Amazon S3
<a name="transfer-manager-copy"></a>

O exemplo a seguir mostra como copiar um objeto com o gerenciador de transferência do S3.

Para começar a cópia de um objeto de um bucket do S3 para outro bucket, crie uma [CopyObjectRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/CopyObjectRequest.html)instância básica.

Em seguida, envolva o básico `CopyObjectRequest` em um [CopyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CopyRequest.html)que possa ser usado pelo S3 Transfer Manager. 

O objeto `Copy` retornado pelo método `copy` do `S3TransferManager` representa o processo de cópia. Depois que o processo de cópia for concluído, o [CompletedCopy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedCopy.html)objeto conterá detalhes sobre a resposta.

```
    public String copyObject(S3TransferManager transferManager, String bucketName,
            String key, String destinationBucket, String destinationKey) {
        CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
                .sourceBucket(bucketName)
                .sourceKey(key)
                .destinationBucket(destinationBucket)
                .destinationKey(destinationKey)
                .build();

        CopyRequest copyRequest = CopyRequest.builder()
                .copyObjectRequest(copyObjectRequest)
                .build();

        Copy copy = transferManager.copy(copyRequest);

        CompletedCopy completedCopy = copy.completionFuture().join();
        return completedCopy.response().copyObjectResult().eTag();
    }
```

**nota**  
Para realizar uma cópia entre regiões com o S3 Transfer Manager, habilite `crossRegionAccessEnabled` no construtor de clientes S3 AWS baseado em CRT, conforme mostrado no trecho a seguir.  

```
S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder()
                .crossRegionAccessEnabled(true)
                .build();

S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();
```

### Importações
<a name="transfer-manager-copy-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedCopy;
import software.amazon.awssdk.transfer.s3.model.Copy;
import software.amazon.awssdk.transfer.s3.model.CopyRequest;

import java.util.UUID;
```

## Carregamento de um diretório local para um bucket do S3
<a name="transfer-manager-upload_directory"></a>

O exemplo a seguir demonstra como fazer upload de um diretório local para o S3.

Comece chamando o método [uploadDirectory](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#uploadDirectory(software.amazon.awssdk.transfer.s3.model.UploadDirectoryRequest)) da `S3TransferManager` instância, passando um. [UploadDirectoryRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadDirectoryRequest.html)

O [DirectoryUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DirectoryUpload.html)objeto representa o processo de upload, que gera um [CompletedDirectoryUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedDirectoryUpload.html)quando a solicitação é concluída. O objeto `CompleteDirectoryUpload` contém informações sobre os resultados da transferência, incluindo quais arquivos falharam na transferência.

```
    public Integer uploadDirectory(S3TransferManager transferManager,
            URI sourceDirectory, String bucketName) {
        DirectoryUpload directoryUpload = transferManager.uploadDirectory(UploadDirectoryRequest.builder()
                .source(Paths.get(sourceDirectory))
                .bucket(bucketName)
                .build());

        CompletedDirectoryUpload completedDirectoryUpload = directoryUpload.completionFuture().join();
        completedDirectoryUpload.failedTransfers()
                .forEach(fail -> logger.warn("Object [{}] failed to transfer", fail.toString()));
        return completedDirectoryUpload.failedTransfers().size();
    }
```

### Importações
<a name="transfer-manager-upload_directory-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.services.s3.model.ObjectIdentifier;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryUpload;
import software.amazon.awssdk.transfer.s3.model.DirectoryUpload;
import software.amazon.awssdk.transfer.s3.model.UploadDirectoryRequest;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.UUID;
```

## Baixar objetos do bucket do S3 para um diretório local
<a name="transfer-manager-download_directory"></a>

É possível baixar os objetos em um bucket do S3 para um diretório local, conforme mostrado no exemplo a seguir.

Para baixar os objetos em um bucket do S3 para um diretório local, comece chamando o método [DownloadDirectory](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#downloadDirectory(software.amazon.awssdk.transfer.s3.model.DownloadDirectoryRequest)) do Transfer Manager, passando um. [DownloadDirectoryRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DownloadDirectoryRequest.html)

O [DirectoryDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DirectoryDownload.html)objeto representa o processo de download, que gera um [CompletedDirectoryDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedDirectoryDownload.html)quando a solicitação é concluída. O objeto `CompleteDirectoryDownload` contém informações sobre os resultados da transferência, incluindo quais arquivos falharam na transferência.

```
    public Integer downloadObjectsToDirectory(S3TransferManager transferManager,
            URI destinationPathURI, String bucketName) {
        DirectoryDownload directoryDownload = transferManager.downloadDirectory(DownloadDirectoryRequest.builder()
                .destination(Paths.get(destinationPathURI))
                .bucket(bucketName)
                .build());
        CompletedDirectoryDownload completedDirectoryDownload = directoryDownload.completionFuture().join();

        completedDirectoryDownload.failedTransfers()
                .forEach(fail -> logger.warn("Object [{}] failed to transfer", fail.toString()));
        return completedDirectoryDownload.failedTransfers().size();
    }
```

### Importações
<a name="transfer-manager-download_directory-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.ObjectIdentifier;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryDownload;
import software.amazon.awssdk.transfer.s3.model.DirectoryDownload;
import software.amazon.awssdk.transfer.s3.model.DownloadDirectoryRequest;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
```

## Ver exemplos completos
<a name="transfer-manager-example-location"></a>

[GitHub contém o código completo](https://github.com/awsdocs/aws-doc-sdk-examples/tree/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/transfermanager) de todos os exemplos desta página.

# Trabalhar com Notificações de Eventos do S3
<a name="examples-s3-event-notifications"></a>

O Amazon S3 pode enviar notificações quando determinados eventos acontecerem para ajudar você a monitorar a atividade nos buckets. O Guia do usuário do Amazon S3 fornece informações sobre as [notificações que um bucket pode enviar](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html#notification-how-to-overview). 

É possível configurar um bucket para enviar eventos a quatro destinos possíveis usando o SDK para Java: 
+ Tópicos do Amazon Simple Notification Service
+ Filas do Amazon Simple Queue Service
+ AWS Lambda funções
+ Amazon EventBridge

Ao configurar um bucket para o qual enviar eventos EventBridge, você pode configurar uma EventBridge regra para distribuir o mesmo evento para vários destinos. Ao configurar o bucket para enviar diretamente a um dos três primeiros destinos, somente um tipo de destino pode ser especificado para cada evento.

Na próxima seção, você verá como configurar um bucket usando o SDK for Java para enviar notificações de eventos do S3 de duas maneiras: diretamente para uma fila do Amazon SQS e para. EventBridge

A última seção mostra como usar a API de Notificações de Eventos do S3 para trabalhar com notificações de uma forma orientada a objetos.

## Configurar um bucket para enviar diretamente a um destino
<a name="s3-event-conf-bucket-direct"></a>

O exemplo a seguir configura um bucket para enviar notificações quando eventos de *criação de objetos* ou eventos de *marcação de objetos* ocorrem em um bucket.

```
static void processS3Events(String bucketName, String queueArn) {
    // Configure the bucket to send Object Created and Object Tagging notifications to an existing SQS queue.
    s3Client.putBucketNotificationConfiguration(b -> b
            .notificationConfiguration(ncb -> ncb
                    .queueConfigurations(qcb -> qcb
                            .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING)
                            .queueArn(queueArn)))
                    .bucket(bucketName)
    );
}
```

O código mostrado acima configura uma fila para receber dois tipos de eventos. Convenientemente, o método `queueConfigurations` permite que você defina vários destinos de fila, se necessário. Além disso, no método `notificationConfiguration`, você pode definir destinos adicionais, como um ou mais tópicos do Amazon SNS ou uma ou mais funções do Lambda. O trecho a seguir mostra um exemplo com duas filas e três tipos de destinos.

```
s3Client.putBucketNotificationConfiguration(b -> b
                .notificationConfiguration(ncb -> ncb
                        .queueConfigurations(qcb -> qcb
                                .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING)
                                .queueArn(queueArn), 
                                qcb2 -> qcb2.<...>)
                        .topicConfigurations(tcb -> tcb.<...>)
                        .lambdaFunctionConfigurations(lfcb -> lfcb.<...>))
                        .bucket(bucketName)
        );
```

O GitHub repositório de exemplos de código contém o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java) para enviar notificações de eventos do S3 diretamente para uma fila.

## Configurar um bucket para enviar para EventBridge
<a name="s3-event-conf-bucket-eventbridge"></a>

O exemplo a seguir configura um bucket para o qual enviar EventBridge notificações.

```
public static String setBucketNotificationToEventBridge(String bucketName) {
    // Enable bucket to emit S3 Event notifications to EventBridge.
    s3Client.putBucketNotificationConfiguration(b -> b
            .bucket(bucketName)
            .notificationConfiguration(b1 -> b1
                    .eventBridgeConfiguration(SdkBuilder::build))
    .build());
```

Ao configurar um bucket para o qual enviar eventos EventBridge, basta indicar o EventBridge destino, não os tipos de eventos nem o destino final para o qual o envio EventBridge será enviado. Você configura os destinos finais e os tipos de eventos usando o EventBridge cliente do Java SDK.

O código a seguir mostra como configurar EventBridge para distribuir eventos *criados por objetos* para um tópico e uma fila.

```
   public static String configureEventBridge(String topicArn, String queueArn) {
        try {
            // Create an EventBridge rule to route Object Created notifications.
            PutRuleRequest putRuleRequest = PutRuleRequest.builder()
                    .name(RULE_NAME)
                    .eventPattern("""
                            {
                              "source": ["aws.s3"],
                              "detail-type": ["Object Created"],
                              "detail": {
                                "bucket": {
                                  "name": ["%s"]
                                }
                              }
                            }
                            """.formatted(bucketName))
                    .build();

            // Add the rule to the default event bus.
            PutRuleResponse putRuleResponse = eventBridgeClient.putRule(putRuleRequest)
                    .whenComplete((r, t) -> {
                        if (t != null) {
                            logger.error("Error creating event bus rule: " + t.getMessage(), t);
                            throw new RuntimeException(t.getCause().getMessage(), t);
                        }
                        logger.info("Event bus rule creation request sent successfully. ARN is: {}", r.ruleArn());
                    }).join();

            // Add the existing SNS topic and SQS queue as targets to the rule.
            eventBridgeClient.putTargets(b -> b
                    .eventBusName("default")
                    .rule(RULE_NAME)
                    .targets(List.of (
                            Target.builder()
                                    .arn(queueArn)
                                    .id("Queue")
                                    .build(),
                            Target.builder()
                                    .arn(topicArn)
                                    .id("Topic")
                                    .build())
                            )
                    ).join();
            return putRuleResponse.ruleArn();
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return null;
    }
```

Para trabalhar com EventBridge seu código Java, adicione uma dependência do `eventbridge` artefato ao seu arquivo `pom.xml` Maven.

```
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>eventbridge</artifactId>
</dependency>
```

O GitHub repositório de exemplos de código contém o [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/PutBucketS3EventNotificationEventBridge.java) para enviar notificações de eventos do S3 para EventBridge e depois para um tópico e uma fila.

## Usar a API de Notificações de Eventos do S3 para processar eventos
<a name="s3-event-notification-read"></a>

Depois que um destino recebe eventos de notificação do S3, você pode processá-los de forma orientada a objetos usando a API de Notificações de Eventos do S3. Você pode usar a API de notificações de eventos do S3 para trabalhar com notificações de eventos que são enviadas diretamente para um destino (conforme mostrado no [primeiro exemplo](#s3-event-conf-bucket-direct)), mas não com notificações roteadas. EventBridge As notificações de eventos do S3 enviadas por buckets EventBridge contêm uma [estrutura diferente](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ev-events.html#ev-events-list) que a API de notificações de eventos do S3 não processa atualmente.

### Adicionar dependência
<a name="s3-event-notifications-dep"></a>

A API de Notificações de Eventos do S3 foi lançada com a versão 2.25.11 do SDK para Java 2.x.

Para usar a API de Notificações de Eventos do S3, adicione o elemento de dependência necessário ao `pom.xml` do Maven, conforme mostrado no trecho a seguir.

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.X.X1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-event-notifications</artifactId>
    </dependency>
</dependencies>
```

1 [Versão mais recente](https://central.sonatype.com/artifact/software.amazon.awssdk/bom).

### Usar a classe `S3EventNotification`
<a name="s3-event-notifications-use"></a>

#### Criar uma instância do `S3EventNotification` com base em uma string JSON
<a name="s3-event-notifications-use-from-json"></a>

Para converter uma string JSON em um objeto `S3EventNotification`, use os métodos estáticos da classe `S3EventNotification`, conforme mostrado no exemplo a seguir.

```
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord
import software.amazon.awssdk.services.sqs.model.Message; 

public class S3EventNotificationExample {
    ...
    
    void receiveMessage(Message message) {
       // Message received from SQSClient.
       String sqsEventBody = message.body();
       S3EventNotification s3EventNotification = S3EventNotification.fromJson(sqsEventBody);
    
       // Use getRecords() to access all the records in the notification.                                                                                                       
       List<S3EventNotificationRecord> records = s3EventNotification.getRecords();   
    
        S3EventNotificationRecord record = records.stream().findFirst();
        // Use getters on the record to access individual attributes.
        String awsRegion = record.getAwsRegion();
        String eventName = record.getEventName();
        String eventSource = record.getEventSource();                                                                                                   
    }
}
```

Neste exemplo, o método `fromJson` converte a string JSON em um objeto `S3EventNotification`. Os campos ausentes na string JSON resultarão em valores `null` nos campos do objeto Java correspondentes e os campos extras no JSON serão ignorados.

Outros APIs para um registro de notificação de eventos podem ser encontrados na referência da API para`[S3EventNotificationRecord](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3EventNotificationRecord.html)`.

#### Converter uma instância `S3EventNotification` em uma string JSON
<a name="s3-event-notifications-use-to-json"></a>

Use o método `toJson` (ou `toJsonPretty`) para converter um objeto `S3EventNotification` em uma string JSON, conforme mostrado no exemplo a seguir.

```
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification

public class S3EventNotificationExample {
    ...

    void toJsonString(S3EventNotification event) {

        String json = event.toJson();
        String jsonPretty = event.toJsonPretty();

        System.out.println("JSON: " + json);
        System.out.println("Pretty JSON: " + jsonPretty);
    }
}
```

Os campos para `GlacierEventData`, `ReplicationEventData`, `IntelligentTieringEventData` e `LifecycleEventData` serão excluídos do JSON se forem `null`. Outros campos `null` serão serializados como `null`.

Veja a seguir um exemplo de saída do método `toJsonPretty` para um evento de marcação de objetos do S3.

```
{
  "Records" : [ {
    "eventVersion" : "2.3",
    "eventSource" : "aws:s3",
    "awsRegion" : "us-east-1",
    "eventTime" : "2024-07-19T20:09:18.551Z",
    "eventName" : "ObjectTagging:Put",
    "userIdentity" : {
      "principalId" : "AWS:XXXXXXXXXXX"
    },
    "requestParameters" : {
      "sourceIPAddress" : "XXX.XX.XX.XX"
    },
    "responseElements" : {
      "x-amz-request-id" : "XXXXXXXXXXXX",
      "x-amz-id-2" : "XXXXXXXXXXXXX"
    },
    "s3" : {
      "s3SchemaVersion" : "1.0",
      "configurationId" : "XXXXXXXXXXXXX",
      "bucket" : {
        "name" : "amzn-s3-demo-bucket",
        "ownerIdentity" : {
          "principalId" : "XXXXXXXXXXX"
        },
        "arn" : "arn:aws:s3:::XXXXXXXXXX"
      },
      "object" : {
        "key" : "akey",
        "size" : null,
        "eTag" : "XXXXXXXXXX",
        "versionId" : null,
        "sequencer" : null
      }
    }
  } ]
}
```

Um [exemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/75c3daadf750406156fc87fa30ee499a206b4a36/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java#L117) está disponível em GitHub que mostra como usar a API para trabalhar com notificações recebidas por uma fila do Amazon SQS.

## Processe eventos do S3 no Lambda com bibliotecas Java: e AWS SDK for Java 2.x `aws-lambda-java-events`
<a name="s3-event-notif-processing-options"></a>

Em vez de usar o SDK for Java 2.x para processar notificações de eventos do Amazon S3 em uma função Lambda, você pode usar a biblioteca na versão 3.x.x. `[aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events)` AWS mantém a `aws-lambda-java-events` biblioteca de forma independente e tem seus próprios requisitos de dependência. A biblioteca `aws-lambda-java-events` funciona somente com eventos do S3 nas funções do Lambda, enquanto o SDK para Java 2.x funciona com eventos do S3 nas funções do Lambda, Amazon SNS e Amazon SQS.

Ambas as abordagens modelam a carga útil de notificação de eventos JSON de forma orientada a objetos e similares. APIs A tabela a seguir mostra as diferenças notáveis entre o uso das duas abordagens.


****  

|  | AWS SDK para Java | aws-lambda-java-events biblioteca | 
| --- | --- | --- | 
| Nomeação do pacote |  `software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification`  | com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification | 
| Parâmetro RequestHandler |  Escreva a implementação `RequestHandler` da função do Lambda para receber uma string JSON: <pre>import com.amazonaws.services.lambda.runtime.Context;<br />import com.amazonaws.services.lambda.runtime.RequestHandler;<br />import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;<br /><br />public class Handler implements RequestHandler<String, String> {<br /><br />    @Override<br />        public String handleRequest(String jsonS3Event, Context context) {<br />            S3EventNotification s3Event = S3EventNotification<br />                                             .fromJson(jsonS3Event);<br />            // Work with the s3Event object.        <br />            ...<br />    }<br />}</pre>  | Escreva a implementação RequestHandler da função do Lambda para receber um objeto S3Event:<pre>import com.amazonaws.services.lambda.runtime.Context;<br />import com.amazonaws.services.lambda.runtime.RequestHandler;<br />import com.amazonaws.services.lambda.runtime.events.S3Event;<br /><br />public class Handler implements RequestHandler<S3Event, String> {<br /><br />    @Override<br />        public String handleRequest(S3Event s3event, Context context) {<br />            // Work with the s3Event object.        <br />            ...<br />    }<br />}</pre> | 
| Dependências do Maven |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.X.X</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3-event-notifications</artifactId><br />    </dependency><br />    <!-- Add other SDK dependencies that you need. --><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.X.X</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <!-- The following two dependencies are for the <br />         aws-lambda-java-events library. --><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-lambda-java-core</artifactId><br />        <version>1.2.3</version>     <br />    </dependency><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-lambda-java-events</artifactId><br />        <version>3.15.0</version><br />    </dependency><br />    <!-- Add other SDK dependencies that you need. --><br /></dependencies></pre>  | 