AWS S3 Bucket Setup | Spring Boot

Amazon Simple Storage Service which commonly known as Amazon S3. It is an object storage service which offers industry leading data availability, scalability, performance, and security.

In this article we are going to learn how to setup a AWS S3 Bucket with Spring Boot. For this tutorial we are using the IDE as Intelij IDEA.

Create a new Spring Boot project

Navigate in to File -> New -> Project

Click on Next

Fill the required details and click on Next

Add the Spring Web from the dependencies and click Next. After clicking on Next select a location to save the project and click on finish.

Once the project created, open the pom.xml file and add the below AWS S3 dependency.

    <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.1022</version>
        </dependency>

Complete pom.xml should be similar to below

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aws.s3bucket</groupId>
    <artifactId>s3bucket-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>s3bucket-example</name>
    <description>AWS S3 Bucket Example</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.1022</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

pom.xml

Create a new package named model and add below two classes

AwsS3File.java : This class will hold the object/file information from the S3 bucket.

package com.aws.s3bucket.s3bucketexample.model;

import com.amazonaws.services.s3.model.S3Object;

public class AwsS3File {

    private byte[] data;
    private String contentType;
    private String fileName;
    private S3Object s3Object;

    public byte[] getData() {
        return data;
    }

    public void setData(byte[] data) {
        this.data = data;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public S3Object getS3Object() {
        return s3Object;
    }

    public void setS3Object(S3Object s3Object) {
        this.s3Object = s3Object;
    }
}

AwsS3File.java

ResponseFile.java : Return response of the file. Basically contains the file name and the Base64 String value.

package com.aws.s3bucket.s3bucketexample.model;

public class ResponseFile {

    private String contentType;
    private String base64File;

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public String getBase64File() {
        return base64File;
    }

    public void setBase64File(String base64File) {
        this.base64File = base64File;
    }
}

ResponseFile.java

Create a new package named utill and all the utility related files we are keeping under the utill package. Create a new class named AWSS3Config and this is the configuration file for S3 Bucket.

Change the accessKeyId, secretAccessKey and the region as per your S3 Bucket configurations.

package com.aws.s3bucket.s3bucketexample.utill;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AWSS3Config {

    @Bean
    public AmazonS3 getAmazonS3Client() {
        String accessKeyId = "A23IASDED1233K";
        String secretAccessKey = "XCVADSADasdd+Asc/sdfdASDCXZCVED";
        String region = "ap-southeast-1";

        final BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);
        return AmazonS3ClientBuilder
                .standard()
                .withRegion(Regions.fromName(region))
                .withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials))
                .build();
    }
}

AWSS3Config.java

Now lets create a connector class which access the S3 Bucket through the controller. Create a new class named AwsS3Connector.java. uploadMultipartFilesToAwsS3 is the upload functionality for the S3 Bucket. loadFileDataFromS3 is the function to retrieve image from S3. convertMultiPartToFile uses to convert the Multipart File to Java File format

package com.aws.s3bucket.s3bucketexample.utill;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.util.IOUtils;
import com.aws.s3bucket.s3bucketexample.model.AwsS3File;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Objects;

@Service
public class AwsS3Connector {

    private final AmazonS3 amazonS3;

    @Autowired
    public AwsS3Connector(AmazonS3 amazonS3) {
        this.amazonS3 = amazonS3;
    }

    public boolean uploadMultipartFilesToAwsS3(String bucketName, String objectKey, MultipartFile multipartFile) {
        boolean status = false;
        try {
            System.out.println("inside upload method to awss3::::::::");
            File file = this.convertMultiPartToFile(multipartFile);
            this.amazonS3.putObject(bucketName, objectKey, file);
            status = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return status;
    }

    public AwsS3File loadFileDataFromS3(String bucketName, String objectKey) {
        AwsS3File awsS3File = new AwsS3File();
        try {
            S3Object s3Object = this.amazonS3.getObject(bucketName, objectKey);
            InputStream inputStream = s3Object.getObjectContent();
            awsS3File.setS3Object(s3Object);
            awsS3File.setContentType(s3Object.getObjectMetadata().getContentType());
            awsS3File.setData(IOUtils.toByteArray(inputStream));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return awsS3File;
    }

    private File convertMultiPartToFile(MultipartFile file) throws IOException {
        File convertedFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
        FileOutputStream fos = new FileOutputStream(convertedFile);
        fos.write(file.getBytes());
        fos.close();
        return convertedFile;
    }

}

AwsS3Connector.java

Create a controller package and add a class named AWSS3Controller and change it as below. upload endpoint we are using to upload files in to S3 and getFile we are using to retrieve the image from S3.

package com.aws.s3bucket.s3bucketexample.controller;

import com.aws.s3bucket.s3bucketexample.model.AwsS3File;
import com.aws.s3bucket.s3bucketexample.model.ResponseFile;
import com.aws.s3bucket.s3bucketexample.utill.AwsS3Connector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Base64;

@RestController
@RequestMapping("awsS3controller")
public class AWSS3Controller {

    private final AwsS3Connector awsS3Connector;

    @Autowired
    public AWSS3Controller(AwsS3Connector awsS3Connector) {
        this.awsS3Connector = awsS3Connector;
    }

    @PostMapping("upload")
    public ResponseEntity upload(@RequestParam("file") MultipartFile file,
                                 @RequestParam("imageName") String imageName,
                                 @RequestParam("folderName") String folderName) {
        ResponseEntity responseEntity;

            boolean status = this.awsS3Connector.uploadMultipartFilesToAwsS3("test_bucket" + "/" + folderName.trim(), imageName, file);
            if (status) {
                responseEntity = new ResponseEntity<>( HttpStatus.OK);
            } else {
                responseEntity = new ResponseEntity<>(HttpStatus.BAD_REQUEST);
            }

        return responseEntity;
    }

    @GetMapping("getFile")
    public ResponseFile getFile(@RequestParam("imageName") String imageName,
                                @RequestParam("folderName") String folderName) {
        ResponseFile responseFile = new ResponseFile();
        try {

                AwsS3File awsS3File = this.awsS3Connector.loadFileDataFromS3("test_bucket" + "/" + folderName.trim(), imageName);

                if (awsS3File.getData() != null) {
                    responseFile.setBase64File(Base64.getEncoder().encodeToString(awsS3File.getData()));
                    responseFile.setContentType(awsS3File.getContentType());
                } else {
                    System.out.println("imageName:" + imageName + " folderName:" + folderName + " data not found");
                }

        } catch (NullPointerException e) {
            System.out.println("BucketName:" + folderName + "  imageName:" + imageName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseFile;
    }

}

AWSS3Controller.java

If you have completed every step carefully now you will be able to run the application without any issue. Download the full source code from here

Leave a Reply

Your email address will not be published. Required fields are marked *