AWS S3 bucket File Upload with Spring boot

Why?

There will be questions arise why we need to upload images in the aws s3 bucket rather than our local Database. The answer is pretty simple. There are 2 main reasons to do this. The first, CloudFront is a true CDN and will load files much faster than your server, the second, Browsers can only open so many connections to the server at once, by offloading files like this to different host names, then your visitors will be able to download more items in parallel.

Why Using Amazon AWS?

  • It’s easy to programmatically upload any file using their API.
  • Amazon supports a lot of programming languages.
  • There is a web interface where you can see all of your uploaded files.
  • You can manually upload/delete any file using the web interface.

AWS account configuration

You need to create an account on Amazon website to start using S3 Bucket. Registration is easy and clear enough, but you will have to verify your phone number and enter your credit card info (don’t worry, your card will not be charged if only you buy some services).

Create I AM User

Now your bucket is created but we need to give permission for users to access this bucket. It is not secure to give the access keys of your root user to your developer team or someone else. We need to create a new IAM user and give him permission to use only the S3 Bucket.

Spring boot Application

Let’s create Spring Boot project and add amazon dependency.

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.133</version>
</dependency>
amazonProperties:
endpointUrl:
https://s3.us-east-2.amazonaws.com
accessKey: XXXXXXXXXXXXXXXXX
secretKey: XXXXXXXXXXXXXXXXXXXXXXXXXX
bucketName: your-bucket-name
@RestController
@RequestMapping("/storage/")
public class BucketController {
private AmazonClient amazonClient; @Autowired
BucketController(AmazonClient amazonClient) {
this.amazonClient = amazonClient;
}
@PostMapping("/uploadFile")
public String uploadFile(@RequestPart(value = "file") MultipartFile file) {
return this.amazonClient.uploadFile(file);
}
@DeleteMapping("/deleteFile")
public String deleteFile(@RequestPart(value = "url") String fileUrl) {
return this.amazonClient.deleteFileFromS3Bucket(fileUrl);
}
}
@Service
public class AmazonClient {
private AmazonS3 s3client; @Value("${amazonProperties.endpointUrl}")
private String endpointUrl; @Value("${amazonProperties.bucketName}")
private String bucketName; @Value("${amazonProperties.accessKey}")
private String accessKey; @Value("${amazonProperties.secretKey}")
private String secretKey;@PostConstruct
private void initializeAmazon() {
AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey);
this.s3client = new AmazonS3Client(credentials);
}
}
private File convertMultiPartToFile(MultipartFile file) throws IOException {
File convFile = new File(file.getOriginalFilename());
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
}
private String generateFileName(MultipartFile multiPart) {
return new Date().getTime() + "-" + multiPart.getOriginalFilename().replace(" ", "_");
}
private void uploadFileTos3bucket(String fileName, File file) {
s3client.putObject(new PutObjectRequest(bucketName, fileName, file)
.withCannedAcl(CannedAccessControlList.PublicRead));
}
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
public String uploadFile(MultipartFile multipartFile) {    String fileUrl = "";
try {
File file = convertMultiPartToFile(multipartFile);
String fileName = generateFileName(multipartFile);
fileUrl = endpointUrl + "/" + bucketName + "/" + fileName;
uploadFileTos3bucket(fileName, file);
file.delete();
} catch (Exception e) {
e.printStackTrace();
}
return fileUrl;
}
public String deleteFileFromS3Bucket(String fileUrl) {
String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
s3client.deleteObject(new DeleteObjectRequest(bucketName + "/", fileName));
return "Successfully deleted";
}
String filePath = "/some/folder/image.png"
s3client.deleteObject(new DeleteObjectRequest(bucketName + "/", filePath));

Test

Let’s test our application by making requests using Postman. We need to choose the POST method, in the Body we should select ‘form-data’. As a key, we should enter ‘file’ and choose the value type ‘File’. Then choose any file from your PC as a value. The endpoint URL is http://localhost:8080/storage/uploadFile.

Conclusion

Now you got a better understanding of using the S3 bucket with spring boot application. Hope this was helpful to you. If you have any questions please feel free to leave a comment. Thank you for reading.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store