DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Running a Java App With MySQL in Any Docker Environment
  • How to Use Bootstrap to Build Beautiful Angular Apps
  • GraphQL With Java Spring Boot and Postgres or MySQL Made Easy!
  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing

Trending

  • Microsoft Azure Synapse Analytics: Scaling Hurdles and Limitations
  • Understanding Java Signals
  • Solid Testing Strategies for Salesforce Releases
  • The Role of Retrieval Augmented Generation (RAG) in Development of AI-Infused Enterprise Applications
  1. DZone
  2. Coding
  3. Frameworks
  4. Upload and Retrieve Files/Images Using Spring Boot, Angular, and MySQL

Upload and Retrieve Files/Images Using Spring Boot, Angular, and MySQL

This article demonstrates how you can select an image using the Angular 8 UI, send it to the Spring backend, and retrieve it later from MySQL.

By 
Rida Shaikh user avatar
Rida Shaikh
·
Feb. 26, 20 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
127.8K Views

Join the DZone community and get the full member experience.

Join For Free

In this tutorial, we will be selecting an image using Angular 8 UI. This image will then be sent to the Spring Boot backend by making a REST call. Later this image will be stored in a MySQL database. We will also later retrieve the saved image and display it using Angular.

Store Image in MYSQL Using Spring Boot and Angular 8

Retrieve Image From MYSQL using Spring Boot and Angular 8

This tutorial is explained in the below Youtube Video.

Angular Setup

We will be installing npm and Angular CLI 8

Install NodeJS by downloading the installable from Install NodeJS. Install the Angular CLI using the following command. It will get us the latest version of Angular CLI.


Shell
 




xxxxxxxxxx
1


 
1
npm install -g @angular/cli



Shell
 




x


 
1
npm install -g @angular/cli     


We can check the Angular CLI version:

Shell
 




x


 
1
ng version     



Next, we will create a new Angular project using the Angular CLI as follows:

Shell
 




xxxxxxxxxx
1


 
1
ng new ImageUpload



To get the Angular CLI project started use the following command. We must go inside the ImageUpload folder and then use it.

Shell
 




xxxxxxxxxx
1


 
1
ng serve    
2
 
          



Go to localhost:4200.

I will be using the Microsoft Visual Studio Code IDE for Angular to import the project we developed earlier in Microsoft Visual Studio Code IDE.

Our final Angular project will be as follows:

For this project, I will be making use of Bootstrap CSS. So in the index.html, add the URL for the bootstrap CSS.

CSS
 




xxxxxxxxxx
1
16


 
1
<!doctype html>
2
<html lang="en">
3
<head>
4
  <meta charset="utf-8">
5
  <title>ImageUpload</title>
6
  <base href="/">
7
 
          
8
  <meta name="viewport" content="width=device-width, initial-scale=1">
9
  <link rel="icon" type="image/x-icon" href="favicon.ico">
10
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
11
 integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
12
</head>
13
<body>
14
  <app-root></app-root>
15
</body>
16
</html>


Angular Component to Send and Retrieve Image Using MySQL

We will be not be creating any new components and instead modify the existing app components.

Modify the app.component.html. Add the File Selector section and also a section to show the retrieved image:

Java
 




x


 
1
<div class="container row">
2
    <div class="col-md-12">
3
        <h1>Upload Image</h1>
4
    </div>
5
</div>
6
<div class="container row">
7
    <div class="col-md-6">
8
        <input type="file" (change)="onFileChanged($event)">
9
    </div>
10
    <div class="col-md-6">
11
        <input type="button" (click)="onUpload()" value="upload">
12
    </div>
13
</div>
14
<hr />
15
<div class="container row">
16
    <div class="col-md-12">
17
        <div *ngIf=message>{{message}}</div>
18
    </div>
19
</div>
20
 
          
21
<div class="container row">
22
    <div class="col-md-6">
23
        <input type="text" class="form-control" id="name" placeholder="image name" [(ngModel)]="imageName"
24
            name="name" />
25
    </div>
26
    <div class="col-md-6">
27
        <input type="button" (click)="getImage()" value="Get Image">
28
    </div>
29
</div>
30
 
          
31
<div class="container row">
32
    <div class="col-md-12">
33
        <div *ngIf=retrievedImage>
34
            <img [src]="retrievedImage">
35
        </div>
36
    </div>
37
</div>



Next, modify the app component typescript file.

Java
 




xxxxxxxxxx
1
121
99


 
1
import { HttpClient, HttpEventType } from '@angular/common/http';
2
import { Component } from '@angular/core';
3
 
          
4
@Component({
5
  selector: 'app-root',
6
  templateUrl: './app.component.html',
7
  styleUrls: ['./app.component.css'],
8
})
9
 
          
10
export class AppComponent {
11
  constructor(private httpClient: HttpClient) { }
12
  selectedFile: File;
13
  retrievedImage: any;
14
  base64Data: any;
15
  retrieveResonse: any;
16
  message: string;
17
  imageName: any;
18
 
          
19
  //Gets called when the user selects an image
20
 
          
21
  public onFileChanged(event) {
22
    //Select File
23
    this.selectedFile = event.target.files[0];
24
  }
25
 
          
26
  //Gets called when the user clicks on submit to upload the image
27
  onUpload() {
28
    console.log(this.selectedFile);
29
    //FormData API provides methods and properties to allow us easily prepare form data to be sent with POST HTTP requests.
30
    const uploadImageData = new FormData();
31
    uploadImageData.append('imageFile', this.selectedFile, this.selectedFile.name);
32
    //Make a call to the Spring Boot Application to save the image
33
    this.httpClient.post('http://localhost:8080/image/upload', uploadImageData, { observe: 'response' })
34
      .subscribe((response) => {
35
        if (response.status === 200) {
36
          this.message = 'Image uploaded successfully';
37
        } else {
38
          this.message = 'Image not uploaded successfully';
39
        }
40
      }
41
      );
42
  }
43
 
          
44
    //Gets called when the user clicks on retieve image button to get the image from back end
45
    getImage() {
46
    //Make a call to Sprinf Boot to get the Image Bytes.
47
    this.httpClient.get('http://localhost:8080/image/get/' + this.imageName)
48
      .subscribe(
49
        res => {
50
          this.retrieveResonse = res;
51
          this.base64Data = this.retrieveResonse.picByte;
52
          this.retrievedImage = 'data:image/jpeg;base64,' + this.base64Data;
53
        }
54
      );
55
  }
56
}



Modify app.module.ts to include the required modules i.e HttpClientModule and FormsModule-

Java
 




xxxxxxxxxx
1
25


 
1
import { BrowserModule } from '@angular/platform-browser';
2
import { NgModule } from '@angular/core';
3
import { AppRoutingModule } from './app-routing.module';
4
import { AppComponent } from './app.component';
5
import { HttpClientModule } from '@angular/common/http';
6
import { FormsModule } from '@angular/forms';
7
 
          
8
 
          
9
@NgModule({
10
  declarations: [
11
    AppComponent
12
  ],
13
 
          
14
  imports: [
15
    BrowserModule,
16
    AppRoutingModule,
17
    HttpClientModule,
18
    FormsModule
19
  ],
20
 
          
21
  providers: [],
22
  bootstrap: [AppComponent]
23
})
24
 
          
25
export class AppModule { }


Spring Boot Module To Save and Retrieve Images Using MySQL

The Maven project will be as follows:

The pom.xml will contain the Spring web and data dependencies.

XML
 




xxxxxxxxxx
1
52


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4
 
          
5
    <modelVersion>4.0.0</modelVersion>
6
    <groupId>com.javainuse</groupId>
7
    <artifactId>boot-image-upload</artifactId>
8
    <version>0.0.1-SNAPSHOT</version>
9
    <packaging>jar</packaging>
10
 
          
11
 
          
12
    <name>boot-jdbc</name>
13
    <description>Demo project for Spring Boot</description>
14
    <parent>
15
        <groupId>org.springframework.boot</groupId>
16
        <artifactId>spring-boot-starter-parent</artifactId>
17
        <version>2.0.1.RELEASE</version>
18
        <relativePath /> <!-- lookup parent from repository -->
19
    </parent>
20
 
          
21
    <properties>
22
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24
        <java.version>1.8</java.version>
25
    </properties>
26
 
          
27
    <dependencies>
28
        <dependency>
29
            <groupId>org.springframework.boot</groupId>
30
            <artifactId>spring-boot-starter-web</artifactId>
31
        </dependency>
32
        <dependency>
33
            <groupId>org.springframework.boot</groupId>
34
            <artifactId>spring-boot-starter-data-jpa</artifactId>
35
        </dependency>
36
        <dependency>
37
           <groupId>mysql</groupId>
38
            <artifactId>mysql-connector-java</artifactId>
39
            <scope>runtime</scope>
40
        </dependency>
41
    </dependencies>
42
 
          
43
    <build>
44
        <plugins>
45
            <plugin>
46
                <groupId>org.springframework.boot</groupId>
47
                <artifactId>spring-boot-maven-plugin</artifactId>
48
            </plugin>
49
        </plugins>
50
    </build>
51
 
          
52
</project>


Create a model class named  ImageModel :

Java
 




xxxxxxxxxx
1
115
99


 
1
package com.javainuse.model;
2
import javax.persistence.*;
3
 
          
4
@Entity
5
@Table(name = "image_table")
6
public class ImageModel {
7
 
          
8
  public ImageModel() {
9
        super();
10
    }
11
 
          
12
   public ImageModel(String name, String type, byte[] picByte) {
13
        this.name = name;
14
        this.type = type;
15
        this.picByte = picByte;
16
    }
17
 
          
18
    @Id
19
    @Column(name = "id")
20
    @GeneratedValue(strategy = GenerationType.IDENTITY)
21
    private Long id;
22
    @Column(name = "name")
23
    private String name;
24
    @Column(name = "type")
25
    private String type;
26
 
          
27
    //image bytes can have large lengths so we specify a value
28
    //which is more than the default length for picByte column
29
    @Column(name = "picByte", length = 1000)
30
 
          
31
    private byte[] picByte;
32
    public String getName() {
33
        return name;
34
    }
35
 
          
36
    public void setName(String name) {
37
        this.name = name;
38
    }
39
 
          
40
    public String getType() {
41
        return type;
42
    }
43
 
          
44
   public void setType(String type) {
45
        this.type = type;
46
    }
47
 
          
48
    public byte[] getPicByte() {
49
        return picByte;
50
    }
51
 
          
52
    public void setPicByte(byte[] picByte) {
53
       this.picByte = picByte;
54
    }
55
 
          
56
}


Create the JPARepository for storing and retrieving images:

Java
 




x
9


 
1
package com.javainuse.db;
2
 
          
3
import java.util.Optional;
4
import org.springframework.data.jpa.repository.JpaRepository;
5
import com.javainuse.model.ImageModel;
6
 
          
7
public interface ImageRepository extends JpaRepository<ImageModel, Long> {
8
    Optional<ImageModel> findByName(String name);
9
}


Create the controller class: 

  • Expose a POST API for receiving the Multipart file and storing the bytes for the same in MySQL using the JPA repository. Multipart originates from MIME, an Internet standard that extends the format of emails. It is what browsers use to upload files through HTML forms.
  • Expose a GET API for retrieving the image bytes from MySQL using the JPA repository and returning it.
  • As the image bytes are large, we make use of the compression and decompression algorithms.
Java
 




xxxxxxxxxx
1
181
99


 
1
package com.javainuse.controller;
2
 
          
3
import java.io.ByteArrayOutputStream;
4
import java.io.IOException;
5
import java.util.Optional;
6
import java.util.zip.DataFormatException;
7
import java.util.zip.Deflater;
8
import java.util.zip.Inflater;
9
import org.springframework.beans.factory.annotation.Autowired;
10
import org.springframework.http.HttpStatus;
11
import org.springframework.http.ResponseEntity;
12
import org.springframework.http.ResponseEntity.BodyBuilder;
13
import org.springframework.web.bind.annotation.CrossOrigin;
14
import org.springframework.web.bind.annotation.GetMapping;
15
import org.springframework.web.bind.annotation.PathVariable;
16
import org.springframework.web.bind.annotation.PostMapping;
17
import org.springframework.web.bind.annotation.RequestMapping;
18
import org.springframework.web.bind.annotation.RequestParam;
19
import org.springframework.web.bind.annotation.RestController;
20
import org.springframework.web.multipart.MultipartFile;
21
import com.javainuse.db.ImageRepository;
22
import com.javainuse.model.ImageModel;
23
 
          
24
@RestController
25
@CrossOrigin(origins = "http://localhost:4200")
26
@RequestMapping(path = "image")
27
public class ImageUploadController {
28
 
          
29
  @Autowired
30
    ImageRepository imageRepository;
31
    @PostMapping("/upload")
32
    public BodyBuilder uplaodImage(@RequestParam("imageFile") MultipartFile file) throws IOException {
33
 
          
34
        System.out.println("Original Image Byte Size - " + file.getBytes().length);
35
        ImageModel img = new ImageModel(file.getOriginalFilename(), file.getContentType(),
36
                compressBytes(file.getBytes()));
37
        imageRepository.save(img);
38
        return ResponseEntity.status(HttpStatus.OK);
39
    }
40
 
          
41
    @GetMapping(path = { "/get/{imageName}" })
42
    public ImageModel getImage(@PathVariable("imageName") String imageName) throws IOException {
43
        final Optional<ImageModel> retrievedImage = imageRepository.findByName(imageName);
44
        ImageModel img = new ImageModel(retrievedImage.get().getName(), retrievedImage.get().getType(),
45
                decompressBytes(retrievedImage.get().getPicByte()));
46
        return img;
47
    }
48
 
          
49
    // compress the image bytes before storing it in the database
50
    public static byte[] compressBytes(byte[] data) {
51
        Deflater deflater = new Deflater();
52
        deflater.setInput(data);
53
        deflater.finish();
54
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
55
        byte[] buffer = new byte[1024];
56
        while (!deflater.finished()) {
57
            int count = deflater.deflate(buffer);
58
            outputStream.write(buffer, 0, count);
59
        }
60
        try {
61
            outputStream.close();
62
        } catch (IOException e) {
63
        }
64
        System.out.println("Compressed Image Byte Size - " + outputStream.toByteArray().length);
65
        return outputStream.toByteArray();
66
    }
67
 
          
68
    // uncompress the image bytes before returning it to the angular application
69
    public static byte[] decompressBytes(byte[] data) {
70
        Inflater inflater = new Inflater();
71
        inflater.setInput(data);
72
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
73
        byte[] buffer = new byte[1024];
74
        try {
75
            while (!inflater.finished()) {
76
                int count = inflater.inflate(buffer);
77
                outputStream.write(buffer, 0, count);
78
            }
79
            outputStream.close();
80
        } catch (IOException ioe) {
81
        } catch (DataFormatException e) {
82
        }
83
        return outputStream.toByteArray();
84
    }
85
}


Create the application.properties file where we specify the database properties:

Java
 




xxxxxxxxxx
1
11
9


 
1
spring.datasource.url=jdbc:mysql://localhost/bootdb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
2
spring.datasource.username=root
3
spring.datasource.password=root
4
spring.datasource.platform=mysql
5
spring.datasource.initialization-mode=always
6
spring.jpa.hibernate.ddl-auto=update


Finally, create the bootstrap class using SpringBoot annotation:

Java
 




x
12


 
1
package com.javainuse;
2
 
          
3
import org.springframework.boot.SpringApplication;
4
import org.springframework.boot.autoconfigure.SpringBootApplication;
5
 
          
6
@SpringBootApplication
7
public class ImageUploadApplication {
8
 
          
9
  public static void main(String[] args) {
10
        SpringApplication.run(ImageUploadApplication.class, args);
11
    }
12
}



Start the Spring Boot Application 

Go to localhost:4200, select the image to be uploaded and click on upload button. If the image is uploaded successfully, then we will display the message that the image has been uploaded successfully. In the Spring Boot console, we can see the size of the image received. Also in MySQL, we can see the image saved as bytes in the tabled named image_model. For retrieving the image, enter the name of the image to be retrieved and click on the Get Image button. 

Further Reading

Configuring Spring Boot for MySQL


Spring Framework Spring Boot AngularJS MySQL Upload Microsoft Visual Studio Visual Studio Code Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Running a Java App With MySQL in Any Docker Environment
  • How to Use Bootstrap to Build Beautiful Angular Apps
  • GraphQL With Java Spring Boot and Postgres or MySQL Made Easy!
  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!