I have an Spring App(running on AWS Lambda) which gets a file and uploads it on AWS S3.
The Spring Controller sends a MultipartFile to my method, where it's uploaded to AWS S3, using 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);
}
I try to upload a PDF file which has 2 pages with text. After upload, the PDF file(on AWS S3) has 2 blank pages.
Why is the uploaded PDF file blank?
I also tried with other files(like PNG image) and when I open it the image I uploaded is corrupted.
The only thing that worked was when I uploaded a text file.
Can I say I have seen people do this allot, whereby their app, accepts a MultipartFile, and proxy upload it to S3.
Uploading to your App and then S3 honestly is the wrong approach, and has many drawbacks which negate the benefits of using S3 in the first place. Simply generate a pre-signed URL and have your user upload directly to S3. This is preferable for a few reasons but the main ones are:
If you happened to be using Cognito you can also achieve this with 0 backend code using AWS Amplify. Which I highly recommend, but if not then pre-signed URL is the way to go.
Turns out that this will do this trick. Its all about encoding, thanks to the help of @KunLun. In my scenario, file is the multipart file (pdf) that is passed to aws via a POST to the 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);