Hey guys in this post, we will discuss uploading file to AWS S3 bucket in Spring boot application with full coding example.
Table of Contents
Watch the Video
Complete Example
We will create this example step by step, follow this tutorial till the end
Read More:
- Check the Complete AWS Tutorial
- Check the Complete Spring Boot and Thymeleaf Tutorial
- Check the Complete JavaServer Faces (JSF) Tutorial
- Check the Complete Spring Data JPA Tutorial
- Check the Complete Spring Security Tutorial
- Check the Javascript Projects for Beginners
- Check the Spring Boot JdbcTemplate Tutorials
Create a S3 Bucket on AWS
1. Login in to your AWS account, and go to services, click on the S3 service
2. On the S3 service, click on the Create Bucket option to create new bucket
3. Next enter the Bucket name (give unique name for the bucket), and make sure to Uncheck Block all public access
—
4. Create Access key and Secret key, go to your profile and select My Security Credentials
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-configuredCannedAccessControlList
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
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.