I am trying to upload files to Amazon S3 storage using Amazon’s Java API for it. The code is
Byte[] b = data.getBytes();
InputStream stream  = new ByteArrayInputStream(b);
//InputStream stream = new FileInputStream(new File("D:/samples/test.txt"));
AWSCredentials credentials = new BasicAWSCredentials("<key>", "<key1>");
AmazonS3 s3client = new AmazonS3Client(credentials);
s3client.putObject(new PutObjectRequest("myBucket",name,stream, new ObjectMetadata()));
When I run the code after commenting the first two lines and uncommenting the third one, ie stream is a FileoutputStream, the file is uploaded correctly. But when data is a base64 encoded String, which is image data, the file is uploaded but image is corrupted.
Amazon documentation says I need to create and attach a POST policy and signature for this to work. How I  can do that in java? I am not using an html form for uploading. 
To upload folders and files to an S3 bucketSign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to upload your folders or files to. Choose Upload.
Convert Image File to Base64 Stringbyte[] fileContent = FileUtils. readFileToByteArray(new File(filePath)); String encodedString = Base64. getEncoder(). encodeToString(fileContent);
First you should remove data:image/png;base64, from beginning of the string:
Sample Code Block:
byte[] bI = org.apache.commons.codec.binary.Base64.decodeBase64((base64Data.substring(base64Data.indexOf(",")+1)).getBytes());
InputStream fis = new ByteArrayInputStream(bI);
AmazonS3 s3 = new AmazonS3Client();
Region usWest02 = Region.getRegion(Regions.US_WEST_2);
s3.setRegion(usWest02);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(bI.length);
metadata.setContentType("image/png");
metadata.setCacheControl("public, max-age=31536000");
s3.putObject(BUCKET_NAME, filename, fis, metadata);
s3.setObjectAcl(BUCKET_NAME, filename, CannedAccessControlList.PublicRead);
                        Here's a DTO class that takes in the base64Image data passed in directly from your client and parsed into its different components that can easily be passed in your uploadToAwsS3 method:
public class Base64ImageDto {
    private byte[] imageBytes;
    private String fileName;
    private String fileType;
    private boolean hasErrors;
    private List<String> errorMessages;
    private static final List<String> VALID_FILE_TYPES = new ArrayList<String>(3);
    static {
        VALID_FILE_TYPES.add("jpg");
        VALID_FILE_TYPES.add("jpeg");
        VALID_FILE_TYPES.add("png");
    }
    public Base64ImageDto(String b64ImageData, String fileName) {
        this.fileName = fileName;
        this.errorMessages = new ArrayList<String>(2);
        String[] base64Components = b64ImageData.split(",");
        if (base64Components.length != 2) {
            this.hasErrors = true;
            this.errorMessages.add("Invalid base64 data: " + b64ImageData);
        }
        if (!this.hasErrors) {
            String base64Data = base64Components[0];
            this.fileType = base64Data.substring(base64Data.indexOf('/') + 1, base64Data.indexOf(';'));
            if (!VALID_FILE_TYPES.contains(fileType)) {
                this.hasErrors = true;
                this.errorMessages.add("Invalid file type: " + fileType);
            }
            if (!this.hasErrors) {
                String base64Image = base64Components[1];
                this.imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);
            }
        }
    }
    public byte[] getImageBytes() {
        return imageBytes;
    }
    public void setImageBytes(byte[] imageBytes) {
        this.imageBytes = imageBytes;
    }
    public boolean isHasErrors() {
        return hasErrors;
    }
    public void setHasErrors(boolean hasErrors) {
        this.hasErrors = hasErrors;
    }
    public List<String> getErrorMessages() {
        return errorMessages;
    }
    public void setErrorMessages(List<String> errorMessages) {
        this.errorMessages = errorMessages;
    }
    public String getFileType() {
        return fileType;
    }
    public void setFileType(String fileType) {
        this.fileType = fileType;
    }
    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}
And here's the method you can add to your AwsS3Service that will put the object up there (Note: You might not be using a transfer manager to manage your puts so you'll need to change that code accordingly):
public void uploadBase64Image(Base64ImageDto base64ImageDto, String pathToFile) {
    InputStream stream = new ByteArrayInputStream(base64ImageDto.getImageBytes());
    ObjectMetadata metadata = new ObjectMetadata();
    metadata.setContentLength(base64ImageDto.getImageBytes().length);
    metadata.setContentType("image/"+base64ImageDto.getFileType());
    String bucketName = awsS3Configuration.getBucketName();
    String key = pathToFile + base64ImageDto.getFileName();
    try {
        LOGGER.info("Uploading file " + base64ImageDto.getFileName() + " to AWS S3");
        PutObjectRequest objectRequest = new PutObjectRequest(bucketName, key, stream, metadata);
        objectRequest.setCannedAcl(CannedAccessControlList.PublicRead);
        Upload s3FileUpload = s3TransferManager.upload(objectRequest);
        s3FileUpload.waitForCompletion();
    } catch (Exception e) {
        e.printStackTrace();
        LOGGER.info("Error uploading file " + base64ImageDto.getFileName() + " to AWS S3");
    }      
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With