Angular 11 + Spring Boot: File upload example
Tags: angular, springboot, webdev, fullstack
Published: 2020-12-31 09:00:33

In this tutorial, I will show you way to build Angular 11 File upload & download example with Spring Boot server.

<h2>Overview</h2>
We're gonna create a full-stack Angular 11 File upload to Spring Boot Server in that user can:
<ul>
	<li>see the upload process (percentage)</li>
	<li>view all uploaded files</li>
	<li>download by clicking on the file name</li>
</ul>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lfmpd9xqyxv7s4q8axz6.png)

All uploaded files will be saved in <strong>uploads</strong> folder:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hllwzcysehx720ylhjas.png)

<h2>Angular 11 + Spring Boot File upload Architecture</h2>
Let's look at the architecture below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/98uqr6ei9jq73uobgf9b.png)

Angular 11 Client:
<ul>
	<li><code>FileUpload</code> Component calls <code>UploadService</code> functions for upload/download/display files</li>
	<li><code>UploadService</code> uses <code>HttpClientModule</code> to make HTTP requests</li>
</ul>

Spring Boot Server:
<ul>
	<li><code>FilesController</code> receives the HTTP requests from Client, then calls <code>FilesStorageService</code> functions for upload/download/getting files</li>
	<li><code>FilesStorageService</code> implements functions for storing and retrieving file systems using Java <code>Files</code> library</li>
</ul>

<h2>Technology</h2>
Server:
<ul>
    	<li>Java 8</li>
    	<li>Spring Boot 2 (with Spring Web MVC)</li>
    	<li>Maven 3.6.1</li>
</ul>

Client:
<ul>
	<li>Angular 11</li>
	<li>RxJS 6</li>
	<li>Bootstrap 4</li>
</ul>

<h2>Spring Boot Rest APIs for File Upload & Storage</h2>
Spring Boot App will provide APIs

<div class="table-responsive">
<table class="table table-hover  table table-hover" width="100%">
<thead>
<tr>
<th>Methods</th>
<th>Urls</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>POST</td>
<td>/upload</td>
<td>upload a File</td>
</tr>
<tr>
<td>GET</td>
<td>/files</td>
<td>get List of Files (name & url)</td>
</tr>
<tr>
<td>GET</td>
<td>/files/[filename]</td>
<td>download a File</td>
</tr>
</tbody>
</table>
</div>

This is the project structure:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jl256ysvhgzvfn7mj2of.png)

- <code>FileInfo</code> contains information of the uploaded file.
- <code>FilesStorageService</code> helps us to initialize storage, save new file, load file, get list of Files' info, delete all files.
- <code>FilesController</code> uses <code>FilesStorageService</code> to export Rest APIs: POST a file, GET all files' information, download a File.
- <code>FileUploadExceptionAdvice</code> handles exception when the controller processes file upload.
- <em>application.properties</em> contains configuration for Servlet Multipart.
- <em>pom.xml</em> for Spring Boot dependency.

You can find Step by Step to implement the Spring Boot Server at:
<a href="https://bezkoder.com/spring-boot-file-upload/">Spring Boot Multipart File upload (to static folder) example</a>

Or: <a href="https://bezkoder.com/spring-boot-upload-file-database/">Spring Boot Multipart File upload (to database) example</a>

<h2>Angular 11 Client for file upload/download UI</h2>
This is the project structure that we're gonna build:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/z1tulms70nnkioorzy6h.png)

- We import necessary library, components in <em>app.module.ts</em>.
- <em>upload-file.service</em> provides methods to save File and get Files from Spring Boot Server.
- <em>upload-files.component</em> contains upload form, progress bar, display of list files.
- <em>app.component</em> is the container that we embed all components.
- <em>index.html</em> for importing the Bootstrap.

<strong>Angular Service for File Upload</strong>
This service will use Angular <code>HTTPClient</code> to send HTTP requests.
There are 2 functions:
<ul>
	<li><code>upload(file)</code>: returns <code>Observable&lt;HttpEvent&lt;any>></code> that we're gonna use for tracking progress</li>
	<li><code>getFiles()</code>: returns a list of Files' information as <code>Observable</code> object</li>
</ul>

```js
export class UploadFileService {

  constructor(private http: HttpClient) { }

  upload(file: File): Observable&lt;HttpEvent&lt;any>> {
    ...
  }

  getFiles(): Observable&lt;any> {
    ...
  }
}
```

<strong>Angular Component for File Upload</strong>
File Upload Component has Progress Bar, Card, Button and Message. It injects <code>UploadFileService</code> to call <code>uploadService.upload()</code> method.

The upload progress will be calculated basing on <code>event.loaded</code> and <code>event.total</code>.
If the transmission is done, the event will be a <code>HttpResponse</code> object. At this time, we call <code>uploadService.getFiles()</code> to get the files' information and assign the result to <code>fileInfos</code> variable.

```js
upload() {
  this.progress = 0;

  this.currentFile = this.selectedFiles.item(0);
  this.uploadService.upload(this.currentFile).subscribe(
    event => {
      if (event.type === HttpEventType.UploadProgress) {
        this.progress = Math.round(100 * event.loaded / event.total);
      } else if (event instanceof HttpResponse) {
        this.message = event.body.message;
        this.fileInfos = this.uploadService.getFiles();
      }
    },
    err => {
      this.progress = 0;
      this.message = 'Could not upload the file!';
    });
}
```

You can find step by step with more details in the tutorial:
<a href="https://bezkoder.com/angular-11-file-upload/">Angular 11 File upload example with progress bar & Bootstrap</a>

<h2>Run the App</h2>
Run Spring Boot Server with command: <code>mvn spring-boot:run</code>.
Refresh the project directory and you will see <em>uploads</em> folder inside it.

Because we configure CORS for origin: <code>http://localhost:8081</code>, so you need to run Angular 11 Client with command:
<code>ng serve --port 8081</code>

Open Browser with url <code>http://localhost:8081/</code> and check the result.

<h2>Further Reading</h2>
<ul>
	<li><a href="https://angular.io/api/common/http/HttpRequest">https://angular.io/api/common/http/HttpRequest</a></li>
	<li><a href="https://bezkoder.com/pagination-spring-boot-angular-11/">Angular 11 + Spring Boot: Pagination example</a></li>
	<li><a href="https://bezkoder.com/angular-11-spring-boot-jwt-auth/">Angular 11 + Spring Boot: JWT Authentication example</a></li>
</ul>

Fullstack CRUD App:
- <a href="https://bezkoder.com/angular-11-spring-boot-crud/">Angular + Spring Boot + MySQL example</a>
- <a href="https://bezkoder.com/angular-11-spring-boot-postgresql/">Angular + Spring Boot + PostgreSQL example</a>
- <a href="https://bezkoder.com/angular-11-spring-boot-mongodb/">Angular + Spring Boot + MongoDB example</a>

Serverless with Firebase:
<a href="https://bezkoder.com/angular-11-file-upload-firebase-storage/">Angular 11 Upload File to Firebase Storage example</a>

<h2>Conclusion</h2>
Today we're learned how to build an example for upload Files from Angular 11 to Spring Boot server. We also provide the ability to show list of files, upload progress using Bootstrap, and to download file from the server.

Next tutorials will show you way to implement the full-stack (with source code):
- Back-end: File Upload to <a href="https://bezkoder.com/spring-boot-file-upload/">Static folder</a> / File Upload to <a href="https://bezkoder.com/spring-boot-upload-file-database/">Database</a>
- <a href="https://bezkoder.com/angular-11-file-upload/">Front-end</a>

If you want to upload multiple files at once like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qyfl3fd095a3hvrgay1w.png)

You can find the instruction here:
<a href="https://bezkoder.com/angular-11-multiple-files-upload/">Angular 11 Multiple Files upload example</a>

You will want to know how to run both projects in one place:
<a href="https://bezkoder.com/integrate-angular-spring-boot/">How to Integrate Angular with Spring Boot Rest API</a>

Happy Learning! See you again.