Angular + Spring JPA + PostgreSQL example | Angular 4 Http Client - Spring Boot RestApi Server
angular
65
spring jpa
9
Postgresql
42
Male avatar

loveprogramming viết ngày 25/03/2021

https://grokonez.com/spring-framework/spring-mvc/angular-4-spring-jpa-postgresql-example-angular-4-http-client-spring-boot-restapi-server

Angular + Spring JPA + PostgreSQL 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 PostgreSQL and Angular 4 as a front-end technology to make request and receive response.

Related Posts:

Updated:

I. Technologies

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

II. Overview

angular-http-service-architecture

1. Spring Boot Server

angular-4-spring-jpa-postgresql-spring-boot-architecture

For more details about Spring JPA - PostgreSQL, please visit:
How to use Spring JPA with PostgreSQL | Spring Boot

2. Angular 4 Client

angular-4-spring-jpa-postgresql-angular-architecture

For more details:

III. Practice

1. Project Structure

1.1 Spring Boot Server

angular-4-spring-jpa-postgresql-spring-boot-structure

  • 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 application.properties
  • Dependencies for Spring Boot and PostgreSQL in pom.xml

    1.2 Angular 4 Client

    angular-4-spring-jpa-postgresql-angular-structure

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
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

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

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>
2.1.2 Customer - Data Model

package com.javasampleapproach.jpapostgresqlangular4.model;

import java.io.Serializable;

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

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

    private static final long serialVersionUID = -3009157732242241606L;
    @Id
    @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) {
        this.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;
    }

    @Override
    public String toString() {
        return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
    }
}
2.1.3 JPA Repository

package com.javasampleapproach.jpapostgresqlangular4.repo;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.javasampleapproach.jpapostgresqlangular4.model.Customer;

public interface CustomerRepository extends CrudRepository {
    List findByLastName(String lastName);
}
2.1.4 REST Controller

package com.javasampleapproach.jpapostgresqlangular4.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.jpapostgresqlangular4.model.Customer;
import com.javasampleapproach.jpapostgresqlangular4.repo.CustomerRepository;

@RestController
public class CustomerController {

    @Autowired
    CustomerRepository repository;

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

        customers.forEach(list::add);
        return list;
    }
    
    @PostMapping(value="/postcustomer")
    public Customer postCustomer(@RequestBody Customer customer) {

        repository.save(new 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;
    }
    
    @DeleteMapping(value="/customer/{id}")
    public void deleteCustomer(@PathVariable long id){
        
        repository.delete(id);
    }
}
2.1.5 Configuration for Spring Datasource & JPA properties

spring.datasource.url=jdbc:postgresql://localhost/testdb
spring.datasource.username=postgres
spring.datasource.password=123
spring.jpa.generate-ddl=true

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';

@Injectable()
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)
      .toPromise()
      .then(response => response.json() as Customer[])
      .catch(this.handleError);
  }

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

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

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

  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';

@Component({
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 {
this.getCustomers();
}

onSelect(cust: Customer): void {
this.selectedCustomer = cust;
}
}

<ul>
    <li *ngFor="let cust of customers"
        [class.selected]="cust === selectedCustomer" (click)="onSelect(cust)">
        <h4>{{cust.id}} - {{cust.firstName}} {{cust.lastName}}</h4> 
    </li>
</ul>
<customer-detail [customer]="selectedCustomer"></customer-detail>
  • CustomerDetailsComponent:
    
    import { Component, Input } from '@angular/core';

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

@Component({
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.customer.id).then(() => this.goBack());
}

goBack(): void {
window.location.replace('');
}
}

<div *ngIf="customer">
    <h2>{{customer.firstName}} details:</h2>
    <div>
        <label>id: </label> {{customer.id}}
    </div>
    <div>
        <label>First Name: </label> {{customer.firstName}}
    </div>
    <div>
        <label>Last Name: </label> {{customer.lastName}}
    </div>
    
    <button class="btn btn-danger" (click)="delete()">Delete</button>
</div>
  • CreateCustomerComponent:
    
    import {Customer} from '../customer';
    import {DataService} from '../data.service';
    import {Component, OnInit} from '@angular/core';
    import {Location} from '@angular/common';

@Component({
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 {
this.dataService.create(this.customer);
}

onSubmit() {
this.submitted = true;
this.save();
}

goBack(): void {
this.location.back();
}
}

<h3>Create Customer Form</h3>
<div [hidden]="submitted" style="width: 300px;">
    <form (ngSubmit)="onSubmit()">
        <div class="form-group">
            <label for="firstname">First Name</label> <input type="text"
                class="form-control" id="firstname" required
                [(ngModel)]="customer.firstName" name="firstname">
        </div>

        <div class="form-group">
            <label for="lastname">Last Name</label> <input type="text"
                class="form-control" id="lastname" required
                [(ngModel)]="customer.lastName" name="lastname">
        </div>

        <div class="btn-group">
            <button class="btn btn-primary" (click)="goBack()">Back</button>
            <button type="submit" class="btn btn-success">Submit</button>
        </div>
    </form>
</div>

<div [hidden]="!submitted">
    <div class="btn-group ">
        <h4>You submitted successfully!</h4>
        <button class="btn btn-primary" (click)="goBack()">Back</button>
        <button class="btn btn-success" (click)="newCustomer()">Add</button>
    </div>
</div>
  • SearchCustomersComponent:
    
    import {Component, OnInit} from '@angular/core';
    import {Customer} from '../customer';
    import {DataService} from '../data.service';

@Component({
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() {
this.searchCustomers();
}

}

<h3>Find By Last Name</h3>
<div style="width: 300px;">
    <form (ngSubmit)="onSubmit()">
        <div class="form-group">
            <label for="lastname">Last Name</label> <input type="text"
                class="form-control" id="lastname" required [(ngModel)]="lastName"
                name="lastname">
        </div>

        <div class="btn-group">
            <button type="submit" class="btn btn-success">Submit</button>
        </div>
    </form>
</div>
<ul>
    <li *ngFor="let cust of customers">
        <h4>{{cust.id}} - {{cust.firstName}} {{cust.lastName}}</h4>
    </li>
</ul>
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},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

export class AppRoutingModule {}

And AppComponent HTML for routing:

<div style="padding: 20px;">
    <h2 style="color: blue">JSA - Angular Application!</h2>
    <nav>
        <a routerLink="customer" class="btn btn-primary active" role="button" routerLinkActive="active">Customers</a>
        <a routerLink="add"    class="btn btn-primary active" role="button" routerLinkActive="active">Add</a>
        <a routerLink="findbylastname" class="btn btn-primary active" role="button" routerLinkActive="active">Search</a>
    </nav>
    <router-outlet></router-outlet>
</div>
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';

@NgModule({
  declarations: [
    AppComponent,
    CustomerDetailsComponent,
    CustomersComponent,
    CreateCustomerComponent,
    SearchCustomersComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule
  ],
  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:
    angular-4-spring-jpa-postgresql-result-add-customer

Show Customers & click on any Customer:
angular-4-spring-jpa-postgresql-result-show-customers

PostgreSQL DB:
angular-4-spring-jpa-postgresql-result-db

Search Customer:
angular-4-spring-jpa-postgresql-result-search-customers

Go back to ShowCustomers, chose a Customer and click on Delete Customer:
angular-4-spring-jpa-postgresql-result-delete-customer

PostgreSQL DB after deleting:
angular-4-spring-jpa-postgresql-result-db-after-delete-customer

IV. Source Code

SpringJpaPostgreSQLAngular4
Angular4Client

https://grokonez.com/spring-framework/spring-mvc/angular-4-spring-jpa-postgresql-example-angular-4-http-client-spring-boot-restapi-server

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

loveprogramming

451 bài viết.
79 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
1 0
Tutorial Link: (Link) (Ảnh) Django is a Pythonbased free and opensource web framework that follows the modeltemplateview architectural pattern. A...
loveprogramming viết 6 tháng trước
1 0
Male avatar
1 0
https://loizenai.com/angular11nodejspostgresqlcrudexample/ Angular 11 Node.js PostgreSQL Crud Example (Ảnh) Tutorial: “Angular 11 Node.js Postg...
loveprogramming viết 5 tháng trước
1 0
Male avatar
1 0
Angular Spring Boot jwt Authentication Example Github https://loizenai.com/angularspringbootjwt/ (Ảnh) Tutorial: ” Angular Spring Boot jwt Authe...
loveprogramming viết 5 tháng trước
1 0
Bài viết liên quan
Male avatar
1 0
https://loizenai.com/angular11nodejspostgresqlcrudexample/ Angular 11 Node.js PostgreSQL Crud Example (Ảnh) Tutorial: “Angular 11 Node.js Postg...
loveprogramming viết 5 tháng trước
1 0
Male avatar
0 0
https://grokonez.com/springframework/springmvc/angular4springbootcassandracrudexample no_toc]In this tutorial, grokonez shows you Angular Http Cli...
loveprogramming viết 2 tháng trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
451 bài viết.
79 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!