Angular + Spring JPA + PostgreSQL example | Angular 4 Http Client - Spring Boot RestApi Server
angular
43
spring jpa
9
Postgresql
23
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

209 bài viết.
64 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 5 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 4 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 4 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 4 tháng trước
1 0
White
25 0
(Ảnh) Slow query là gì? Khi các câu query chậm hơn một thời gian nhất định tùy theo bạn định nghĩa, ví dụ chậm hơn 50ms, thì các câu query đó đư...
Triet Pham viết gần 4 năm trước
25 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

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


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
209 bài viết.
64 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á!