Upload and View Files in Amazon S3 using Angular + Spring Boot

Chinthaka Jayatilake
LinkIT
Published in
7 min readOct 10, 2019
Photo by Christian Wiediger on Unsplash

Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance. This can be used to store and protect any amount of data for a range of use cases, such as websites, mobile applications, backup and restore, archive, enterprise applications, IoT devices, and big data analytics.

So let us now see how we could use Amazon S3 in our projects to store and retrieve files.

To start with, we will create our Angular project.

ng new project_name

Next is to create a simple HTML page to upload, view, and delete files. For that, we will move to the app.component.html page and start implementing it.

<h1>Upload,View & Delete File</h1><input type="file" id="customFile" (change)="selectFile($event)" placeholder="File To Upload"><button class="btn btn-primary" [disabled]="!selectedFiles || admincheck || status" (click)="upload()">Save File</button><br><br><br><input type="text" placeholder="File to View or Delete"  name="image" [(ngModel)]="file"><button class="btn btn-primary" style="margin-left: 10px" (click)="viewFile()">View File</button><button class="btn btn-primary" style="margin-left: 10px" (click)="deleteFile()">Delete File</button>

Now we need to create a service to communicate with the back-end and to send the selected file as a multipart file to the back-end.

import { Injectable } from '@angular/core';
import { HttpClient, HttpEvent, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UploadFileService { constructor(private https: HttpClient) { } pushFileToStorage(file: File): Observable<HttpEvent<{}>> { const data: FormData = new FormData();
data.append('file', file);
const newRequest = new HttpRequest('POST', 'http://localhost:8080/uploadFile', data, { reportProgress: true,
responseType: 'text'
});
return this.https.request(newRequest);
}
}

As it is done, we need to import the service we created to the app.component.ts file and add few more methods to upload files with the help of the service, view files, and also to delete files.

import { Component } from '@angular/core';
import { UploadFileService } from './Services/upload-file.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent { selectedFiles: FileList; currentFileUpload: File; progress: { percentage: number } = { percentage: 0 }; selectedFile = null; changeImage = false; file:string; constructor(private uploadService: UploadFileService, private https:HttpClient){} viewFile(){window.open('https://bucketName.s3.cloudLocation.amazonaws.com/'+this.file); } deleteFile()
{
this.https.post<string>('http://localhost:8080/deleteFile',this.file).subscribe(
res => {
this.file = res;
}
);
}
change(event) {
this.changeImage = true;
}
changedImage(event) {
this.selectedFile = event.target.files[0];
}
upload() {
this.progress.percentage = 0;
this.currentFileUpload = this.selectedFiles.item(0);
this.uploadService.pushFileToStorage(this.currentFileUpload).subscribe(event => {
this.selectedFiles = undefined;
});
}
selectFile(event) {
this.selectedFiles = event.target.files;
}
}

It is important to make sure that all the imports which are mentioned at the beginning of the component.ts files are present in the project node modules folder. If not they must be installed as below.

npm install imported_file_name

With that, we have completed our front-end interface and its functionalities.

Now we need to create an Amazon Web Service(AWS) account and get the S3 service. The below link will get you to the AWS account creation page.

Even though your card details will be taken you will not be charged as you will be getting a free period to try their services. After creating the account you will be able to see the services that they provide. Under Storage Services you will be able to select ‘S3’. That would lead you to the buckets that you have. As this is a new account there will be none. So let us now create a bucket.

Screenshot by Author

First, you need to select the option ‘Create Bucket’.

Screenshot by Author

The bucket creation process will have 4 sections. In the first section, you need to give a name to your bucket and then select the region. When selecting the region it is better to select a region that is close to you. But that is not a must.

Screenshot by Author

You can just skip the next section by clicking the button on your right-hand side bottom of the pop-up window.

Screenshot by Author

The 3rd section is important as it will set permissions to our bucket. So check the boxes as per below and click next. This setting can be changed anytime after creating the bucket.

Screenshot by Author

Then the last section will show you an overall review of the bucket that you are about to create. So now you can click the option ‘Create Bucket’.

Now go back to the services and select the option ‘IAM’ under ‘Security, Identity & Compliance’.

Screenshot by Author

There you will see the option ‘add user’. Select that option. In the popped up window, you need to give a user name and select access type as programmatic access. Now click ‘Next’.

Screenshot by Author

Then select the option ‘Attach existing policies directly’ and type ‘S3’ in the search box. From the search results select ‘AmazonS3FullAccess’ and click next.

Screenshot by Author

You can now skip the ‘Add tags section’. Then it will show a review of the user that you are about to create. You can click Next again and then you will get the ‘Access Key ID’ and the ‘Secret Access Key’. Open a notepad file and keep them copied.

We are all set to start implementing our back-end. We can create our Spring Boot project easily from the below link.

Then we need to add the below dependencies to our pom.xml file.

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.133</version>
</dependency>
</dependencies>

Let us add the credentials of our S3 bucket which we previously copied to a notepad file, to the application.properties file now.

endpointUrl = https://s3.cloudLocation.amazonaws.com
accessKey = accesskey
secretKey = secretkey
bucketName = bucketname

It is time to create our service class to work with Amazon S3. In the service class, we need to implement methods to establish a connection with the S3 bucket, to convert the multipart file to a file, to upload that file, and to delete a file.

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

@Service
public class AmazonS3BucketService {

private AmazonS3 amazonS3;

@Value("${endpointUrl}")
private String endpointUrl;
@Value("${bucketName}")
private String bucketName;
@Value("${accessKey}")
private String accessKey;
@Value("${secretKey}")
private String secretKey;

@PostConstruct
private void initializeAmazon() {
AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey);
this.amazonS3 = new AmazonS3Client(credentials);
}

public String uploadFile(MultipartFile multipartFile) {
String fileURL = "";
try {
File file = convertMultipartFileToFile(multipartFile);
String fileName = multipartFile.getOriginalFilename();
fileURL = endpointUrl + "/" + bucketName + "/" + fileName;
uploadFileToBucket(fileName, file);
file.delete();
} catch (Exception e) {
e.printStackTrace();
}
return fileURL;
}

private File convertMultipartFileToFile(MultipartFile file) throws IOException {
File convertedFile = new File(file.getOriginalFilename());
FileOutputStream fos = new FileOutputStream(convertedFile);
fos.write(file.getBytes());
fos.close();
return convertedFile;
}

private void uploadFileToBucket(String fileName, File file) {
amazonS3.putObject(new PutObjectRequest(bucketName, fileName, file)
.withCannedAcl(CannedAccessControlList.PublicRead));
}

public String deleteFileFromBucket(String fileName) {
amazonS3.deleteObject(new DeleteObjectRequest(bucketName, fileName));
return "Deletion Successful";
}

}

Now we need to create the controller class that would communicate with the front-end and uses the service class that we created before to carry out the requests which are being directed by the front-end.

import com.s3.fileupload.Service.AmazonS3BucketService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@CrossOrigin(origins = "http://localhost:4200")
@Controller
public class S3BucketController {

private AmazonS3BucketService amazonS3BucketService;

S3BucketController(AmazonS3BucketService amazonS3BucketService) {
this.amazonS3BucketService = amazonS3BucketService;
}

@PostMapping("/uploadFile")
public String uploadFile(@RequestPart(value = "file") MultipartFile file) {
return this.amazonS3BucketService.uploadFile(file);
}

@PostMapping("/deleteFile")
public String deleteFile(@RequestBody String fileURL) {
return this.amazonS3BucketService.deleteFileFromBucket(fileURL);
}
}

With that, we have come to the end of our implementation. Now it is time to test. Try uploading files and see whether they are being saved in the bucket. Also, try to view and delete files by giving the file name along with their file extensions and see whether the functionalities work properly.

I hope it is all clear and your project is working perfectly...

So you can use this amazing Amazon service whenever you need to store data in your projects. It is really efficient and easy to implement as well.

The project source code can be viewed and downloaded from GitHub.

Cheers!! Have a pleasant day!!

Visit my Official Blog Site to send in your queries directly to me and to read more articles by me….

--

--