Subir archivo de Amazon S3 y obtener URL

94

¿Es posible cargar un archivo txt / pdf / png en Amazon S3 en una sola acción y obtener la URL del archivo cargado como respuesta? Si es así, ¿AWS Java SDK es la biblioteca correcta que necesito agregar en mi aplicación web java struts2?

Sugiéreme una solución para esto.

Sangram Anand
fuente

Respuestas:

-35

Para hacer público el archivo antes de cargarlo, puede usar el #withCannedAclmétodo de PutObjectRequest:

myAmazonS3Client.putObject(new PutObjectRequest('some-grails-bucket',  'somePath/someKey.jpg', new    File('/Users/ben/Desktop/photo.jpg')).withCannedAcl(CannedAccessControlList.PublicRead))
Michael Astreiko
fuente
46
¿Cómo obtengo el enlace de esta solicitud?
Andreas Rudolph
60
Esto no nos dice cómo obtener la URL pública del recurso cargado.
Valentin Waeselynck
107

No, no puede obtener la URL en una sola acción, sino en dos :)

En primer lugar, es posible que deba hacer público el archivo antes de cargarlo porque no tiene sentido obtener la URL a la que nadie puede acceder. Puede hacerlo configurando ACL como sugirió Michael Astreiko. Puede obtener la URL del recurso llamando getResourceUrlo getUrl.

AmazonS3Client s3Client = (AmazonS3Client)AmazonS3ClientBuilder.defaultClient();
s3Client.putObject(new PutObjectRequest("your-bucket", "some-path/some-key.jpg", new File("somePath/someKey.jpg")).withCannedAcl(CannedAccessControlList.PublicRead))
s3Client.getResourceUrl("your-bucket", "some-path/some-key.jpg");

Nota 1: La diferencia entre getResourceUrly getUrles que getResourceUrl devolverá un valor nulo cuando se produzca una excepción.

Nota 2: el getUrl método no está definido en la interfaz de AmazonS3. Debe convertir el objeto a AmazonS3Client si usa el constructor estándar.

hussachai
fuente
27
Vale la pena señalar que esto solo da como resultado una única llamada a AWS. Si profundiza en el SDK de Java, verá que s3Client.getResourceUrl("your-bucket", "some-path/some-key.jpg")funciona la URL sin una llamada a AWS.
sihil
3
Esta realmente debería ser la respuesta recomendada. La otra respuesta falla para los casos en los que el nombre de archivo incluye espacios. En tales escenarios, el nombre de archivo que se muestra en S3 y el sufijo de URL son diferentes entre sí. El método s3Client.getUrl anterior maneja este escenario correctamente
RvPr
3
Tenga en getResourceUrlcuenta que no está en el último sdk.
Martín Serrano
6
para el último sdk s3Client.getUrl("your-bucket", "some-path/some-key.jpg").toString();obtendrá la URL pública.
kristianva
2
Para versiones de SDK aún más nuevas, pruebes3Client.utilities().getUrl(getUrlRequest);
mrog
84

Puede resolverlo usted mismo con el depósito y el nombre de archivo que especifique en la solicitud de carga.

por ejemplo, si su depósito es mybuckety su archivo se llama myfilename:

https://mybucket.s3.amazonaws.com/myfilename

El s3bit será diferente según la región en la que se encuentre su depósito. Por ejemplo, uso la región del sudeste asiático, por lo que mis URL son como:

https://mybucket.s3-ap-southeast-1.amazonaws.com/myfilename
Jeffrey Kemp
fuente
Después de cargar el archivo desde la consola de administración de AWS, los siguientes vínculos funcionan para un solo archivo, por lo que cuál podría ser la respuesta. S3.amazonaws.com/cdn.generalsentiment.com/MVR/reports/… - cdn.generalsentiment. com.s3.amazonaws.com/MVR/reports/… - cdn.generalsentiment.com/MVR/reports/…
Sangram Anand
1
Sí, existen variaciones de la URL que deberían funcionar. Elija el que desee usar y vaya con él.
Jeffrey Kemp
Kool .. gracias por la información .. Por cierto, la parte de carga la voy a hacer con la biblioteca sdk de AWS, ¿verdad?
Sangram Anand
Sí, así lo creo. Pero no tengo experiencia con struts.
Jeffrey Kemp
Casi he terminado con la carga ... pero tuve problemas con los permisos. ¿Hay alguna forma en el sdk de AWS java para S3 para permitirnos hacer público un archivo antes de cargarlo?
Sangram Anand
6

Las respuestas de @hussachai y @Jeffrey Kemp son bastante buenas. Pero tienen algo en común: la URL devuelta es de estilo de host virtual, no de estilo de ruta. Para obtener más información sobre el estilo de URL s3, puede consultar Estilos de URL de AWS S3 . En el caso de que algunas personas quieran que se genere la URL s3 de estilo de ruta. Este es el paso. Básicamente, todo será igual a las respuestas de @hussachai y @Jeffrey Kemp, solo con un cambio de configuración de línea como se muestra a continuación:

AmazonS3Client s3Client = (AmazonS3Client) AmazonS3ClientBuilder.standard()
                    .withRegion("us-west-2")
                    .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                    .withPathStyleAccessEnabled(true)
                    .build();

// Upload a file as a new object with ContentType and title specified.
PutObjectRequest request = new PutObjectRequest(bucketName, stringObjKeyName, fileToUpload);
s3Client.putObject(request);
URL s3Url = s3Client.getUrl(bucketName, stringObjKeyName);
logger.info("S3 url is " + s3Url.toExternalForm());

Esto generará una URL como: https://s3.us-west-2.amazonaws.com/mybucket/myfilename

James
fuente
5

Del mismo modo, si desea un enlace a través de s3Client, puede usarlo a continuación.

System.out.println("filelink: " + s3Client.getUrl("your_bucket_name", "your_file_key"));
Omkar Ayachit
fuente
2

un poco viejo, pero aún para cualquiera que se encuentre con esto en el futuro:

puede hacerlo con una línea asumiendo que ya escribió CredentialProvider y AmazonS3Client.

se verá así:

 String ImageURL = String.valueOf(s3.getUrl(
                                  ConstantsAWS3.BUCKET_NAME, //The S3 Bucket To Upload To
                                  file.getName())); //The key for the uploaded object

y si no escribió CredentialProvider y AmazonS3Client, simplemente agréguelos antes de obtener la URL como esta:

  CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
        getApplicationContext(),
        "POOL_ID", // Identity pool ID
        Regions.US_EAST_1 // Region
);
jaula
fuente
1

Para AWS SDK 2+

String key = "filePath";
String bucketName = "bucketName";
PutObjectResponse response = s3Client
            .putObject(PutObjectRequest.builder().bucket(bucketName ).key(key).build(), RequestBody.fromFile(file));
 GetUrlRequest request = GetUrlRequest.builder().bucket(bucketName ).key(key).build();
 String url = s3Client.utilities().getUrl(request).toExternalForm();
Bala
fuente
0
        System.out.println("Link : " + s3Object.getObjectContent().getHttpRequest().getURI());

con esto, puede recuperar el enlace del archivo ya cargado al depósito S3.

Omkar Ayachit
fuente
0

El método siguiente carga el archivo en una carpeta particular en un depósito y devuelve la URL generada del archivo cargado.

private String uploadFileToS3Bucket(final String bucketName, final File file) {
    final String uniqueFileName = uploadFolder + "/" + file.getName();
    LOGGER.info("Uploading file with name= " + uniqueFileName);
    final PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, uniqueFileName, file);
    amazonS3.putObject(putObjectRequest);
    return ((AmazonS3Client) amazonS3).getResourceUrl(bucketName, uniqueFileName);
}
Ankitech
fuente