Angular 4 + Spring JPA + MySQL example | Angular 4 Http Client – Spring Boot RestApi Server

In this tutorial, grokonez shows you Angular 4 Http Client & Spring Boot Server example that uses Spring JPA to interact with MySQL and Angular 4 as a front-end technology to make request and receive response.

Related Posts:
How to use Spring JPA MySQL | Spring Boot
How to use Angular Http Client to fetch Data from SpringBoot RestAPI – Angular 4
How to use Angular HttpClient to POST, PUT, DELETE data on SpringBoot Rest APIs – Angular 4

– Angular 6: Spring Boot + Angular 6 example | Spring Data JPA + REST + MySQL CRUD example
– Angular 8: Spring Boot 2.1 + Angular 8 + MySQL example | Angular HTTP Client + RestAPIs + Spring JPA CRUD + MySQL tutorial

I. Technologies

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.4.RELEASE
– Spring Boot: RELEASE
– Angular 4

II. Overview


1. Spring Boot Server


For more details about Spring JPA – MySQL, please visit:
How to use Spring JPA MySQL | Spring Boot

2. Angular 4 Client


For more details:
– About Angular 4 Routing:
How to work with Angular Routing – Spring Boot + Angular 4
– About Angular Http Client to GET/POST/DELETE:
+ How to use Angular Http Client to fetch Data from SpringBoot RestAPI – Angular 4
+ How to use Angular HttpClient to POST, PUT, DELETE data on SpringBoot Rest APIs – Angular 4

III. Practice

1. Project Structure

1.1 Spring Boot Server


– Class Customer corresponds to entity and table customer, it should be implemented Serializable.
CustomerRepository is an interface extends CrudRepository, will be autowired in CustomerController for implementing repository methods and custom finder methods.
CustomerController is a REST Controller which has request mapping methods for RESTful requests such as: getAll, postCustomer, delete, findByLastName.
– Configuration for Spring Datasource and Spring JPA properties in
Dependencies for Spring Boot and MySQL in pom.xml

1.2 Angular 4 Client


In this example, we focus on:
– 4 components: customers, customer-details, create-customer, search-customer.
– 3 modules: FormsModule, HttpModule, AppRoutingModule.
customer.ts: class Customer (id, firstName, lastName)
data.service.ts: DataService for Http Client methods
proxy.conf.json for integrating Angular Client with Spring Boot Server.

2. How to do

2.1 Spring Boot Server
2.1.1 Dependency




2.1.2 Customer – Data Model
package com.javasampleapproach.jpamysqlangular4.model;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "customer")
public class Customer implements Serializable {

	private static final long serialVersionUID = -3009157732242241606L;
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	@Column(name = "firstname")
	private String firstName;

	@Column(name = "lastname")
	private String lastName;

	protected Customer() {

	public long getId() {
		return id;

	public void setId(long id) { = id;

	public String getFirstName() {
		return firstName;

	public void setFirstName(String firstName) {
		this.firstName = firstName;

	public String getLastName() {
		return lastName;

	public void setLastName(String lastName) {
		this.lastName = lastName;

	public Customer(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;

	public String toString() {
		return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
2.1.3 JPA Repository
package com.javasampleapproach.jpamysqlangular4.repo;

import java.util.List;


import com.javasampleapproach.jpamysqlangular4.model.Customer;

public interface CustomerRepository extends CrudRepository {
	List findByLastName(String lastName);
2.1.4 REST Controller
package com.javasampleapproach.jpamysqlangular4.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.javasampleapproach.jpamysqlangular4.model.Customer;
import com.javasampleapproach.jpamysqlangular4.repo.CustomerRepository;

public class CustomerController {

	CustomerRepository repository;

	@GetMapping(value="/customer",  produces=MediaType.APPLICATION_JSON_VALUE)
	public List getAll() {
		List list = new ArrayList<>();
		Iterable customers = repository.findAll();

		return list;
	public Customer postCustomer(@RequestBody Customer customer) { Customer(customer.getFirstName(), customer.getLastName()));
		return customer;

	@GetMapping(value="/findbylastname/{lastName}",  produces=MediaType.APPLICATION_JSON_VALUE)
	public List findByLastName(@PathVariable String lastName) {

		List customers = repository.findByLastName(lastName);
		return customers;
	public void deleteCustomer(@PathVariable long id){
2.1.5 Configuration for Spring Datasource & JPA properties
2.2 Angular 4 Client
2.2.0 Model
export class Customer {
    public id: number;
    public firstName: string;
    public lastName: string;
2.2.1 DataService
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';

import 'rxjs/add/operator/toPromise';

import { Customer } from './customer';

export class DataService {

  private customersUrl = 'customer';  // URL to web API
  private headers = new Headers({'Content-Type': 'application/json'});

  constructor(private http: Http) {}

  // Get all customers
  getCustomers(): Promise {
    return this.http.get(this.customersUrl)
      .then(response => response.json() as Customer[])

  getCustomersByLastName(lastName: string): Promise {
    const url = `findbylastname/${lastName}`;
    return this.http.get(url)
      .then(response => response.json() as Customer)

  create(customer: Customer): Promise {
    return this.http
      .post("postcustomer", JSON.stringify(customer), {headers : this.headers})
      .then(res => res.json() as Customer)

  delete(id: number): Promise {
    const url = `${this.customersUrl}/${id}`;
    return this.http.delete(url, {headers: this.headers})
      .then(() => null)

  private handleError(error: any): Promise {
    console.error('Error', error); // for demo purposes only
    return Promise.reject(error.message || error);
2.2.2 Components

– CustomersComponent:

import { Component, OnInit } from '@angular/core';
import { Customer } from '../customer';
import { DataService } from '../data.service';

  selector: 'customers-list',
  templateUrl: './customers.component.html',
  styleUrls: ['./customers.component.css'],

export class CustomersComponent implements OnInit {
  customers: Customer[];
  selectedCustomer: Customer;

  constructor(private dataService: DataService) {}

  getCustomers() {
     this.dataService.getCustomers().then(customers => this.customers = customers);

  ngOnInit(): void {

  onSelect(cust: Customer): void {
    this.selectedCustomer = cust;
  • {{}} - {{cust.firstName}} {{cust.lastName}}

– CustomerDetailsComponent:

import { Component, Input } from '@angular/core';

import { Customer } from '../customer';
import { DataService } from '../data.service';

  selector: 'customer-detail',
  templateUrl: './customer-details.component.html',
  styleUrls: ['./customer-details.component.css'],
  providers: [DataService]

export class CustomerDetailsComponent {

  @Input() customer: Customer;

  constructor(private dataService: DataService) {}

  delete(): void {
    this.dataService.delete( => this.goBack());

  goBack(): void {

{{customer.firstName}} details:


– CreateCustomerComponent:

import {Customer} from '../customer';
import {DataService} from '../data.service';
import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';

  selector: 'app-create-customer',
  templateUrl: './create-customer.component.html',
  styleUrls: ['./create-customer.component.css']

export class CreateCustomerComponent implements OnInit {
  customer = new Customer;
  submitted = false;
  constructor(private dataService: DataService,
    private location: Location) {}

  ngOnInit() {

  newCustomer(): void {
    this.submitted = false;
    this.customer = new Customer();

  private save(): void {

  onSubmit() {
    this.submitted = true;;

  goBack(): void {

Create Customer Form

You submitted successfully!

– SearchCustomersComponent:

import {Component, OnInit} from '@angular/core';
import {Customer} from '../customer';
import {DataService} from '../data.service';

  selector: 'app-search-customers',
  templateUrl: './search-customers.component.html',
  styleUrls: ['./search-customers.component.css']

export class SearchCustomersComponent implements OnInit {
  lastName: string;
  customers: Customer[];
  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.lastName = "";

  private searchCustomers() {
    this.dataService.getCustomersByLastName(this.lastName).then(customers => this.customers = customers);

  onSubmit() {


Find By Last Name

  • {{}} - {{cust.firstName}} {{cust.lastName}}

2.2.3 AppRoutingModule
import {CreateCustomerComponent} from './create-customer/create-customer.component';
import {CustomersComponent} from './customers/customers.component';
import {SearchCustomersComponent} from './search-customers/search-customers.component';

import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

const routes: Routes = [
  {path: '', redirectTo: 'customer', pathMatch: 'full'},
  {path: 'customer', component: CustomersComponent},
  {path: 'add', component: CreateCustomerComponent},
  {path: 'findbylastname', component: SearchCustomersComponent},

  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]

export class AppRoutingModule {}

And AppComponent HTML for routing:

JSA - Angular Application!

2.2.4 AppModule
import {AppRoutingModule} from './app-routing.module';
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';

import {AppComponent} from './app.component';
import {CustomerDetailsComponent} from './customer-details/customer-details.component';
import {CustomersComponent} from './customers/customers.component';
import {DataService} from './data.service';
import {CreateCustomerComponent} from './create-customer/create-customer.component';

import {enableProdMode} from '@angular/core';
import {SearchCustomersComponent} from './search-customers/search-customers.component';

  declarations: [
  imports: [
  providers: [DataService],
  bootstrap: [AppComponent]

export class AppModule {}
2.2.5 Integrate Angular Client with Spring Boot Server

– Add proxy.conf.json to root folder of the project:

    "/": {
        "target": "http://localhost:8080",
        "secure": false

– Edit package.json file for “start” script:

"scripts": {
    "ng": "ng",
    "start": "ng serve --proxy-config proxy.conf.json",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"

3. Run & Check Result

Build and Run Spring Boot project with commandlines: mvn clean install and mvn spring-boot:run.
– Run the Angular App with command: npm start.

– Open browser for url http://localhost:4200/:
Add Customer:

Show Customers & click on any Customer:

>> MySQL DB:

Search Customer:

Go back to ShowCustomers, chose a Customer and click on Delete Customer:

>> MySQL DB after deleting:

IV. Source Code


By grokonez | August 29, 2017.

Last updated on February 7, 2020.

Related Posts

14 thoughts on “Angular 4 + Spring JPA + MySQL example | Angular 4 Http Client – Spring Boot RestApi Server”

  1. Hi I had been build this app in my Intellij Idea and when I try isert data to database from page ask me on user name and password and I don’t know what kind of password and username he is asking. Can you give me advice ?

  2. Hi, i found this error and i don’t know how to correct it. Could you help me plz
    2018-03-23 15:36:42.038 ERROR 10580 — [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: antlr/RecognitionException] with root cause

    java.lang.ClassNotFoundException: antlr.RecognitionException

  3. I am not able to run mvn clean install
    getting following error…

    Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 26.731 sec <<< FAILURE! – in com.javasampleapproach.jpamysqlangular4.SpringJpaMySqlAngular4ApplicationTests
    contextLoads(com.javasampleapproach.jpamysqlangular4.SpringJpaMySqlAngular4ApplicationTests) Time elapsed: 0.006 sec << [Help 1]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1]

  4. Hi,
    I want to run this code but I want know how these two projects exchange Angular4Client and SpringJPAMySQLAngular4?
    How to configure SpringBoot in order to allow these exchanges between SpringJPAMySQLAngular4 and SpringJPAMySQLAngular4? How to configure the server?

  5. Hi, Thank you for this tutorial, very usefull.
    I am bulding a similar project, but now i have a doubt. How do i do to implement a counter of register with angular.
    I have the method in tha backend side i tried it with postman and it works, but i could not implement in the frontend side with angular 4. I have the following code inn my userservice:

    public countUsers(): Observable {
       return this.http.get("http://localhost:8080/CountUsers");

    But in the component i don´t know how. Any suggestions?
    Thanks in advance!!

Got Something To Say:

Your email address will not be published. Required fields are marked *