Tengo una aplicación Spring (que se ejecuta en AWS Lambda) que obtiene un archivo y lo carga en AWS S3.
Spring Controller envía un MultipartFile a mi método, donde se carga en AWS S3, utilizando Amazon API Gateway.
public static void uploadFile(MultipartFile mpFile, String fileName) throws IOException{ String dirPath = System.getProperty("java.io.tmpdir", "/tmp"); File file = new File(dirPath + "/" + fileName); OutputStream ops = new FileOutputStream(file); ops.write(mpFile.getBytes()); s3client.putObject("fakebucketname", fileName, file); }Intento cargar un archivo PDF que tiene 2 páginas con texto. Después de la carga, el archivo PDF (en AWS S3) tiene 2 páginas en blanco.
¿Por qué el archivo PDF subido está en blanco?
También probé con otros archivos (como una imagen PNG) y cuando lo abro, la imagen que cargué está dañada.
Lo único que funcionó fue cuando subí un archivo de texto.
¿Puedo decir que he visto a personas hacer esta asignación, por lo que su aplicación acepta un MultipartFile y lo carga por proxy en S3?
Cargar a su aplicación y luego a S3 honestamente es el enfoque incorrecto y tiene muchos inconvenientes que anulan los beneficios de usar S3 en primer lugar. Simplemente genere una URL prefirmada y haga que su usuario cargue directamente a S3. Esto es preferible por algunas razones, pero las principales son:
Si estaba usando Cognito, también puede lograr esto con 0 código de back-end usando AWS Amplify. Lo cual recomiendo encarecidamente, pero si no, la URL prefirmada es el camino a seguir.
Resulta que esto hará este truco. Se trata de codificar, gracias a la ayuda de @KunLun. En mi escenario, el archivo es el archivo de varias partes (pdf) que se pasa a aws a través de un POST a la url.
Base64.Encoder enc = Base64.getEncoder(); byte[] encbytes = enc.encode(file.getBytes()); for (int i = 0; i < encbytes.length; i++) { System.out.printf("%c", (char) encbytes[i]); if (i != 0 && i % 4 == 0) System.out.print(' '); } Base64.Decoder dec = Base64.getDecoder(); byte[] barray2 = dec.decode(encbytes); InputStream fis = new ByteArrayInputStream(barray2); PutObjectResult objectResult = s3client.putObject("xxx", file.getOriginalFilename(), fis, data);