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.
Migre el Transfer Manager de la versión 1 a la versión 2 del AWS SDK para Java
Esta guía de migración describe las principales diferencias entre Transfer Manager v1 y S3 Transfer Manager v2, incluidos los cambios de constructor, las asignaciones de métodos y los ejemplos de código para operaciones comunes. Tras revisar estas diferencias, podrás migrar correctamente tu código de Transfer Manager actual para aprovechar el rendimiento mejorado y las operaciones asincrónicas de la versión 2.
Acerca de la herramienta de migración del SDK AWS
AWS SDK para Java Proporciona una herramienta de migración automatizada que puede migrar gran parte de la API de Transfer Manager de la versión 1 a la versión 2. Sin embargo, la herramienta de migración no admite varias funciones de Transfer Manager de la versión 1. En estos casos, debes migrar manualmente el código de Transfer Manager siguiendo las instrucciones de este tema.
A lo largo de esta guía, los indicadores del estado de la migración muestran si la herramienta de migración puede migrar automáticamente un constructor, un método o una función:
-
✅ Compatible: la herramienta de migración puede transformar automáticamente este código
-
❌ No compatible: debe migrar el código manualmente
Incluso en el caso de los elementos marcados como «compatibles», revisa los resultados de la migración y pruébalos minuciosamente. La migración de Transfer Manager implica cambios significativos en la arquitectura, pasando de operaciones sincrónicas a asíncronas.
Descripción general
S3 Transfer Manager v2 introduce cambios significativos en la API de Transfer Manager. S3 Transfer Manager v2 se basa en operaciones asíncronas y ofrece un mejor rendimiento, especialmente cuando se utiliza el cliente Amazon S3 AWS basado en CRT.
Diferencias clave
-
Paquete:
com.amazonaws.services.s3.transfer
→software.amazon.awssdk.transfer.s3
-
Nombre de la clase:
TransferManager
→S3TransferManager
-
Dependencia del cliente: cliente Amazon S3 sincrónico → Cliente Amazon S3 asíncrono ()
S3AsyncClient
-
Arquitectura: Operaciones sincrónicas → Operaciones asíncronas con
CompletableFuture
-
Rendimiento: mejorado con soporte al cliente basado en CRT AWS
Cambios de alto nivel
Aspecto | V1 | V2 |
---|---|---|
Dependencia de Maven | aws-java-sdk-s3 |
s3-transfer-manager |
Package | com.amazonaws.services.s3.transfer |
software.amazon.awssdk.transfer.s3 |
Clase principal | TransferManager |
S3TransferManager |
Cliente Amazon S3 | AmazonS3 (sincronización) |
S3AsyncClient (asíncrono) |
Tipos de devoluciones | Operaciones de bloqueo | CompletableFuture<T> |
dependencias Maven
V1 | V2 |
---|---|
|
|
1 Última versión.
Migración de constructores de clientes
Constructores compatibles (migración automática)
Constructor V1 | Equivalente a V2 | Estado de migración |
---|---|---|
new TransferManager() |
S3TransferManager.create() |
✅ Compatible |
TransferManagerBuilder.
defaultTransferManager() |
S3TransferManager.create() |
✅ Compatible |
TransferManagerBuilder.
standard().build() |
S3TransferManager.builder().build() |
✅ Compatible |
new TransferManager(AWSCredentials) |
S3TransferManager.builder()
.s3Client(S3AsyncClient.builder()
.credentialsProvider(...).build())
.build() |
✅ Compatible |
new TransferManager(
AWSCredentialsProvider) |
S3TransferManager.builder()
.s3Client(S3AsyncClient.builder()
.credentialsProvider(...).build())
.build() |
✅ Compatible |
Constructores no compatibles (se requiere una migración manual)
Constructor V1 | Equivalente a V2 | Notas sobre migración |
---|---|---|
new TransferManager(AmazonS3) |
Se requiere una migración manual | Cree una S3AsyncClient por separado |
new TransferManager(AmazonS3,
ExecutorService) |
Se requiere una migración manual | Cree un ejecutor S3AsyncClient y configúrelo |
new TransferManager(AmazonS3,
ExecutorService, boolean) |
Se requiere una migración manual | shutDownThreadPools parámetro no compatible |
Ejemplos de migración manual
Código V1:
AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
TransferManager transferManager = new TransferManager(s3Client);
Código V2:
// Create an `S3AsyncClient` with similar configuration
S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
.credentialsProvider(DefaultCredentialsProvider.create())
.build();
// Provide the configured `S3AsyncClient` to the S3 transfer manager builder.
S3TransferManager transferManager = S3TransferManager.builder()
.s3Client(s3AsyncClient)
.build();
Migración del método del cliente
Actualmente, la herramienta de migración admite resumeUpload
métodos básicos copy
download
upload
uploadDirectory
,downloadDirectory
,resumeDownload
,, y.
Métodos de transferencia principales
Método V1 | Método V2 | Cambio de tipo de devolución | Estado de migración |
---|---|---|---|
upload(String, String, File) |
uploadFile(UploadFileRequest) |
Upload → FileUpload |
✅ Compatible |
upload(PutObjectRequest) |
upload(UploadRequest) |
Upload → Upload |
✅ Compatible |
download(String, String, File) |
downloadFile(DownloadFileRequest) |
Download → FileDownload |
✅ Compatible |
download(GetObjectRequest, File) |
downloadFile(DownloadFileRequest) |
Download → FileDownload |
✅ Compatible |
copy(String, String, String, String) |
copy(CopyRequest) |
Copy → Copy |
✅ Compatible |
copy(CopyObjectRequest) |
copy(CopyRequest) |
Copy → Copy |
✅ Compatible |
uploadDirectory(String, String,
File, boolean) |
uploadDirectory(
UploadDirectoryRequest) |
MultipleFileUpload →
DirectoryUpload |
✅ Compatible |
downloadDirectory(String, String, File) |
downloadDirectory(
DownloadDirectoryRequest) |
MultipleFileDownload →
DirectoryDownload |
✅ Compatible |
Métodos de transferencia reanudables
Método V1 | Método V2 | Estado de migración |
---|---|---|
resumeUpload(PersistableUpload) |
resumeUploadFile(ResumableFileUpload) |
✅ Compatible |
resumeDownload(PersistableDownload) |
resumeDownloadFile(ResumableFileDownload) |
✅ Compatible |
Métodos de ciclo de vida
Método V1 | Método V2 | Estado de migración |
---|---|---|
shutdownNow() |
close() |
✅ Compatible |
shutdownNow(boolean) |
Ajuste manualmente el código mediante el close() método |
❌ No compatible |
Métodos de cliente V1 no compatibles
Método V1 | Alternativa V2 | Notas |
---|---|---|
abortMultipartUploads(String, Date) |
Utilice el cliente Amazon S3 de bajo nivel | ❌ No compatible |
getAmazonS3Client() |
Guarda una referencia por separado | ❌ No es compatible; no hay captador en la versión 2 |
getConfiguration() |
Guarda una referencia por separado | ❌ No es compatible; no hay captador en la versión 2 |
uploadFileList(...) |
Realiza múltiples llamadas uploadFile() |
❌ No compatible |
copy métodos con un TransferStateChangeListener parámetro |
Uso de TransferListener |
Consulte el ejemplo de migración manual |
download métodos con un S3ProgressListener parámetro |
Uso de TransferListener |
Consulte el ejemplo de migración manual |
|
Consulte el ejemplo de migración manual | |
upload método con un ObjectMetadataProvider parámetro |
Establece los metadatos en la solicitud | Consulte el ejemplo de migración manual |
uploadDirectory métodos con *Provider parámetros |
Establece etiquetas en la solicitud | Consulte el ejemplo de migración manual |
copy
métodos con un TransferStateChangeListener
parámetro
-
copy(CopyObjectRequest copyObjectRequest, AmazonS3 srcS3, TransferStateChangeListener stateChangeListener)
-
copy(CopyObjectRequest copyObjectRequest, TransferStateChangeListener stateChangeListener)
// V1 ---------------------------------------------------------------------------------------------- // Initialize source S3 client AmazonS3 s3client = AmazonS3ClientBuilder.standard() .withRegion("us-west-2") .build(); // Initialize Transfer Manager TransferManager tm = TransferManagerBuilder.standard() .withS3Client(srcS3) .build(); CopyObjectRequest copyObjectRequest = new CopyObjectRequest( "amzn-s3-demo-source-bucket", "source-key", "amzn-s3-demo-destination-bucket", "destination-key" ); TransferStateChangeListener stateChangeListener = new TransferStateChangeListener() { @Override public void transferStateChanged(Transfer transfer, TransferState state) { //Implementation of the TransferStateChangeListener } }; Copy copy = tm.copy(copyObjectRequest, srcS3, stateChangeListener); // V2 ---------------------------------------------------------------------------------------------- S3AsyncClient s3AsyncClient = S3AsyncClient.builder() .region(Region.US_WEST_2) .build(); S3TransferManager transferManager = S3TransferManager.builder() .s3Client(s3AsyncClient) .build(); // Create transfer listener (equivalent to TransferStateChangeListener in v1) TransferListener transferListener = new TransferListener() { @Override public void transferInitiated(Context.TransferInitiated context) { //Implementation System.out.println("Transfer initiated"); } @Override public void bytesTransferred(Context.BytesTransferred context) { //Implementation System.out.println("Bytes transferred"); } @Override public void transferComplete(Context.TransferComplete context) { //Implementation System.out.println("Transfer completed!"); } @Override public void transferFailed(Context.TransferFailed context) { //Implementation System.out.println("Transfer failed"); } }; CopyRequest copyRequest = CopyRequest.builder() .copyObjectRequest(req -> req .sourceBucket("amzn-s3-demo-source-bucket") .sourceKey("source-key") .destinationBucket("amzn-s3-demo-destination-bucket") .destinationKey("destination-key") ) .addTransferListener(transferListener) // Configure the transferListener into the request .build(); Copy copy = transferManager.copy(copyRequest);
download
métodos con un S3ProgressListener
parámetro
-
download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener)
-
download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis)
-
download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis, boolean resumeOnRetry)
// V1 ---------------------------------------------------------------------------------------------- S3ProgressListener progressListener = new S3ProgressListener() { @Override public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) { long bytes = progressEvent.getBytesTransferred(); ProgressEventType eventType = progressEvent.getEventType(); // Use bytes and eventType as needed } @Override public void onPersistableTransfer(PersistableTransfer persistableTransfer) { } }; Download download1 = tm.download(getObjectRequest, file, progressListener); Download download2 = tm.download(getObjectRequest, file, progressListener, timeoutMillis) Download download3 = tm.download(getObjectRequest, file, progressListener, timeoutMillis, true) // V2 ---------------------------------------------------------------------------------------------- TransferListener transferListener = new TransferListener() { @Override public void transferInitiated(Context.InitializedContext context) { // Equivalent to ProgressEventType.TRANSFER_STARTED_EVENT System.out.println("Transfer initiated"); } @Override public void bytesTransferred(Context.BytesTransferred context) { // Equivalent to ProgressEventType.REQUEST_BYTE_TRANSFER_EVENT long bytes = context.bytesTransferred(); System.out.println("Bytes transferred: " + bytes); } @Override public void transferComplete(Context.TransferComplete context) { // Equivalent to ProgressEventType.TRANSFER_COMPLETED_EVENT System.out.println("Transfer completed"); } @Override public void transferFailed(Context.TransferFailed context) { // Equivalent to ProgressEventType.TRANSFER_FAILED_EVENT System.out.println("Transfer failed: " + context.exception().getMessage()); } }; DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder() .getObjectRequest(getObjectRequest) .destination(file.toPath()) .addTransferListener(transferListener) .build(); // For download1 FileDownload download = transferManager.downloadFile(downloadFileRequest); // For download2 CompletedFileDownload completedFileDownload = download.completionFuture() .get(timeoutMillis, TimeUnit.MILLISECONDS); // For download3, the v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1. // If a download is interrupted, you need to start a new download request.
downloadDirectory
métodos con 4 o más parámetros
-
downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry)
-
downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry, KeyFilter filter)
-
downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, KeyFilter filter)
// V1 ---------------------------------------------------------------------------------------------- KeyFilter filter = new KeyFilter() { @Override public boolean shouldInclude(S3ObjectSummary objectSummary) { //Filter implementation } }; MultipleFileDownload multipleFileDownload = tm.downloadDirectory(bucketName, keyPrefix, destinationDirectory, filter); // V2 ---------------------------------------------------------------------------------------------- // The v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1. // If a download is interrupted, you need to start a new download request. DownloadFilter filter = new DownloadFilter() { @Override public boolean test(S3Object s3Object) { // Filter implementation. } }; DownloadDirectoryRequest downloadDirectoryRequest = DownloadDirectoryRequest.builder() .bucket(bucketName) .filter(filter) .listObjectsV2RequestTransformer(builder -> builder.prefix(keyPrefix)) .destination(destinationDirectory.toPath()) .build(); DirectoryDownload directoryDownload = transferManager.downloadDirectory(downloadDirectoryRequest);
upload
método con ObjectMetadata
parámetro
-
upload(String bucketName, String key, InputStream input, ObjectMetadata objectMetadata)
// V1 ----------------------------------------------------------------------------------------------ObjectMetadata metadata = new ObjectMetadata(); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("text/plain"); // System-defined metadata metadata.setContentLength(22L); // System-defined metadata metadata.addUserMetadata("myKey", "myValue"); // User-defined metadata PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata); Upload upload = transferManager.upload("amzn-s3-demo-bucket", "my-key", inputStream, metadata); // V2 ---------------------------------------------------------------------------------------------- /* When you use an InputStream to upload in V2, you should specify the content length and use `RequestBody.fromInputStream()`. If you don't provide the content length, the entire stream will be buffered in memory. If you can't determine the content length, we recommend using the CRT-based S3 client. */ Map<String, String> userMetadata = new HashMap<>(); userMetadata.put("x-amz-meta-myKey", "myValue"); PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket("amzn-s3-demo-bucket1") .key("k") .contentType("text/plain") //System-defined metadata usually has separate methods in the builder. .contentLength(22L) .metadata(userMetadata) //metadata() is only for user-defined metadata. .build(); UploadRequest uploadRequest = UploadRequest.builder() .putObjectRequest(putObjectRequest) .requestBody(AsyncRequestBody.fromInputStream(stream, 22L, executor)) .build(); transferManager.upload(uploadRequest).completionFuture().join();
uploadDirectory
con ObjectMetadataProvider
parámetro
-
uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider)
-
uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider)
-
uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider, ObjectCannedAclProvider cannedAclProvider)
// V1 ---------------------------------------------------------------------------------------------- tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider) tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider) tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider, cannedAclProvider) // V2 ---------------------------------------------------------------------------------------------- UploadDirectoryRequest request = UploadDirectoryRequest.builder() .bucket(bucketName) .s3Prefix(virtualDirectoryKeyPrefix) .source(directory.toPath()) .maxDepth(includeSubdirectories ? Integer.MAX_VALUE : 1) .uploadFileRequestTransformer(builder -> { // 1.Replace `ObjectMetadataProvider`, `ObjectTaggingProvider`, and `ObjectCannedAclProvider` with an // `UploadFileRequestTransformer` that can combine the functionality of all three *Provider implementations. // 2. Convert your v1 `ObjectMetadata` to v2 `PutObjectRequest` parameters. // 3. Convert your v1 `ObjectTagging` to v2 `Tagging`. // 4. Convert your v1 `CannedAccessControlList` to v2 `ObjectCannedACL`. }) .build(); DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);
Migración de objetos modelo
En AWS SDK for Java 2.x, muchos de los objetos del TransferManager
modelo se han rediseñado y varios métodos de captación y colocación disponibles en los objetos del modelo de la versión 1 ya no son compatibles.
En la versión 2, puedes usar la CompletableFuture<T>
clase para realizar acciones cuando se complete la transferencia, ya sea correctamente o con una excepción. Si es necesario, puedes usar el join()
método para esperar a que se complete.
Objetos principales de transferencia
Clase V1 | Clase V2 | Estado de migración |
---|---|---|
TransferManager |
S3TransferManager |
✅ Compatible |
TransferManagerBuilder |
S3TransferManager.Builder |
✅ Compatible |
Transfer |
Transfer |
✅ Compatible |
AbortableTransfer |
Transfer |
✅ Compatible (sin clase separada) |
Copy |
Copy |
✅ Compatible |
Download |
FileDownload |
✅ Compatible |
Upload |
Upload / FileUpload |
✅ Compatible |
MultipleFileDownload |
DirectoryDownload |
✅ Compatible |
MultipleFileUpload |
DirectoryUpload |
✅ Compatible |
Objetos de persistencia
Clase V1 | Clase V2 | Estado de migración |
---|---|---|
PersistableDownload |
ResumableFileDownload |
✅ Compatible |
PersistableUpload |
ResumableFileUpload |
✅ Compatible |
PersistableTransfer |
ResumableTransfer |
✅ Compatible |
PauseResult<T> |
Objeto reanudable directo | ❌ No compatible |
Objetos de resultado
Clase V1 | Clase V2 | Estado de migración |
---|---|---|
CopyResult |
CompletedCopy |
✅ Compatible |
UploadResult |
CompletedUpload |
✅ Compatible |
Objetos de configuración
Clase V1 | Clase V2 | Estado de migración |
---|---|---|
TransferManagerConfiguration |
MultipartConfiguration (en el cliente Amazon S3) |
✅ Compatible |
TransferProgress |
TransferProgress + TransferProgressSnapshot |
✅ Compatible |
KeyFilter |
DownloadFilter |
✅ Compatible |
Objetos no admitidos
Clase V1 | Alternativa V2 | Estado de migración |
---|---|---|
PauseStatus |
No compatible | ❌ No compatible |
UploadContext |
No compatible | ❌ No compatible |
ObjectCannedAclProvider |
PutObjectRequest.builder().acl() |
❌ No compatible |
ObjectMetadataProvider |
PutObjectRequest.builder().metadata() |
❌ No compatible |
ObjectTaggingProvider |
PutObjectRequest.builder().tagging() |
❌ No compatible |
PresignedUrlDownload |
No compatible | ❌ No compatible |
TransferManagerBuilder migración de configuración
Cambios de configuración
Los cambios de configuración que debe configurar para el administrador de transferencias v2 dependen del cliente S3 que utilice. Puede elegir entre el cliente S3 AWS basado en CRT o el cliente asíncrono S3 estándar basado en Java. Para obtener información sobre las diferencias, consulte el tema. Los clientes de S3 en el AWS SDK for Java 2.x
Cambios de comportamiento
Operaciones asíncronas
V1 (bloqueo):
Upload upload = transferManager.upload("amzn-s3-demo-bucket", "key", file);
upload.waitForCompletion(); // Blocks until complete
V2 (asíncrono):
FileUpload upload = transferManager.uploadFile(UploadFileRequest.builder()
.putObjectRequest(PutObjectRequest.builder()
.bucket("amzn-s3-demo-bucket")
.key("key")
.build())
.source(file)
.build());
CompletedFileUpload result = upload.completionFuture().join(); // Blocks until complete
// Or handle asynchronously:
upload.completionFuture().thenAccept(result -> {
System.out.println("Upload completed: " + result.response().eTag());
});
Gestión de errores
V1: Las transferencias de directorios fallan por completo si se produce un error en alguna subsolicitud.
V2: Las transferencias de directorios se completan correctamente incluso si algunas subsolicitudes fallan. Compruebe si hay errores de forma explícita:
DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);
CompletedDirectoryUpload result = directoryUpload.completionFuture().join();
// Check for failed transfers
if (!result.failedTransfers().isEmpty()) {
System.out.println("Some uploads failed:");
result.failedTransfers().forEach(failed ->
System.out.println("Failed: " + failed.exception().getMessage()));
}
Descarga paralela mediante búsquedas por rango de bytes
Cuando la función de transferencia paralela automática está habilitada en el SDK de la versión 2, S3 Transfer Manager utiliza recuperaciones de rango de bytes para recuperar partes específicas del objeto en paralelo (descarga multiparte). La forma en que se descarga un objeto con la versión 2 no depende de cómo se cargó originalmente. Todas las descargas pueden beneficiarse de un alto rendimiento y simultaneidad.
Por el contrario, con el Transfer Manager de la versión 1, sí importa cómo se cargó originalmente el objeto. El Gestor de transferencias de la versión 1 recupera las partes del objeto de la misma forma en que se cargaron las partes. Si un objeto se cargó originalmente como un objeto único, el Transfer Manager de la versión 1 no puede acelerar el proceso de descarga mediante subsolicitudes.