In this tutorial, we will learn how to upload, download, and delete files to/from Amazon s3 in the Spring boot project. We will develop Spring Boot REST APIs to upload, download, and delete files to/from Amazon S3.
Amazon simple storage (Amazon S3) is a service offered by Amazon web services that offer scalable, secure, and well-performing object storage.The source code of this tutorial available on our GitHub repository at https://github.com/sourcecodeexamples/spring-boot-amazon-s3-example
Create AWS Free Account
Before we start creating our application, head over to the Amazon console and create an account. You will be given 12 months of free access to various Amazon web services that you can use to test various Amazon services.Create S3 Bucket
After signing up, head over to the Amazon console and search for Amazon S3 then create a new S3 bucket that we will use to store the files we will be uploading from our Spring boot application.Access and secret keys
Create a new access key from the My Security Credentials navigation menu. Copy the access and the secret key generated as we will be using them to access the bucket from the application we will be creating.Technologies used
- Java 8+
- Spring Boot
- Spring Data JPA (Hibernate)
- Maven
- MySQL database
- Lombok
- AWS - Amazon S3
- Eclipse STS IDE
1. Create Spring Boot Project
We’ll use Spring initializr web tool to bootstrap our application.
Go to http://start.spring.io
Select Java in the language section.
Enter Artifact as spring-boot-amazon-s3-example
Add Web, Lombok, Spring Cloud AWS dependencies.
Click Generate to generate and download the project.
Once the project is generated, unzip it and import it into your favorite IDE.
2. Maven Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
3. Configure Amazon S3 Details
Open the application.yml file and add the following content to it:
cloud:
aws:
credentials:
access-key:
secret-key:
region:
static: us-east-2
stack:
auto: false
application:
bucket:
name: spring-boot-amazon-storage
spring:
servlet:
multipart:
enabled: true
file-size-threshold: 2MB
max-file-size: 5MB
max-request-size: 10MB
Make sure that you add Amazon S3 access and secret key in the above file.
4. S3 Storage Config Class
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class StorageConfig {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.credentials.secret-key}")
private String accessSecret;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3 s3Client() {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, accessSecret);
return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region).build();
}
}
5. Service Layer - Upload, Download and Delete to/from Amazon S3
Let's create a StorageService class that holds all the logic to upload, download, and delete files to/from the Amazon S3 server:
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import com.amazonaws.util.IOUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@Service
@Slf4j
public class StorageService {
@Value("${application.bucket.name}")
private String bucketName;
@Autowired
private AmazonS3 s3Client;
public String uploadFile(MultipartFile file) {
File fileObj = convertMultiPartFileToFile(file);
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
s3Client.putObject(new PutObjectRequest(bucketName, fileName, fileObj));
fileObj.delete();
return "File uploaded : " + fileName;
}
public byte[] downloadFile(String fileName) {
S3Object s3Object = s3Client.getObject(bucketName, fileName);
S3ObjectInputStream inputStream = s3Object.getObjectContent();
try {
byte[] content = IOUtils.toByteArray(inputStream);
return content;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String deleteFile(String fileName) {
s3Client.deleteObject(bucketName, fileName);
return fileName + " removed ...";
}
private File convertMultiPartFileToFile(MultipartFile file) {
File convertedFile = new File(file.getOriginalFilename());
try (FileOutputStream fos = new FileOutputStream(convertedFile)) {
fos.write(file.getBytes());
} catch (IOException e) {
log.error("Error converting multipartFile to file", e);
}
return convertedFile;
}
}
6. REST APIs for Upload, Download, and Delete Files
import com.springboot.s3.service.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/file")
public class StorageController {
@Autowired
private StorageService service;
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam(value = "file") MultipartFile file) {
return new ResponseEntity<>(service.uploadFile(file), HttpStatus.OK);
}
@GetMapping("/download/{fileName}")
public ResponseEntity<ByteArrayResource> downloadFile(@PathVariable String fileName) {
byte[] data = service.downloadFile(fileName);
ByteArrayResource resource = new ByteArrayResource(data);
return ResponseEntity
.ok()
.contentLength(data.length)
.header("Content-type", "application/octet-stream")
.header("Content-disposition", "attachment; filename=\"" + fileName + "\"")
.body(resource);
}
@DeleteMapping("/delete/{fileName}")
public ResponseEntity<String> deleteFile(@PathVariable String fileName) {
return new ResponseEntity<>(service.deleteFile(fileName), HttpStatus.OK);
}
}
7. Run Spring Boot Application
We’ve successfully built all the APIs for our application. Let’s now run the app and test the APIs.
Just go to the root directory of the application and type the following command to run it -
$ mvn spring-boot:run
The application will start at Spring Boot’s default tomcat port 8080.
Source code on GitHub:
The source code of this tutorial available on our GitHub repository at https://github.com/sourcecodeexamples/spring-boot-amazon-s3-example
8. Demo
For more details and demo, you can watch this YouTube video:
Comments
Post a Comment