AWS S3 con Java

1. Introducción

En este tutorial, aprenderemos cómo interactuar con el sistema de almacenamiento Amazon S3 (Simple Storage Service) mediante programación, desde Java.

Recuerde que S3 tiene una estructura muy simple: cada depósito puede almacenar cualquier cantidad de objetos a los que se puede acceder mediante una interfaz SOAP o una API de estilo REST.

En el futuro, usaremos AWS SDK para Java para crear, enumerar y eliminar depósitos de S3. También cargaremos, enumeraremos, descargaremos, copiaremos, moveremos, cambiaremos el nombre y eliminaremos objetos dentro de estos depósitos.

2. Dependencias de Maven

Antes de comenzar, debemos declarar la dependencia de AWS SDK en nuestro proyecto:

 com.amazonaws aws-java-sdk 1.11.163 

Para ver la última versión, consulte Maven Central.

3. Requisitos previos

Para utilizar AWS SDK, necesitaremos algunas cosas:

  1. Cuenta de AWS: necesitamos una cuenta de Amazon Web Services. Si aún no tienes ninguno, adelante y crea una cuenta
  2. Credenciales de seguridad de AWS: estas son nuestras claves de acceso que nos permiten realizar llamadas programáticas a las acciones de la API de AWS. Podemos obtener estas credenciales de dos formas, ya sea utilizando las credenciales de la cuenta raíz de AWS de la sección de claves de acceso de la página Credenciales de seguridad o utilizando las credenciales de usuario de IAM de la consola de IAM.
  3. Elección de la región de AWS: Tenemos que seleccionar una región de AWS donde queremos almacenar nuestros datos de Amazon S3. Tenga en cuenta que los precios del almacenamiento de S3 varían según la región. Para más detalles, diríjase a la documentación oficial. Para este tutorial, usaremos US East (Ohio) (región us-east-2 )

4. Creación de una conexión de cliente

Primero, necesitamos crear una conexión de cliente para acceder al servicio web de Amazon S3. Vamos a utilizar AmazonS3 interfaz para este propósito:

AWSCredentials credentials = new BasicAWSCredentials( "", "" ); 

Y luego configura el cliente:

AmazonS3 s3client = AmazonS3ClientBuilder .standard() .withCredentials(new AWSStaticCredentialsProvider(credentials)) .withRegion(Regions.US_EAST_2) .build();

5. Operaciones de bucket de Amazon S3

5.1. Crear un depósito

Es importante tener en cuenta que el espacio de nombres del depósito lo comparten todos los usuarios del sistema. Por lo tanto, nuestro nombre de depósito debe ser único en todos los nombres de depósito existentes en Amazon S3 (descubriremos cómo comprobarlo en un momento).

Además, como se especifica en la documentación oficial, los nombres de Bucket deben cumplir con los siguientes requisitos:

  • los nombres no deben contener guiones bajos
  • los nombres deben tener entre 3 y 63 caracteres
  • los nombres no deben terminar con un guión
  • los nombres no pueden contener puntos adyacentes
  • los nombres no pueden contener guiones junto a puntos (p. ej., "my-.bucket.com" y "my.-bucket" no son válidos)
  • los nombres no pueden contener caracteres en mayúscula

Creemos un cubo:

String bucketName = "baeldung-bucket"; if(s3client.doesBucketExist(bucketName)) { LOG.info("Bucket name is not available." + " Try again with a different Bucket name."); return; } s3client.createBucket(bucketName);

Aquí, estamos usando s3client que creamos en el paso anterior. Antes de crear un depósito, comprobamos si nuestro nombre de depósito está disponible o no mediante el método doesBucketExist () . Si este nombre está disponible, usaremos el método createBucket () .

5.2. Listado de cubos

Ahora que hemos creado algunos depósitos, imprimamos una lista de todos los depósitos disponibles en nuestro entorno S3 usando el método listBuckets () . Este método devolverá una lista de todos los depósitos:

List buckets = s3client.listBuckets(); for(Bucket bucket : buckets) { System.out.println(bucket.getName()); }

Esto enumerará todos los depósitos que están presentes en nuestro entorno S3:

baeldung-bucket baeldung-bucket-test2 elasticbeanstalk-us-east-2

5.3. Eliminar un depósito

Es importante asegurarse de que nuestro depósito esté vacío antes de que podamos eliminarlo. De lo contrario, se lanzará una excepción. Además, tenga en cuenta que solo el propietario de un depósito puede eliminarlo independientemente de sus permisos (Políticas de control de acceso):

try { s3client.deleteBucket("baeldung-bucket-test2"); } catch (AmazonServiceException e) { System.err.println("e.getErrorMessage()); return; }

6. Operaciones de objetos de Amazon S3

Un archivo o una colección de datos dentro del bucket de Amazon S3 se conoce como objeto. Podemos realizar varias operaciones en objetos como cargar, listar, descargar, copiar, mover, renombrar y eliminar.

6.1. Carga de objetos

Cargar un objeto es un proceso bastante sencillo. Usaremos un método putObject () que acepta tres parámetros:

  1. bucketName : el nombre del depósito donde queremos subir el objeto
  2. clave : esta es la ruta completa al archivo
  3. archivo : el archivo real que contiene los datos que se van a cargar
s3client.putObject( bucketName, "Document/hello.txt", new File("/Users/user/Document/hello.txt") );

6.2. Listado de objetos

Usaremos el método listObjects () para enumerar todos los objetos disponibles en nuestro depósito S3:

ObjectListing objectListing = s3client.listObjects(bucketName); for(S3ObjectSummary os : objectListing.getObjectSummaries()) { LOG.info(os.getKey()); }

Llamar al método listObjects () del objeto s3client producirá el objeto ObjectListing , que se puede usar para obtener una lista de todos los resúmenes de objetos en el depósito especificado. Solo estamos imprimiendo la clave aquí, pero también hay un par de otras opciones disponibles, como tamaño, propietario, última modificación, clase de almacenamiento, etc.

Esto ahora imprimirá una lista de todos los objetos dentro de nuestro depósito:

Document/hello.txt

6.3. Descarga de un objeto

To download an object, we'll first use the getObject() method on s3client which will return an S3Object object. Once we get this, we'll call getObjectContent() on this to get an S3ObjectInputStream object which behaves like a conventional Java InputStream.

S3Object s3object = s3client.getObject(bucketName, "picture/pic.png"); S3ObjectInputStream inputStream = s3object.getObjectContent(); FileUtils.copyInputStreamToFile(inputStream, new File("/Users/user/Desktop/hello.txt"));

Here, we are using FileUtils.copyInputStreamToFile() method by Apache Commons. You can also visit this Baeldung article to explore other ways to convert an InputStream to a File.

6.4. Copying, Renaming and Moving an Object

We can copy an object by calling copyObject() method on our s3client which accepts four parameters:

  1. source bucket name
  2. object key in source bucket
  3. destination bucket name (it can be same as source)
  4. object key in destination bucket
s3client.copyObject( "baeldung-bucket", "picture/pic.png", "baeldung-bucket2", "document/picture.png" );

Note: We can use a combination of copyObject() method deleteObject() for performing moving and renaming tasks. This will involve copying the object first and then deleting it from its old location.

6.5. Deleting an Object

To delete an Object, we'll call deleteObject() method on s3client and pass the bucket name and object key:

s3client.deleteObject("baeldung-bucket","picture/pic.png");

6.6. Deleting Multiple Objects

To delete multiple objects at once, we'll first create the DeleteObjectsRequest object and pass the bucket name to its constructor. Then we'll pass an array of all the object keys that we want to delete.

Una vez que tenemos este objeto DeleteObjectsRequest , podemos pasarlo al método deleteObjects () de nuestro s3client como argumento. Si tiene éxito, esto eliminará todos los objetos que hemos proporcionado:

String objkeyArr[] = { "document/hello.txt", "document/pic.png" }; DeleteObjectsRequest delObjReq = new DeleteObjectsRequest("baeldung-bucket") .withKeys(objkeyArr); s3client.deleteObjects(delObjReq);

7. Conclusión

En este artículo, nos centramos en los conceptos básicos de la interacción con el servicio web Amazon S3, tanto a nivel de depósito como de objeto.

Como siempre, la implementación completa de este tutorial se puede encontrar en Github.