

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Trabajo con Amazon S3
<a name="examples-s3"></a>

En esta sección se proporciona información básica para trabajar con Amazon S3 mediante AWS SDK for Java 2.x. Esta sección complementa los [ejemplos de Java v2 de Amazon S3](java_s3_code_examples.md) presentados en la sección *Ejemplos de código* de esta guía.

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

 AWS SDK for Java 2.x Proporciona diferentes tipos de clientes S3. La siguiente tabla muestra las diferencias y puede ayudarle a decidir qué es lo mejor para sus casos de uso.


**Diferentes tipos de clientes de Amazon S3**  

| Cliente de S3 | Descripción breve | Cuándo se debe usar | Limitación o inconveniente | 
| --- | --- | --- | --- | 
|  **AWS Cliente S3 basado en CRT** [Interfaz: S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Constructor: [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/es_es/sdk-for-java/latest/developer-guide/examples-s3.html) Consulte [Utilice un cliente S3 de alto rendimiento: cliente S3 basado en AWS CRT](crt-based-s3-client.md).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  | 
|  **Cliente asincrónico S3 basado en Java *con* multiparte habilitada** Interfaz: [S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Constructor: [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/es_es/sdk-for-java/latest/developer-guide/examples-s3.html) Consulte [Configuración del cliente asincrónico S3 basado en Java para usar transferencias paralelas](s3-async-client-multipart.md).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  | Tiene menos rendimiento que el cliente S3 basado en AWS CRT. | 
|  **Cliente asincrónico de S3 basado en Java *sin* multiparte habilitada** [Interfaz: S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Constructor: [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/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  |  Sin optimización del rendimiento  | 
|  **Cliente asincrónico de S3 basado en Java** Interfaz: [S3Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) Constructor: [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/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/examples-s3.html)  |  Sin optimización del rendimiento  | 

**nota**  
A partir de la versión 2.18.x, AWS SDK for Java 2.x utiliza un [direccionamiento de tipo alojamiento virtual al incluir una anulación de punto final](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#virtual-hosted-style-access). Esto se aplica siempre que el nombre del bucket sea una etiqueta DNS válida.   
Llame al 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) con `true` en su constructor de clientes para forzar al cliente a utilizar el direccionamiento estilo ruta para los buckets.  
En el siguiente ejemplo se muestra un cliente de servicio configurado con una anulación de punto de conexión y utilizando direccionamiento estilo ruta.  

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

**Topics**
+ [Clientes de S3 en el SDK](#s3-clients)
+ [Carga de flujos en S3](best-practices-s3-uploads.md)
+ [Prefirmado URLs](examples-s3-presign.md)
+ [Acceso entre regiones](s3-cross-region.md)
+ [Protección de la integridad de los datos con sumas de comprobación](s3-checksums.md)
+ [Utilizar un cliente S3 de alto rendimiento](crt-based-s3-client.md)
+ [Configuración de la compatibilidad con la transferencia paralela](s3-async-client-multipart.md)
+ [Transferir archivos y directorios](transfer-manager.md)
+ [Notificaciones de eventos de S3](examples-s3-event-notifications.md)

# Carga de transmisiones a Amazon S3 mediante AWS SDK for Java 2.x
<a name="best-practices-s3-uploads"></a>

Cuando se utiliza un flujo para cargar contenido en S3 utilizando [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)) o [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)), se utiliza una clase de fábrica `RequestBody` para que la API sincrónica suministre el flujo. Para la API asincrónica, `AsyncRequestBody` es la clase de fábrica equivalente.

## ¿Qué métodos cargan flujos?
<a name="s3-stream-upload-methods"></a>

En la API sincrónica, puede usar los siguientes métodos de fábrica de `RequestBody` para suministrar el flujo:
+ `[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)`
  + El `ContentStreamProvider` tiene el 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)`

En la API asincrónica, puede usar los siguientes 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)`
  + Utiliza el AsyncRequestBodyFromInputStreamConfiguration .Builder para suministrar la transmisión
+ `[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)`
  + El `[BlockingInputStreamAsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.html)` resultante contiene el método `writeInputStream(InputStream inputStream)` que puede utilizar para proporcionar el flujo

## Realización de la carga
<a name="s3-upload-stream-perform"></a>

### Si conoce la longitud del flujo
<a name="s3-stream-upload-supply-content-length"></a>

Como puede ver en la firma de los métodos mostrados anteriormente, la mayoría de los métodos aceptan un parámetro de longitud del contenido. 

Si conoce la longitud del contenido en bytes, proporcione el valor exacto:

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

**aviso**  
 Al cargar desde un flujo de entrada, si la longitud del contenido especificada no coincide con el recuento real de bytes, es posible que se produzca lo siguiente:  
Objetos truncados si la longitud especificada es demasiado pequeña
Errores de carga o conexiones bloqueadas si la longitud especificada es demasiado grande

### Si no conoce la longitud del flujo
<a name="s3-stream-upload-unknown-length"></a>

#### Uso de la API sincrónica
<a name="s3-upload-unknown-sync-client"></a>

Usa: `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;
}
```

Dado que el SDK almacena en búfer de memoria todo el flujo para calcular la longitud del contenido, pueden producirse problemas de memoria con flujos grandes. Si necesita cargar flujos de gran tamaño con el cliente sincrónico, considere usar la API multiparte:

##### Cargue un flujo mediante la API de cliente sincrónica y la API multiparte
<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 la mayoría de los casos de uso, recomendamos utilizar la API de cliente asincrónica para los flujos de tamaño desconocido. Este método permite transferencias paralelas y ofrece una interfaz de programación más sencilla, ya que el SDK controla la segmentación de flujos en fragmentos multiparte si el flujo es grande.   
Tanto el cliente asincrónico estándar de S3 con mutiparte habilitada como el cliente de S3 basado en AWS CRT implementan este método. Mostramos ejemplos de este método en la siguiente sección.

#### Uso de la API asincrónica
<a name="s3-stream-upload-unknown-async-client"></a>

Puede proporcionar `null` para el argumento `contentLength` a `fromInputStream(InputStream inputStream, Long contentLength, ExecutorService executor)`

**Example utilizando el cliente asíncrono AWS basado en 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 utilizando el cliente asincrónico estándar con multiparte habilitada:**  

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

# Trabaja con Amazon S3 prefirmado URLs
<a name="examples-s3-presign"></a>

Los prefirmados URLs proporcionan acceso temporal a objetos privados de S3 sin necesidad de que los usuarios tengan AWS credenciales o permisos. 

Por ejemplo, supongamos que Alice tiene acceso a un objeto S3 y desea compartir temporalmente el acceso a ese objeto con Bob. Alice puede generar una solicitud GET prefirmada para compartir con Bob de forma que pueda descargar el objeto sin requerir acceso a las credenciales de Alice. Puede generar solicitudes prefirmadas URLs para HTTP GET y HTTP PUT.

## Genere una URL prefirmada para un objeto y, a continuación, descárguela (solicitud GET)
<a name="get-presignedobject"></a>

El siguiente ejemplo consta de dos partes.
+ Parte 1: Alice genera la URL prefirmada de un objeto.
+ Parte 2: Bob descarga el objeto mediante la URL prefirmada.

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

Alice ya tiene un objeto en un bucket S3. Usa el siguiente código para generar una cadena URL que Bob puede usar en una solicitud GET posterior.

#### Importaciones
<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: Descargar el objeto
<a name="get-presigned-object-part2"></a>

Bob usa una de las siguientes tres opciones de código para descargar el objeto. Como alternativa, podría usar un navegador para realizar la solicitud GET.

#### Usar JDK `HttpURLConnection` (desde la versión 1.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 JDK `HttpClient` (desde la 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` desde el 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();
    }
```

Consulta el [ejemplo completo y [pruébalo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/test/java/com/example/s3/presignurl/GeneratePresignedGetUrlTests.java)](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedGetUrlAndRetrieve.java). GitHub

## Genere una URL prefirmada para una carga y, a continuación, cargue un archivo (solicitud PUT)
<a name="put-presignedobject"></a>

El siguiente ejemplo consta de dos partes.
+ Parte 1: Alice genera la URL prefirmada para cargar un objeto.
+ Parte 2: Bob carga un archivo mediante la URL prefirmada.

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

Alice ya tiene un bucket de S3. Usa el siguiente código para generar una cadena URL que Bob puede usar en una solicitud PUT posterior.

#### Importaciones
<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: Cargar un objeto de archivo
<a name="put-presigned-object-part2"></a>

Bob usa una de las siguientes tres opciones de código para cargar un archivo.

#### Usar JDK `HttpURLConnection` (desde la versión 1.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 JDK `HttpClient` (desde la 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` desde el 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);
        }
    }
```

Consulta el [ejemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedUrlAndPutFileWithMetadata.java) y [sigue probando](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/test/java/com/example/s3/presignurl/GeneratePresignedPutUrlTests.java) GitHub.

# Acceso entre regiones de Amazon S3
<a name="s3-cross-region"></a>

Cuando trabaja con buckets de Amazon Simple Storage Service (Amazon S3), normalmente sabe cuál es la Región de AWS del bucket. La región con la que trabaja se determina al crear el cliente S3. 

Sin embargo, a veces necesitará trabajar con un bucket específico, pero no sabe si se encuentra en la misma región que está configurada para el cliente S3. 

En lugar de hacer más llamadas para determinar la región del bucket, puede usar el SDK para habilitar el acceso a los buckets de S3 en distintas regiones.

## Configuración
<a name="s3-cross-region-setup"></a>

El acceso entre regiones comenzó a estar disponible con la versión `2.20.111` del SDK. Use esta versión o una posterior en su archivo de compilación de Maven para la dependencia `s3`, como se muestra en el siguiente fragmento.

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

Después, cuando cree su cliente S3, habilite el acceso entre regiones, como se muestra en el fragmento. El acceso no está habilitado de forma predeterminada.

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

## Cómo proporciona el SDK acceso entre regiones
<a name="s3-cross-region-routing"></a>

Al hacer referencia a un bucket existente en una solicitud, como cuando utiliza el método `putObject`, el SDK inicia una solicitud a la Región configurada para el cliente. 

Si el bucket no existe en esa región específica, la respuesta al error incluye la región real en la que reside el bucket. A continuación, el SDK utiliza la región correcta en una segunda solicitud.

Para optimizar las futuras solicitudes al mismo bucket, el SDK almacena en caché esta asignación de regiones en el cliente.

## Consideraciones
<a name="s3-cross-region-considerations"></a>

Cuando active el acceso a los buckets entre regiones, tenga en cuenta que la primera llamada a la API puede provocar un aumento de la latencia si el bucket no se encuentra en la región configurada del cliente. Sin embargo, las llamadas posteriores se benefician de la información regional almacenada en caché, lo que mejora el rendimiento.

Al habilitar el acceso entre regiones, el acceso al bucket no se ve afectado. El usuario debe estar autorizado a acceder al bucket en cualquier región en la que resida.

# Protección de la integridad de los datos con sumas de comprobación
<a name="s3-checksums"></a>

Amazon Simple Storage Service (Amazon S3) permite especificar una suma de comprobación al cargar un objeto. Cuando se especifica una suma de comprobación, esta se almacena con el objeto y se puede validar cuando se descarga el objeto.

Las sumas de comprobación proporcionan un nivel adicional de integridad de los datos al transferir archivos. Con las sumas de comprobación, puede comprobar la coherencia de datos verificando que el archivo recibido coincide con el archivo original. Para obtener más información sobre las sumas de comprobación con Amazon S3, consulte la [Guía del usuario de Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html), que incluye los [algoritmos compatibles](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#using-additional-checksums).

Puede elegir el algoritmo que mejor se adapte a sus necesidades y dejar que el SDK calcule la suma de comprobación. También puede especificar un valor de suma de comprobación precalculada mediante uno de los algoritmos compatibles. 

**nota**  
A partir de la versión 2.30.0 de AWS SDK for Java 2.x, el SDK proporciona protecciones de integridad predeterminadas mediante el cálculo automático de una suma de comprobación de `CRC32` para las cargas. El SDK calcula esta suma de comprobación si no se proporciona un valor de suma de comprobación precalculado o si no se especifica un algoritmo que el SDK deba utilizar para calcular una suma de comprobación.   
El SDK también proporciona una configuración global para las protecciones de la integridad de los datos que puede configurar de forma externa, sobre la que puede leer en la Guía de referencia de [herramientas AWS SDKs y herramientas](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html).

Analizaremos las sumas de comprobación en dos fases de solicitud: carga del objeto y descarga del objeto. 

## Cargar un objeto
<a name="use-service-S3-checksum-upload"></a>

Al cargar un objeto con el método `putObject` y proporcionar un algoritmo de suma de comprobación, el SDK calcula la suma de comprobación del algoritmo especificado.

El siguiente fragmento de código muestra una solicitud para cargar un objeto con una suma de comprobación `SHA256`. Cuando el SDK envía la solicitud, calcula la suma de comprobación de `SHA256` y carga el objeto. Amazon S3 valida la integridad del contenido calculando la suma de comprobación y comparándola con la suma de comprobación proporcionada por el SDK. A continuación, Amazon S3 almacena la suma de comprobación con el objeto.

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

Si no proporciona un algoritmo de suma de comprobación con la solicitud, el comportamiento de la suma de comprobación varía en función de la versión del SDK que utilice, tal y como se muestra en la siguiente tabla.

**Comportamiento de la suma de comprobación cuando no se proporciona ningún algoritmo de suma de comprobación**


| Versión del SDK de Java | Comportamiento de la suma de comprobación | 
| --- | --- | 
| anterior a la versión 2.30.0 | El SDK no calcula automáticamente una suma de comprobación basada en CRC ni la proporciona en la solicitud. | 
| 2.30.0 o posterior | El SDK usa el algoritmo `CRC32` para calcular la suma de comprobación y la proporciona en la solicitud. Amazon S3 valida la integridad de la transferencia calculando su propia suma de comprobación `CRC32` y la compara con la suma de comprobación proporcionada por el SDK. Si las sumas de comprobación coinciden, la suma de comprobación se guarda con el objeto. | 

### Utilizar un valor de suma de comprobación calculado previamente
<a name="use-service-S3-checksum-upload-pre"></a>

Un valor de suma de comprobación precalculado proporcionado con la solicitud desactiva el cálculo automático por parte del SDK y utiliza el valor proporcionado en su lugar.

El siguiente ejemplo muestra una solicitud con una suma de control calculada previamente SHA256.

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

Si Amazon S3 determina que el valor de la suma de comprobación es incorrecto para el algoritmo especificado, el servicio devuelve una respuesta de error.

### Cargas multiparte
<a name="use-service-S3-checksum-upload-multi"></a>

También puede utilizar sumas de comprobación en las cargas multiparte.

 El SDK de Java 2.x ofrece dos opciones para usar sumas de comprobación con cargas multiparte. La primera opción usa `S3TransferManager`.

En el siguiente ejemplo de gestor de transferencias se especifica el SHA1 algoritmo de la carga.

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

Si no proporciona un algoritmo de suma de comprobación al utilizar el administrador de transferencias para cargas, el SDK calcula automáticamente una suma de comprobación basada en el algoritmo `CRC32`. El SDK realiza este cálculo para todas las versiones del SDK.

La segunda opción usa la [API `S3Client`](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) (o la [API `S3AsyncClient`](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)) para llevar a cabo la carga multiparte. Si especifica una suma de comprobación con este método, debe especificar el algoritmo que se utilizará al iniciar la carga. También debe especificar el algoritmo para cada solicitud de parte y proporcionar la suma de comprobación calculada para cada parte una vez cargada.

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

El [código de los ejemplos y [las pruebas](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) se encuentra en el repositorio GitHub de ejemplos de código.

## Descargar un objeto
<a name="use-service-S3-checksum-download"></a>

Cuando se utiliza el 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 descargar un objeto, el SDK valida automáticamente la suma de comprobación  cuando el método `checksumMode` del compilador de `GetObjectRequest` se establece como `ChecksumMode.ENABLED`.  

La solicitud del siguiente fragmento indica al SDK que valide la suma de comprobación de la respuesta calculándola y comparando los valores.

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

**nota**  
Si el objeto no se cargó con una suma de comprobación, no se realizará ninguna validación. 

## Otras opciones de cálculo de la suma de comprobación
<a name="S3-checsum-calculation-options"></a>

**nota**  
Para verificar la integridad de los datos transmitidos e identificar errores de transmisión, recomendamos a los usuarios que mantengan la configuración predeterminada del SDK para las opciones de cálculo de la suma de comprobación. De forma predeterminada, el SDK agrega esta importante comprobación a muchas operaciones de S3, incluidas `PutObject` y `GetObject`.

Sin embargo, si el uso de Amazon S3 requiere una validación mínima de la suma de comprobación, puede deshabilitar muchas comprobaciones cambiando los ajustes de configuración predeterminados. 

### Deshabilite el cálculo automático de la suma de comprobación a menos que sea necesario
<a name="S3-minimize-checksum-calc-global"></a>

Puede deshabilitar el cálculo automático de la suma de comprobación mediante el SDK para las operaciones que lo admiten, por ejemplo, `PutObject` y `GetObject`. Sin embargo, algunas operaciones de S3 requieren un cálculo de la suma de comprobación; no se puede deshabilitar el cálculo de la suma de comprobación para estas operaciones.

El SDK proporciona ajustes independientes para el cálculo de una suma de comprobación de la carga útil de una solicitud y de la carga útil de una respuesta.

En la siguiente lista se describen las configuraciones que puede usar para minimizar los cálculos de la suma de comprobación en los distintos ámbitos.
+ **Alcance de todas las aplicaciones**: al cambiar la configuración de las variables de entorno o de un perfil en los `credentials` archivos AWS `config` AND compartidos, todas las aplicaciones pueden usar esta configuración. Esta configuración afecta a todos los clientes de servicio de todas las aplicaciones AWS del SDK, a menos que se anule en el ámbito del cliente de la aplicación o del servicio.
  + Adición de la configuración a un perfil:

    ```
    [default]
    request_checksum_calculation = WHEN_REQUIRED
    response_checksum_validation = WHEN_REQUIRED
    ```
  + Adición de variables de entorno:

    ```
    AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
    AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
    ```
+ **Ámbito actual de la aplicación**: puede establecer la propiedad del sistema Java en `aws.requestChecksumCalculation` a `WHEN_REQUIRED` para limitar el cálculo de la suma de comprobación. La propiedad del sistema correspondiente para respuestas es `aws.responseChecksumValidation`.

  Esta configuración afecta a todos los clientes de servicio del SDK en la aplicación, a menos que se anulen durante la creación del cliente de servicio.

  Defina la propiedad del sistema en el inicio de la aplicación:

  ```
  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.
      }
  }
  ```
+ **Ámbito de cliente de servicio individual de S3**: puede configurar un cliente de servicio individual de S3 para calcular la cantidad mínima de sumas de comprobación mediante métodos de creación:

  ```
  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. 
      }
  // ...
  }
  ```

### Utilícela `LegacyMd5Plugin` para simplificar la compatibilidad MD5
<a name="S3-checksum-legacy-md5"></a>

Junto con el lanzamiento del comportamiento de las CRC32 sumas de verificación en la versión 2.30.0, el SDK dejó de calcular las MD5 sumas de verificación en las operaciones requeridas.

Si necesitas un comportamiento de MD5 suma de comprobación tradicional para las operaciones de S3, puedes usar el`LegacyMd5Plugin`, que se publicó con la versión 2.31.32 del SDK.

Esto `LegacyMd5Plugin` resulta especialmente útil cuando se necesita mantener la compatibilidad con aplicaciones que dependen del comportamiento anterior de las MD5 sumatorias de comprobación, especialmente cuando se trabaja con proveedores de almacenamiento de terceros compatibles con S3, como los que se utilizan con los conectores de sistemas de archivos S3A (Apache Spark, Iceberg).

Para usar el `LegacyMd5Plugin`, agréguelo al compilador de clientes de 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();
```

Si desea añadir sumas de MD5 comprobación a las operaciones que requieren sumas de comprobación y no quiere añadir las sumas de comprobación predeterminadas del SDK para las operaciones que admiten sumas de comprobación pero que no son obligatorias, puede activar las opciones y como. `ClientBuilder` `requestChecksumCalculation` `responseChecksumValidation` `WHEN_REQUIRED` De este modo se agregarán sumas de comprobación predeterminadas del SDK solo a las operaciones que requieran sumas de comprobación:

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

Esta configuración resulta especialmente útil cuando se trabaja con sistemas de almacenamiento de terceros compatibles con S3 que pueden no ser totalmente compatibles con los algoritmos de suma de comprobación más recientes, pero que aun así requieren sumas de comprobación para determinadas operaciones. MD5 

# Utilice un cliente S3 de alto rendimiento: cliente S3 basado en AWS CRT
<a name="crt-based-s3-client"></a>

El cliente S3 AWS basado en CRT, creado sobre el [AWS Common Runtime (](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html)CRT), es un cliente asíncrono S3 alternativo. Transfiere objetos hacia y desde Amazon Simple Storage Service (Amazon S3) con un rendimiento y una fiabilidad mejorados mediante el uso automático de la API de [carga multiparte de Amazon S3 y de](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) las [recuperaciones por rango de bytes.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range) 

El cliente S3 AWS basado en CRT mejora la fiabilidad de la transferencia en caso de que se produzca un fallo en la red. La fiabilidad se mejora reintentando partes individuales fallidas de una transferencia de archivos sin reiniciar la transferencia desde el principio.

Además, el cliente S3 AWS basado en CRT ofrece una mejor agrupación de conexiones y un equilibrio de carga del sistema de nombres de dominio (DNS) mejorados, lo que también mejora el rendimiento.

Puede utilizar el cliente S3 AWS basado en CRT en lugar del cliente asíncrono S3 estándar del SDK y aprovechar su rendimiento mejorado de forma inmediata.

**importante**  
El cliente S3 AWS basado en CRT actualmente no admite la [recopilación de métricas del SDK](metrics.md) a nivel de cliente ni a nivel de solicitud.

**AWS Componentes basados en CRT en el SDK**

El cliente *S3 AWS * basado en CRT, que se describe en este tema, y el cliente *HTTP AWS * basado en CRT son componentes diferentes del SDK. 

El **cliente S3 AWS basado en CRT** es una implementación de la AsyncClient interfaz [S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) y se utiliza para trabajar con el servicio Amazon S3. Es una alternativa a la implementación de la interfaz `S3AsyncClient` basada en Java y ofrece varias ventajas.

El [cliente HTTP AWS basado en CRT](http-configuration-crt.md) es una implementación de la [SdkAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/async/SdkAsyncHttpClient.html)interfaz y se utiliza para la comunicación HTTP general. Es una alternativa a la implementación Netty de la interfaz `SdkAsyncHttpClient` basada en Java y ofrece varias ventajas.

Si bien ambos componentes utilizan bibliotecas del [AWS Common Runtime](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html), el cliente S3 AWS basado en CRT utiliza la [biblioteca aws-c-s 3](https://github.com/awslabs/aws-c-s3) y admite las funciones de la API de carga [multiparte de S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html). Como el cliente HTTP AWS basado en CRT está diseñado para un uso general, no admite las funciones de la API de carga multiparte de S3.

## Agregue dependencias para usar el cliente S3 basado en CRT AWS
<a name="crt-based-s3-client-depend"></a>

Para usar el cliente S3 AWS basado en CRT, añada las dos dependencias siguientes al archivo de proyecto de Maven. En el ejemplo siguiente se muestran las versiones mínimas que se utilizarán. Busque en el repositorio central de Maven las versiones más recientes de los artefactos [s3](https://central.sonatype.com/artifact/software.amazon.awssdk/s3) y [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>
```

## Cree una instancia del cliente S3 basado en CRT AWS
<a name="crt-based-s3-client-create"></a>

 Cree una instancia del cliente S3 AWS basado en CRT con la configuración predeterminada, como se muestra en el siguiente fragmento de código.

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

Para configurar el cliente, utilice el generador de clientes CRT. AWS Puede cambiar del cliente asíncrono S3 estándar al cliente AWS basado en CRT cambiando el método de creación.

```
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**  
Es posible que algunas de las configuraciones del generador estándar no sean compatibles actualmente con el generador de clientes AWS CRT. Obtener el constructor estándar llamando a `S3AsyncClient#builder()`.

## Utilice el cliente S3 basado en CRT AWS
<a name="crt-based-s3-client-use"></a>

Utilice el cliente S3 AWS basado en CRT para llamar a las operaciones de la API de Amazon S3. En el siguiente ejemplo, se muestran las [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))operaciones [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))y disponibles a través de. 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();
```

## Carga de flujos de tamaño desconocido
<a name="crt-stream-unknown-size"></a>

Una ventaja importante del cliente S3 AWS AWS basado en CRT es su capacidad para gestionar flujos de entrada de tamaño desconocido de manera eficiente. Esto resulta especialmente útil cuando se deben cargar datos desde una fuente en la que el tamaño total no se puede determinar de antemano.

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

Esta capacidad ayuda a evitar problemas comunes de las cargas tradicionales, en los que una especificación incorrecta de la longitud del contenido puede provocar que los objetos se trunquen o fallen las cargas.

## Limitaciones de la configuración
<a name="crt-based-s3-client-limitations"></a>

El cliente S3 AWS basado en CRT y el cliente asíncrono S3 basado en Java [ofrecen funciones comparables, mientras que el cliente S3 basado en CRT ofrece](examples-s3.md#s3-clients) una ventaja de AWS rendimiento. Sin embargo, el cliente S3 basado en AWS CRT carece de los ajustes de configuración que tiene el cliente asíncrono S3 basado en Java. Esta configuración incluye:
+ *Configuración de nivel de cliente:* tiempo de espera de intentos de llamada a la API, interceptores de ejecución de compresión, publicadores de métricas, atributos de ejecución personalizados, opciones avanzadas personalizadas, servicio de ejecutor programado personalizado, encabezados personalizados
+ *Configuración a nivel de solicitud: firmantes* personalizados, tiempo de espera del intento de llamada a la API

Para obtener una lista completa de las diferencias de configuración, consulte la referencia de la API.


| Cliente asincrónico de S3 basado en Java | AWS Cliente S3 basado en CRT | 
| --- | --- | 
| Configuraciones de nivel de cliente[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)Configuraciones de nivel de solicitud[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | Configuraciones de nivel de cliente[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)Configuraciones de nivel de solicitud[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | 

# Configuración del cliente asincrónico S3 basado en Java para usar transferencias paralelas
<a name="s3-async-client-multipart"></a>

Desde la versión 2.27.5, el cliente asincrónico estándar de S3 basado en Java admite transferencias paralelas automáticas (cargas y descargas multiparte). La compatibilidad con las transferencias paralelas se configura al crear el cliente asincrónico de S3 basado en Java. 

En esta sección se muestra cómo habilitar las transferencias paralelas y cómo personalizar la configuración.

## Cree una instancia de `S3AsyncClient`
<a name="s3-async-client-multipart-create"></a>

Cuando se crea una instancia de `S3AsyncClient` sin llamar a ninguno de los métodos `multipart*` en el [generador](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html), no se habilitan las transferencias paralelas. Cada una de las siguientes instrucciones crea un cliente asincrónico de S3 basado en Java sin compatibilidad con cargas y descargas multiparte.

### Creación *sin* compatibilidad multiparte
<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();
```

### Creación *con* compatibilidad multiparte
<a name="s3-async-client-mp-on"></a>

Para habilitar transferencias paralelas con configuración predeterminada, llame al `multipartEnabled` en el generador y pase `true` como se muestra en el siguiente ejemplo.

**Example**  

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

El valor predeterminado es 8 MiB para la configuración de `thresholdInBytes` y `minimumPartSizeInBytes`.

Si personaliza la configuración multiparte, las transferencias paralelas se habilitan automáticamente, como se muestra a continuación.

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

## Carga de flujos de tamaño desconocido
<a name="java-async-client-stream-unknown-size"></a>

El cliente asincrónico de S3 basado en Java con multiparte habilitada puede controlar eficientemente flujos de entrada cuando el tamaño total no se conozca de antemano:

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

Este método evita los problemas que pueden surgir al especificar manualmente una longitud de contenido incorrecta, como objetos truncados o cargas fallidas.

# Transferir archivos y directorios con Amazon S3 Transfer Manager
<a name="transfer-manager"></a>

Amazon S3 Transfer Manager es una utilidad de transferencia de archivos de alto nivel y de código abierto para el AWS SDK for Java 2.x. Úselo para transferir archivos y directorios desde y hacia Amazon Simple Storage Service (Amazon S3). 

Cuando crea sobre el [cliente de S3 basado en CRT de AWS](crt-based-s3-client.md) o el [cliente asincrónico de S3 basado en Java estándar con multiparte habilitada](s3-async-client-multipart.md), S3 Transfer Manager puede aprovechar mejoras del rendimiento, como la [API de carga multiparte](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) y las [recuperaciones de rango de byte](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range). 

Con el S3 Transfer Manager, también puede supervisar el progreso de una transferencia en tiempo real y pausarla para su posterior ejecución.

## Introducción
<a name="transfer-manager-prerequisites"></a>

### Añadir dependencias a su archivo de compilación
<a name="transfer-manager-add-dependency"></a>

Para utilizar el S3 Transfer Manager con rendimiento multiparte mejorado, configure el archivo de compilación con las dependencias necesarias.

------
#### [ 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 [Última versión](https://central.sonatype.com/artifact/software.amazon.awssdk/bom). 2[Última versión](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 [Última versión](https://central.sonatype.com/artifact/software.amazon.awssdk/bom).

------

### Crear una instancia del S3 Transfer Manager
<a name="transfer-manager-create"></a>

Para habilitar la transferencia paralela, debe pasar un cliente S3 basado en AWS CRT O un cliente asíncrono S3 basado en Java con la función multiparte habilitada. El ejemplo siguiente muestra cómo configurar un S3 Transfer Manager con ajustes personalizados. 

------
#### [ 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 ]

Si la dependencia `aws-crt` no está incluida en el archivo de compilación, S3 Transfer Manager se crea sobre el cliente asincrónico de S3 estándar que se utiliza en el SDK para Java 2.x. 

**Configuración personalizada del cliente de S3: requiere multiparte habilitada**

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

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

**Sin configuración del cliente de S3: compatibilidad multiparte habilitada automáticamente**

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

------

## Cargar un archivo en un bucket de S3
<a name="transfer-manager-upload"></a>

El siguiente ejemplo muestra un ejemplo de carga de archivos junto con el uso opcional de a [LoggingTransferListener](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/LoggingTransferListener.html), que registra el progreso de la carga.

Para cargar un archivo en Amazon S3 mediante el S3 Transfer Manager, pase un 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) al 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)) del `S3TransferManager`.

El [FileUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/FileUpload.html)objeto devuelto por el `uploadFile` método representa el proceso de carga. Una vez finalizada la solicitud, el [CompletedFileUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedFileUpload.html)objeto contiene información sobre la carga.

```
    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!
        */
    }
```

### Importaciones
<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;
```

## Descargar un archivo de un bucket de S3
<a name="transfer-manager-download"></a>

El siguiente ejemplo muestra un ejemplo de descarga junto con el uso opcional de un [LoggingTransferListener](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/LoggingTransferListener.html), que registra el progreso de la descarga.

Para descargar un objeto de un bucket de S3 mediante el administrador de transferencias de S3, cree un [DownloadFileRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DownloadFileRequest.html)objeto y páselo al 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)).

El [FileDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/FileDownload.html)objeto devuelto por el `downloadFile` método `S3TransferManager`'s representa la transferencia de archivos. Una vez completada la descarga, [CompletedFileDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedFileDownload.html)contiene el acceso a la información sobre la descarga.

```
    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!
        */
    }
```

### Importaciones
<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;
```

## Copiar un objeto de Amazon S3 a otro bucket
<a name="transfer-manager-copy"></a>

En el siguiente ejemplo se muestra cómo copiar un objeto con S3 Transfer Manager.

Para empezar a copiar un objeto de un bucket de S3 a otro bucket, cree una [CopyObjectRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/CopyObjectRequest.html)instancia básica.

A continuación, incluya la básica `CopyObjectRequest` en una [CopyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CopyRequest.html)que pueda utilizar el S3 Transfer Manager. 

El objeto `Copy` devuelto por el método `copy` de `S3TransferManager` representa el proceso de copia. Una vez finalizado el proceso de copia, el [CompletedCopy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedCopy.html)objeto contiene detalles sobre la respuesta.

```
    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 una copia entre regiones con el administrador de transferencias de S3, habilítelo `crossRegionAccessEnabled` en el generador de clientes S3 AWS basado en CRT, tal y como se muestra en el siguiente fragmento.  

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

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

### Importaciones
<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;
```

## Cargar un directorio local en un bucket de S3
<a name="transfer-manager-upload_directory"></a>

En el siguiente ejemplo se muestra cómo se puede cargar un directorio local en S3.

Comience por llamar al 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)) de la instancia e introduzca un. `S3TransferManager` [UploadDirectoryRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadDirectoryRequest.html)

El [DirectoryUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DirectoryUpload.html)objeto representa el proceso de carga, que genera un [CompletedDirectoryUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedDirectoryUpload.html)cuando se completa la solicitud. El objeto `CompleteDirectoryUpload` contiene información sobre los resultados de la transferencia, incluidos los archivos que no se pudieron transferir.

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

### Importaciones
<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;
```

## Descargar objetos de bucket S3 en un directorio local
<a name="transfer-manager-download_directory"></a>

Puede descargar los objetos de un bucket S3 en un directorio local tal y como se muestra en el siguiente ejemplo.

Para descargar los objetos de un bucket de S3 a un directorio local, comience por llamar al 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)) del Transfer Manager e introduzca un [DownloadDirectoryRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DownloadDirectoryRequest.html).

El [DirectoryDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DirectoryDownload.html)objeto representa el proceso de descarga, que genera un [CompletedDirectoryDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedDirectoryDownload.html)cuando se completa la solicitud. El objeto `CompleteDirectoryDownload` contiene información sobre los resultados de la transferencia, incluidos los archivos que no se pudieron transferir.

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

### Importaciones
<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;
```

## Vea ejemplos completos
<a name="transfer-manager-example-location"></a>

[GitHub contiene el 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 los ejemplos de esta página.

# Uso de notificaciones de eventos de S3
<a name="examples-s3-event-notifications"></a>

Para ayudarle a monitorizar la actividad de sus buckets, Amazon S3 puede enviar notificaciones cuando se produzcan determinados eventos. La Guía del usuario de Amazon S3 proporciona información sobre las [notificaciones que puede enviar un bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html#notification-how-to-overview). 

Puede configurar un bucket para enviar eventos a cuatro destinos posibles mediante el SDK para Java: 
+ Temas de Amazon Simple Notification Service
+ Colas de Amazon Simple Queue Service
+ AWS Lambda funciones
+ Amazon EventBridge

Cuando configuras un depósito al que enviar eventos EventBridge, tienes la posibilidad de configurar una EventBridge regla para distribuir el mismo evento a varios destinos. Al configurar el bucket para que se envíe directamente a uno de los tres primeros destinos, solo se puede especificar un tipo de destino para cada evento.

En la siguiente sección, verá cómo configurar un bucket mediante el SDK para Java para enviar notificaciones de eventos de S3 de dos maneras: directamente a una cola de Amazon SQS y a. EventBridge

En la última sección se muestra cómo utilizar la API Notificaciones de eventos de S3 para trabajar con notificaciones de una forma orientada a objetos.

## Configuración de un bucket para enviarlo directamente a un destino
<a name="s3-event-conf-bucket-direct"></a>

En el siguiente ejemplo se configura un bucket para enviar notificaciones cuando se produzcan eventos de *creación de objetos* o de *etiquetado de objetos* en un 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)
    );
}
```

El código mostrado configura una cola para recibir dos tipos de eventos. Convenientemente, el método `queueConfigurations` permite configurar varios destinos de cola si es necesario. Además, en el método `notificationConfiguration` puede establecer destinos adicionales, como uno o más temas de Amazon SNS o una o más funciones de Lambda. El siguiente fragmento muestra un ejemplo con dos colas y tres 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)
        );
```

El GitHub repositorio de ejemplos de código contiene el [ejemplo 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 notificaciones de eventos de S3 directamente a una cola.

## Configure un bucket al que enviar EventBridge
<a name="s3-event-conf-bucket-eventbridge"></a>

En el siguiente ejemplo, se configura un depósito al que enviar EventBridge notificaciones.

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

Al configurar un depósito al que enviar eventos EventBridge, solo tiene que indicar el EventBridge destino, no los tipos de eventos ni el destino final al que EventBridge se enviarán. Los objetivos y los tipos de eventos finales se configuran mediante el EventBridge cliente del SDK de Java.

En el siguiente código se muestra cómo configurar EventBridge para distribuir los eventos *creados por objetos* en un tema y una cola.

```
   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 trabajar con él EventBridge en tu código Java, añade una dependencia del `eventbridge` artefacto a tu archivo `pom.xml` Maven.

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

El GitHub repositorio de ejemplos de código contiene el [ejemplo 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 notificaciones de eventos de S3 a, EventBridge y luego, a un tema y una cola.

## Uso de la API Notificaciones de eventos de S3 para procesar eventos
<a name="s3-event-notification-read"></a>

Una vez que un destino recibe eventos de notificación de S3, puede procesarlos de forma orientada a objetos mediante la API Notificaciones de eventos de S3. Puedes usar la API de notificaciones de eventos de S3 para trabajar con las notificaciones de eventos que se envían directamente a un destino (como se muestra en el [primer ejemplo](#s3-event-conf-bucket-direct)), pero no con las notificaciones que se envían directamente. EventBridge Las notificaciones de eventos de S3 se envían mediante buckets para EventBridge contener una [estructura diferente](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ev-events.html#ev-events-list) que la API de notificaciones de eventos de S3 no gestiona actualmente.

### Adición de dependencia
<a name="s3-event-notifications-dep"></a>

La API Notificaciones de eventos de S3 se publicó con la versión 2.25.11 del SDK para Java 2.x.

Para usar la API Notificaciones de eventos de S3, agregue el elemento de dependencia necesario al `pom.xml` de Maven, como se muestra en el siguiente fragmento.

```
<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 [Última versión](https://central.sonatype.com/artifact/software.amazon.awssdk/bom).

### Uso de la clase `S3EventNotification`
<a name="s3-event-notifications-use"></a>

#### Creación de una instancia de `S3EventNotification` a partir de una cadena JSON
<a name="s3-event-notifications-use-from-json"></a>

Para convertir una cadena JSON en un objeto `S3EventNotification`, use los métodos estáticos de la clase `S3EventNotification`, como se muestra en el siguiente ejemplo.

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

En este ejemplo, el método `fromJson` convierte la cadena JSON en un objeto `S3EventNotification`. La falta de campos en la cadena JSON generará valores de `null` en los campos de objetos de Java correspondientes y se ignorará cualquier campo adicional del JSON.

Puedes encontrar otras opciones APIs para un registro de notificaciones de eventos en la referencia de la API. `[S3EventNotificationRecord](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3EventNotificationRecord.html)`

#### Conversión de una instancia de `S3EventNotification` en una cadena JSON
<a name="s3-event-notifications-use-to-json"></a>

Utilice el método `toJson` (o `toJsonPretty`) para convertir un objeto `S3EventNotification` en una cadena JSON, como se muestra en el siguiente ejemplo.

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

Los campos para `GlacierEventData`, `ReplicationEventData`, `IntelligentTieringEventData` y `LifecycleEventData` se excluyen del JSON si son `null`. Los demás campos `null` se serializarán como `null`.

A continuación, se muestra un ejemplo de la salida del método `toJsonPretty` para un evento de etiquetado de objetos de 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
      }
    }
  } ]
}
```

Hay disponible un [ejemplo completo](https://github.com/awsdocs/aws-doc-sdk-examples/blob/75c3daadf750406156fc87fa30ee499a206b4a36/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java#L117) en el GitHub que se muestra cómo utilizar la API para trabajar con las notificaciones recibidas por una cola de Amazon SQS.

## Procese eventos de S3 en Lambda con bibliotecas Java: y AWS SDK for Java 2.x `aws-lambda-java-events`
<a name="s3-event-notif-processing-options"></a>

En lugar de usar el SDK para Java 2.x para procesar las notificaciones de eventos de Amazon S3 en una función Lambda, puede usar `[aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events)` la biblioteca de la versión 3.x.x. AWS mantiene la `aws-lambda-java-events` biblioteca de forma independiente y tiene sus propios requisitos de dependencia. La biblioteca de `aws-lambda-java-events` solo funciona con eventos de S3 en funciones de Lambda, mientras que el SDK para Java 2.x funciona con eventos de S3 en funciones de Lambda, Amazon SNS y Amazon SQS.

Ambos enfoques modelan la carga útil de notificación de eventos de JSON de una manera orientada a objetos con similares. APIs En la tabla siguiente se muestran las notables diferencias entre el uso de los dos métodos.


****  

|  | AWS SDK para Java | aws-lambda-java-events biblioteca | 
| --- | --- | --- | 
| Nomenclatura del paquete |  `software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification`  | com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification | 
| Parámetro RequestHandler |  Escriba la implementación `RequestHandler` de la función de Lambda para recibir una cadena 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>  | Escriba la implementación RequestHandler de la función de Lambda para recibir un 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> | 
| dependencias 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>  | 