Spring Boot + AWS S3 Download Bucket File
In this tutorial, we will develop AWS Simple Storage Service (S3) together with Spring Boot Rest API service to download the file from AWS S3 Bucket.
Amazon S3 Tutorial :
What is S3?
Amazon Simple Storage Service (Amazon S3) is an object storage service that provides industry-leading scalability, data availability, security, and performance.
The service can be used as online backup and archiving of data and applications on Amazon Web Services (AWS).
AWS Core S3 Concepts
In 2006, S3 was one of the first services provided by AWS. Many features have been introduced since then, but the core principles of S3 remain Buckets and Objects.
-
AWS Buckets
Buckets are containers for objects that we choose to store. It is necessary to remember that S3 allows the bucket name to be globally unique. -
AWS Objects
Objects are the actual items that we store in S3. They are marked by a key, which is a sequence of Unicode characters with a maximum length of 1,024 bytes in UTF-8 encoding.
Prerequisites
First Create Bucket on Amazon S3 and then Generate Credentials(accessKey and secretKey) to access AWS S3 bucket
Take a look at our suggested posts:
Let's start developing AWS S3 + Spring Boot application.
Create Spring Boot Project
Refer to create Spring Boot S3 Project.Maven Dependency
As seen in previous tutorial, add spring-cloud-starter-aws as given here.
Spring Cloud AWS Configuration
Add AWS configuration and security credentials in application.yml file, as seen in previous tutorial, refer application properties.
Add this logging.level.com.amazonaws.util.EC2MetadataUtils
entry to get rid of EC2MetadataUtils exception.
fails to connect to service endpoint locally
Also we have shown here how to solvecom.amazonaws.util.EC2MetadataUtils: Unable to retrieve the requested metadata (/latest/meta-data/instance-id). Failed to connect to service endpoint
exception.
Amazon S3 Client Configuration
The main class for communicating with S3 is com.amazonaws.services.s3.AmazonS3
.
To access the Amazon S3 web service, we must first establish a client connection. We will use BasicAWSCredentials AmazonS3 interface
with AWS Access Key and AWS Secret Key and then configure the AmazonS3 client by passing
this credential to AWSStaticCredentialsProvider
as shown here.
Implement Service to Download the file from AWS S3 Bucket
Create the S3BucketStorageService to implement the function to download the file from AWS S3 Bucket.
package com.techgeeknext.springbootawss3.service;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@Service
public class S3BucketStorageService {
private Logger logger = LoggerFactory.getLogger(S3BucketStorageService.class);
@Autowired
private AmazonS3 amazonS3Client;
@Value("${application.bucket.name}")
private String bucketName;
/**
* Downloads file using amazon S3 client from S3 bucket
*
* @param keyName
* @return ByteArrayOutputStream
*/
public ByteArrayOutputStream downloadFile(String keyName) {
try {
S3Object s3object = amazonS3Client.getObject(new GetObjectRequest(bucketName, keyName));
InputStream is = s3object.getObjectContent();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[4096];
while ((len = is.read(buffer, 0, buffer.length)) != -1) {
outputStream.write(buffer, 0, len);
}
return outputStream;
} catch (IOException ioException) {
logger.error("IOException: " + ioException.getMessage());
} catch (AmazonServiceException serviceException) {
logger.info("AmazonServiceException Message: " + serviceException.getMessage());
throw serviceException;
} catch (AmazonClientException clientException) {
logger.info("AmazonClientException Message: " + clientException.getMessage());
throw clientException;
}
return null;
}
}
RestAPI - Download file From AWS S3
Create the RestController class to download the file from AWS S3 bucket.
package com.techgeeknext.springbootawss3.controller;
import com.techgeeknext.springbootawss3.service.S3BucketStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayOutputStream;
@RestController
public class S3BucketStorageController {
@Autowired
S3BucketStorageService service;
@GetMapping(value = "/download/{filename}")
public ResponseEntity<byte[]> downloadFile(@PathVariable String filename) {
ByteArrayOutputStream downloadInputStream = service.downloadFile(filename);
return ResponseEntity.ok()
.contentType(contentType(filename))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
.body(downloadInputStream.toByteArray());
}
private MediaType contentType(String filename) {
String[] fileArrSplit = filename.split("\\.");
String fileExtension = fileArrSplit[fileArrSplit.length - 1];
switch (fileExtension) {
case "txt":
return MediaType.TEXT_PLAIN;
case "png":
return MediaType.IMAGE_PNG;
case "jpg":
return MediaType.IMAGE_JPEG;
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
}
}
Test AWS S3 operations
Now, run the Spring Boot application.
-
Upload File on AWS S3 Bucket
Use POST method with url http://localhost:8081/file/upload, select file and provide filename. - Verify on AWS S3 Bucket.
-
List all Files from AWS S3 Bucket
Use GET method with url http://localhost:8081/list/files. -
Download Files from AWS S3 Bucket
Use GET method with url http://localhost:8081/download/test2-file-techgeeknext.
Download Source Code
The full source code for this article can be found on below.Download it here - Spring Cloud: AWS S3 Example