Spring Boot Upload File to AWS S3





Hey guys in this post, we will discuss uploading file to AWS S3 bucket in Spring boot application with full coding example.

Watch the Video


Complete Example


We will create this example step by step, follow this tutorial till the end

Read More:

Create a S3 Bucket on AWS


1. Login in to your AWS account, and go to services, click on the S3 service

Screenshot-2021-08-13-at-3-05-57-PM

2. On the S3 service, click on the Create Bucket option to create new bucket

Screenshot-2021-08-13-at-3-06-36-PM

3. Next enter the Bucket name (give unique name for the bucket), and make sure to Uncheck Block all public access

Screenshot-2021-08-13-at-3-16-00-PM

Screenshot-2021-08-13-at-3-16-33-PM

4. Create Access key and Secret key, go to your profile and select My Security Credentials

Screenshot-2021-08-13-at-3-31-36-PM

Create spring boot project


There are many different ways to create a spring boot application, you can follow the below articles to create one –

>> Create spring boot application using Spring initializer
>> Create spring boot application in Spring tool suite [STS]
>> Create spring boot application in IntelliJ IDEA

Add maven dependencies


Open pom.xml and add the following dependencies –

<?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.5.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>in.bushansirgur</groupId>
	<artifactId>springboot-file-upload-aws-s3</artifactId>
	<version>1.0.0</version>
	<name>springboot-file-upload-aws-s3</name>
	<description>Spring Boot AWS S3 File Upload</description>
	<properties>
		<java.version>16</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-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>io.awspring.cloud</groupId>
			<artifactId>spring-cloud-aws-context</artifactId>
			<version>2.3.1</version>
		</dependency>

		<dependency>
			<groupId>io.awspring.cloud</groupId>
			<artifactId>spring-cloud-aws-autoconfigure</artifactId>
			<version>2.3.1</version>
		</dependency>
	
	</dependencies>

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

</project>

spring-boot-starter-web dependency for building web applications using Spring MVC. It uses the tomcat as the default embedded container. spring-boot-devtools dependency for automatic reloads or live reload of applications. 





 spring-cloud-aws-context and spring-cloud-aws-autoconfigure dependencies for accessing aws services from spring boot application.

Configure AWS S3 Credentials


Open application.properties file and add the following contents

cloud.aws.credentials.access-key=YOUR_ACCESS_KEY
cloud.aws.credentials.secret-key=YOUR_SECRET_KEY
cloud.aws.region.static=us-east-1
cloud.aws.stack.auto=false

spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB

Make sure to enter your access key and secret key

Create a service


Create FileService.java interface inside src/main/java and add the following contents

package in.bushansirgur.springbootfileupload.service;

import org.springframework.web.multipart.MultipartFile;

public interface FileService {

	String uploadFile(MultipartFile file);
}

Create AWSS3Service.java class inside src/main/java and the following contents. This class implements FileService so we need to override one of the method uploadFile() and provide the implementation for that

package in.bushansirgur.springbootfileupload.service;

import java.io.IOException;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;

@Service
public class AWSS3Service implements FileService{
	@Autowired
	private AmazonS3Client awsS3Client;
	
	@Override
	public String uploadFile(MultipartFile file) {
		
		String filenameExtension = StringUtils.getFilenameExtension(file.getOriginalFilename());
		
		String key = UUID.randomUUID().toString() + "." +filenameExtension;
		
		ObjectMetadata metaData = new ObjectMetadata();
		metaData.setContentLength(file.getSize());
		metaData.setContentType(file.getContentType());
		
		try {
			awsS3Client.putObject("my-videos-bucket-05", key, file.getInputStream(), metaData);
		} catch (IOException e) {
			throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "An exception occured while uploading the file");
		}
		
		awsS3Client.setObjectAcl("my-videos-bucket-05", key, CannedAccessControlList.PublicRead);
		
		return awsS3Client.getResourceUrl("my-videos-bucket-05", key);
	}
}

We will call S3 bucket put() method to store the file, awsS3Client.put() takes 4 parameters,

  • bucketName The name of an existing bucket, to which you have Permission.Write permission.
  • key The key under which to store the specified file.
  • input The input stream containing the data to be uploaded to Amazon S3.
  • metadata Additional metadata instructing Amazon S3 how to handle the uploaded data (e.g. custom user metadata, hooks for specifying content type, etc.).




Next we will set the access control list to public using setObjectAcl(), it takes 3 parameters

  • bucketName The name of the bucket containing the object whose ACL is being set.
  • key The key of the object within the specified bucket whose ACL is being set.
  • acl The new pre-configured CannedAccessControlList for the specified object.

Next we will call getResourceUrl() to get the public URL of the specific file, it takes 2 parameters

  • bucketName
  • key

Create a Rest controller


Create UploadFileController.java class inside src/main/java and add the following contents

package in.bushansirgur.springbootfileupload.controller;

import java.util.HashMap;
import java.util.Map;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import in.bushansirgur.springbootfileupload.service.AWSS3Service;

@RestController
@RequestMapping("/api/file")
public class UploadFileController {
	
	@Autowired
	private AWSS3Service awsS3Service;
	
	@PostMapping
	public ResponseEntity<Map<String, String>> uploadFile(@RequestParam("file") MultipartFile file) {
		String publicURL = awsS3Service.uploadFile(file);
		Map<String, String> response = new HashMap<>();
		response.put("publicURL", publicURL);
		return new ResponseEntity<Map<String, String>>(response, HttpStatus.CREATED);
	}
}

Run the app


Run the application using the below maven command –

mvn spring-boot:run

Open the Postman and enter the following URL –

  • localhost:8080/api/file

Screenshot-2021-08-13-at-4-03-26-PM

Screenshot-2021-08-13-at-4-03-53-PM

That’s it for this post, if you like this post, share this with your friends and colleagues or you can share this within your social media platform. Thanks, I will see you in our next post.



Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

Leave a Reply