Trabajo con S3 y almacenamiento en la nube en Java con AWS SDK y MinIO
Los almacenes de objetos en la nube compatibles con el protocolo Amazon S3 (Simple Storage Service) se han convertido en el estándar de facto para almacenar datos no estructurados: imágenes, videos, registros, copias de seguridad y artefactos de compilación. En Java, la herramienta principal para interactuar con estos almacenes es el AWS SDK for Java (módulo S3). Sin embargo, para el desarrollo local, las pruebas o el trabajo con soluciones autogestionadas, a menudo se utiliza MinIO, un almacenamiento de alto rendimiento compatible con S3 con su propio cliente Java. En este artículo, veremos ambos enfoques.
1. Preparación y conexión de dependencias
Para comenzar, agregue las dependencias a su pom.xml (Maven):
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.30.0</version></dependency>
<!-- Para MinIO (alternativa a AWS SDK) --><dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.17</version></dependency>2. Creación del cliente S3
Veamos dos formas de crear un cliente: para Amazon S3 (AWS) y para MinIO (almacenamiento local/personalizado).
2.1. Cliente para Amazon S3 (AWS SDK)
Utilice el constructor estático, especificando la región y el método de autenticación (por ejemplo, a través de variables de entorno o un perfil IAM).
import software.amazon.awssdk.regions.Region;import software.amazon.awssdk.services.s3.S3Client;
public class AwsS3Example { public static S3Client createAwsS3Client() { return S3Client.builder() .region(Region.EU_CENTRAL_1) // Frankfurt .build(); // Utiliza la cadena de proveedores predeterminada }}2.2. Cliente para MinIO
MinIO requiere especificar explícitamente el endpoint, access key y secret key.
import io.minio.MinioClient;
public class MinioExample { public static MinioClient createMinioClient() { return MinioClient.builder() .endpoint("http://localhost:9000") .credentials("minioadmin", "minioadmin") .build(); }}3. Operaciones básicas con buckets y objetos
Independientemente del cliente elegido, la lógica de trabajo con S3 es universal. Veamos los escenarios clave.
3.1. Verificación de existencia y creación de un bucket
// AWS SDKpublic boolean bucketExists(S3Client s3, String bucketName) { return s3.headBucket(HeadBucketRequest.builder() .bucket(bucketName) .build()) .sdkHttpResponse().isSuccessful();}
// MinIO SDKpublic boolean bucketExists(MinioClient minio, String bucketName) { return minio.bucketExists(BucketExistsArgs.builder() .bucket(bucketName) .build());}
// Creación de bucket (AWS)s3.createBucket(CreateBucketRequest.builder() .bucket("my-unique-bucket-123") .createBucketConfiguration( CreateBucketConfiguration.builder() .locationConstraint("eu-central-1") .build()) .build());
// Creación de bucket (MinIO)minio.makeBucket(MakeBucketArgs.builder() .bucket("my-local-bucket") .build());3.2. Carga de archivo (Upload)
Carga de un archivo desde una ruta local o desde un flujo de datos.
// AWS SDK - desde archivos3.putObject(PutObjectRequest.builder() .bucket("my-bucket") .key("uploads/report.pdf") .build(), Paths.get("/local/path/report.pdf"));
// MinIO SDK - desde InputStreamtry (InputStream is = new FileInputStream("/local/path/photo.jpg")) { minio.putObject(PutObjectArgs.builder()