Vous êtes sur la page 1sur 50

Angular4 Spring boot

Spring Data JPA


Rest CRUD

Monoem YOUNEB
Ingénieur Consultant Java EE
Vue Globale de l’application

- Modifier le nom et le prénom puis cliquer sur le bouton Valider

- Ajouter un enregistrement : appuyer sur le bouton « Ajouter une personne »


Introduire les données puis « Valider »

2
Structure de l’application

3
Structure de la partie Angular 4

4
Partie I : Spring rest Back End

1. Création d’un projet Maven : Spring Boot Initializr project

5
6
7
2. Configuration de Spring Boot

# ===============================
# = DATA SOURCE
# ===============================
spring.datasource.url =
jdbc:mysql://localhost/persondb?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDat
etimeCode=false&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password =
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1

# ===============================
# = JPA / HIBERNATE
# ===============================
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

3. Création de l’entité Person

8
a. Getter & setter

9
10
b. Constructeur par paramètres

c. Constructeur sans paramètres

d. To String

11
e. Entité « Person »

package com.app.person.entites;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {

@Id
@GeneratedValue
private Long id;
private String nom;
private String prenom;

// Getter & Setter


public Long getId() {
return id;
}

public void setId(Long id) {


this.id = id;
}

public String getNom() {


return nom;
}

public void setNom(String nom) {


this.nom = nom;
}

public String getPrenom() {


return prenom;
}

public void setPrenom(String prenom) {

12
this.prenom = prenom;
}

// Constructeur par paramètres


public Person(String nom, String prenom) {
this.nom = nom;
this.prenom = prenom;
}

// To String
@Override
public String toString() {
return "Person{" + "id=" + id + ", nom=" + nom + ", prenom=" + prenom + '}';
}

// Constructeur sans paramètres


public Person() {
}
}
4. Package « Repository »

13
14
package com.app.person.entites.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.app.person.entites.Person;
public interface PersonRepository extends JpaRepository<Person, Long>{
}

5. Création de RestController
Le RestController sert pour réceptionner les requêtes http envoyées par Angular.

package com.app.person.controller;

import com.app.person.repository.PersonRepository;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.app.person.entites.Person;
import org.springframework.web.bind.annotation.CrossOrigin;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;

@RestController
@RequestMapping("/rm")
@CrossOrigin(origins="http://localhost:4200", allowedHeaders="*")
public class PersonController {

@Autowired
private PersonRepository personRepository;

@GetMapping("/list")
public List<Person> getPersons() {

return personRepository.findAll();
}

@GetMapping("/show/{id}")
public Person getPerson(@PathVariable Long id) {

return personRepository.getOne(id);
}

@DeleteMapping("/delete/{id}")

15
public boolean deletePerson(@PathVariable Long id) {

personRepository.deleteById(id);
return true;
}

@PostMapping("/add")
public Person savePerson(@RequestBody Person person) {

return personRepository.save(person);
}

@PutMapping("/update")
public Person updatePerson(@RequestBody Person person) {

return personRepository.save(person);
}

}
6. Modification du main de notre application

package com.app.person;
package com.app.person;

import com.app.person.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;

16
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.app.person.entites.Person;

@SpringBootApplication
public class Angular4SpringBootRestCrudApplication implements CommandLineRunner{

@Autowired
private PersonRepository personRepository;

public static void main(String[] args) {


SpringApplication.run(Angular4SpringBootRestCrudApplication.class, args);
}

@Override
public void run(String... args) throws Exception{
personRepository.save(new Person("YOUNEB","Monoem"));
personRepository.save(new Person("MICHEL","Alexe"));
personRepository.save(new Person("ROBERT","Lisa"));
}

7. Test de la fonction getPersons

17
Partie II : Integration d’angular4
1. Installation de nodeJs

https://nodejs.org/en/

18
19
20
2. Vérifier la version de nodejs
Taper les touches windows + r au même temps
Tapez cmd

21
Taper node –v

Puis npm –v

Ou bien : Taper node –v & npm –v

3. Copier le path du dossier static

22
4. E:\workJee\workSpaceNetbeans8.2\Angular4SpringBootRestCRUD\src\main\resources

5. Installation du RestClient
Visiter le site d’angular CLI (command Line interface) https://cli.angular.io/

Shift + bouton droit sur le dossier Static

23
6. Installer npm dans le dossier static
Taper « npm install -g @angular/cli»

7. Pour créer un nouveau projet taper la commande « ng new


<nom-projet> »
Taper par exemple « ng new restperson »

24
25
8. Pour démarrer l’application taper la cmd :
cd restperson
ng serve

9. Autoriser l’accès
a. Visiter l’adresse : http://localhost:4200/

b. Télécharger & installer visual studio code : https://code.visualstudio.com/

26
27
28
c. Taper la cmd suivante pour ouvrir le projet avec visual studio code :
E:\workJee\workSpaceNetbeans8.2\Angular4SpringBootRestCRUD\src\main\resources\static\re
stperson> code .

d. Ouvrir le comande line avec visual studio code :

29
10. Ou bien cliquer sur la zone en rouge

30
e. Création de la classe User dans angular
Taper la commande : ng g class person
Résultat

La classe a été sous le répertoire src/app/

31
f. Ajouter les attributs

g. Création des components pour le crud (create, read , update and delete).
Liste des person : ng g component components/listperson

h. Ajout/editer (create/ipdate) de person : ng g component components/personform

i. Editer le fichier « app.modules.ts »


Importer RouterModule, Routes pour l’application
11. import {RouterModule, Routes} from '@angular/router';

Déclarer les routes


12. const appRoutes:Routes=[
13. {path:'list', component:ListpersonComponent},
14. {path:'add', component:PersonformComponent}
15. ]

Délarer les modules et importer les routes:

NgModule({
declarations: [
AppComponent,
ListpersonComponent,
PersonformComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(appRoutes)
],

Vue globale

32
Editer le fichier « app.component.html »
Remplacer le contenu par ce ci (création d’une route par défaut qui affiche « Hello
world ! »)

Route : localhost :4200/list

33
Développement des classes services (Angular)

En angular les services sont basés sur les commandes injectables


Création de service
Taper la cmd : ng g serve shared_service/person

Importer la classe service dans : src/app/app.module.ts


16.
17. import { PersonService } from'./shared-service/person.service';

Ajouter le provider de notre service


18. providers: [PersonService],

Ajouter angular : httprequest


19. import {HttpModule} from '@angular/http';

imports: [

34
BrowserModule,
HttpModule,
RouterModule.forRoot(appRoutes)
],
Vue globale

La classe service : person.service.ts


Import dans person.service.ts

20. import {Http, Response, Headers} from '@angular/http';

Vue globale

35
import { Injectable } from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
import {Observable} from 'rxjs/observable';
// importer le map de rxjs
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import {Person} from '../person';

@Injectable()
export class PersonService {
private baseUrl:string='http://localhost:8080/rm';
private headers= new Headers({'Content-Type':'application/json'});
private options = new RequestOptions({headers:this.headers});
//Injection de l'http
constructor(private _http:Http) { }

getPersons(){

// '/list' est une référence au @GetMapping("/list") dans le controlleur : PersonController(com.app.person.controller)


return this._http.get(this.baseUrl+'/list',this.options).map((response:Response)=>response.json())
.catch(this.errorHandle);
}

getPerson(id:Number){

// '/show/' est une référence au @GetMapping("/show/{id}") dans le controlleur :


PersonController(com.app.person.controller)
return this._http.get(this.baseUrl+'/show/'+id,this.options).map((response:Response)=>response.json())
.catch(this.errorHandle);
}

deletePerson(id:Number){

// '/delete/{id}' est une référence au @GetMapping("/delete/{id}") dans le controlleur :


PersonController(com.app.person.controller)
return this._http.delete(this.baseUrl+'/delete/'+id,this.options).map((response:Response)=>response.json())
.catch(this.errorHandle);
}

savePerson(person:Person){

// '/add' est une référence au @GetMapping("/add") dans le controlleur : PersonController(com.app.person.controller)


return this._http.post(this.baseUrl+'/add',JSON.stringify(person),this.options).map((response:Response)=>response.json())
.catch(this.errorHandle);
}

updatePerson(person:Person){

// '/update' est une référence au @GetMapping("/add") dans le controlleur : PersonController(com.app.person.controller)


return
this._http.put(this.baseUrl+'/update',JSON.stringify(person),this.options).map((response:Response)=>response.json())
.catch(this.errorHandle);
}

errorHandle(error:Response){
return Observable.throw(error||"Server Error");

21. Import de classe service dans listperson.component.ts


22. import {Component, OnInit } from '@angular/core';
23. import {PersonService} from '../../shared-service/person.service';
24. import {Person} from '../../person';
25.
26. @Component({
27. selector: 'app-listperson',
28. templateUrl: './listperson.component.html',
29. styleUrls: ['./listperson.component.css']
30. })
31. export class ListpersonComponent implements OnInit {
32.

36
33. private persons:Person[];
34. constructor(private _personService:PersonService) { }
35.
36. ngOnInit() {
37. // appel des méthodes de person.service.ts
38. this._personService.getPersons().subscribe((persons)=>{
39. console.log(persons);
40. this.persons=persons;
41. },(error)=>{console.log(error);
42. })
43. }
44.
45. }

Autorisation de Restcontroller

Affichage de listperson.component.html
46. <table>
47. <thead>
48. <th>ID</th>
49. <th>Nom</th>
50. <th>PRENOM</th>
51. </thead>
52.
53. <tbody>
54. <tr *ngFor ="let p of persons">
55. <td>{{p.id}}</td>
56. <td>{{p.nom}}</td>
57. <td>{{p.prenom}}</td>
58. </tr>
59.
60. </tbody>
61.
62. </table>

Résultat : http://localhost:4200/list

37
Installation de Bootstrap
Taper la cmd : npm install bootstrap@4.0.0-beta –save

63. Ouvrir le fichier angular-cli.json et modifier le style en mettant le path de bootstrap


local & sauvegarder

38
Import directly in src/style.css or src/style.scss:
64. @import '~bootstrap/dist/css/bootstrap.min.css';

Modifier le style du fichier listpersont.component.html


65. <div class="container">
66. <table class="table table-striped">
67. <thead>
68. <th>ID</th>
69. <th>Nom</th>
70. <th>PRENOM</th>
71. </thead>
72.
73. <tbody>
74. <tr *ngFor ="let p of persons">
75. <td>{{p.id}}</td>
76. <td>{{p.nom}}</td>
77. <td>{{p.prenom}}</td>
78. </tr>
79.
80. </tbody>
81.
82. </table>
83.
84. </div>

Taper la cmd : ng serve –open et consulter l’url : http://localhost:4200/list

39
Ajouter des boutons (nouveau, modifier & supprimer) dans : listperson.component.ts

85.
86. <div class="container">
87. <table class="table table-striped">
88. <thead>
89. <th>ID</th>
90. <th>Nom</th>
91. <th>PRENOM</th>
92. <th>Action</th>
93. </thead>
94.
95. <tbody>
96. <tr *ngFor ="let p of persons">
97. <td>{{p.id}}</td>
98. <td>{{p.nom}}</td>
99. <td>{{p.prenom}}</td>
100. <td>
101. <button class="btn btn-primary">Modifier</button>
102. <button class="btn btn-danger">Supprimer</button>
103. </td>
104. </tr>
105.
106. </tbody>
107.
108. </table>
109. <button class="btn btn-primary">Ajouter une personne</button>

40
110. </div>
111.

Résulatat

Bouton Supprimer (Delete)


Revenons au fichier listperson.component.html

<div class="container">
<table class="table table-striped">
<thead>
<th>ID</th>
<th>Nom</th>
<th>PRENOM</th>
<th>Action</th>
</thead>

<tbody>
<tr *ngFor ="let p of persons">
<td>{{p.id}}</td>
<td>{{p.nom}}</td>
<td>{{p.prenom}}</td>
<td>
<button class="btn btn-primary">Modifier</button>
<button class="btn btn-danger" (click)="deletePerson(person)">Supprimer</button>
</td>
</tr>

</tbody>
</table>
<button class="btn btn-primary">Ajouter une personne</button>
</div>

112. Modifier le fichier listperson.component.ts et implémenter la méthode


deletperson()

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


import {PersonService} from '../../shared-service/person.service';
import {Person} from '../../person';
import { splitClasses } from '@angular/compiler';

@Component({
selector: 'app-listperson',
templateUrl: './listperson.component.html',
styleUrls: ['./listperson.component.css']
})
export class ListpersonComponent implements OnInit {

private persons:Person[];

41
constructor(private _personService:PersonService) { }

ngOnInit() {
// appel des méthodes de person.service.ts
this._personService.getPersons().subscribe((persons)=>{
console.log(persons);
this.persons=persons;
},(error)=>{console.log(error);
})
}

deletePerson(person){
this._personService.deletePerson(person.id).subscribe((data)=>{
this.persons.splice(this.persons.indexOf(person),1);
},(error)=>{console.log(error);
})

create and update implementation


1. Modifier un enregistrement
On cliquant sur le bouton « modifier » le détails du personne s’affiche dans un formulaire
puis on peut l’éditer.
a. Modifier le fichier app.module.ts
- Ajouter l’import de formsModule
-
- import {FormsModule} from '@angular/forms';
-

imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot(appRoutes)
],

42
Vue globale du fichier app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

import { AppComponent } from './app.component';


import { ListpersonComponent } from './components/listperson/listperson.component';
import { PersonformComponent } from './components/personform/personform.component';

import { PersonService } from './shared-service/person.service';


import {HttpModule} from '@angular/http';

import {FormsModule} from '@angular/forms';

const appRoutes:Routes=[
{path:'list', component:ListpersonComponent},
{path:'add', component:PersonformComponent}
]

@NgModule({
declarations: [
AppComponent,
ListpersonComponent,
PersonformComponent
],
imports: [
BrowserModule,
HttpModule,
FormsModule,
RouterModule.forRoot(appRoutes)
],
providers: [PersonService],
bootstrap: [AppComponent]
})
export class AppModule { }

b. Modifier le fichier personform.component.ts

- Importer la classe Person


- import {Person} from '../../person';

- Déclarer Person comme attribut (pour le bind dans le formulaire)


private person:Person;

- Vue globale du fichier personform.component.ts


- import { Component, OnInit } from '@angular/core';
- import {Person} from '../../person';

43
-
- @Component({
- selector: 'app-personform',
- templateUrl: './personform.component.html',
- styleUrls: ['./personform.component.css']
- })
- export class PersonformComponent implements OnInit {
- private person:Person;
- constructor() { }
-
- ngOnInit() {
- }
-
- }
-

c. Création du formulaire « personform.component.html »

<div class="container">

<form>
<div class="form group">

<label for="id">ID : </label>


<input type="text" name="id" class="form-control" [(ngModel)]="person.id">
</div>

<label for="nom">Nom : </label>


<div class="form group">
<input type="text" name="nom" class="form-control" [(ngModel)]="person.nom">
</div>

<label for="prenom">Prénom : </label>


<div class="form group">
<input type="text" name="prenom" class="form-control" [(ngModel)]="person.prenom">
</div>

<input type="submit" value="Valider" class="btn btn-success">

</form>

</div>

- Visiter l’adresse : http://localhost:4200/add

44
- Passer l’objet Person au formulaire
Ouvrir le fichier : listperson.component.html

<div class="container">
<table class="table table-striped">
<thead>
<th>ID</th>
<th>Nom</th>
<th>PRENOM</th>
<th>Action</th>
</thead>

<tbody>
<tr *ngFor ="let person of persons">
<td>{{person.id}}</td>
<td>{{person.nom}}</td>
<td>{{person.prenom}}</td>
<td>
<button class="btn btn-primary" (click)="showPerson(person)">Modifier</button>
<button class="btn btn-danger" (click)="deletePerson(person)">Supprimer</button>
</td>
</tr>

</tbody>

</table>
<button class="btn btn-primary" (click)="addPerson()">Ajouter une personne</button>
</div>

- Implémenter les deux méthodes : showPerson(person) & addPerson()


 Déclarer la classe Personne dans le service : person.service.ts
Pour qu’il soit injectable
// Injection de Person
private person:Person;

 Création du setter & getter

setter(person:Person){
this.person=person;
}

getter(){
return this.person;
}

 Vue globale du fichier person.service.ts


 import { Injectable } from '@angular/core';

45
 import {Http, Response, Headers, RequestOptions} from '@angular/http';
 import {Observable} from 'rxjs/observable';
 // importer le map de rxjs
 import 'rxjs/add/operator/map';
 import 'rxjs/add/operator/catch';
 import 'rxjs/add/observable/throw';
 import {Person} from '../person';

 @Injectable()
 export class PersonService {
 private baseUrl:string='http://localhost:8080/rm';
 private headers= new Headers({'Content-Type':'application/json'});
 private options = new RequestOptions({headers:this.headers});
 // Injection de Person
 private person:Person;
 //Injection de l'http
 constructor(private _http:Http) { }

 getPersons(){

 // '/list' est une référence au @GetMapping("/list") dans le controlleur :
PersonController(com.app.person.controller)
 return this._http.get(this.baseUrl+'/list',this.options).map((response:Response)=>response.json())
 .catch(this.errorHandle);
 }

 getPerson(id:Number){

 // '/show/' est une référence au @GetMapping("/show/{id}") dans le controlleur :
PersonController(com.app.person.controller)
 return this._http.get(this.baseUrl+'/show/'+id,this.options).map((response:Response)=>response.json())
 .catch(this.errorHandle);
 }

 deletePerson(id:Number){

 // '/delete/{id}' est une référence au @GetMapping("/delete/{id}") dans le controlleur :
PersonController(com.app.person.controller)
 return this._http.delete(this.baseUrl+'/delete/'+id,this.options).map((response:Response)=>response.json())
 .catch(this.errorHandle);
 }

 savePerson(person:Person){

 // '/add' est une référence au @GetMapping("/add") dans le controlleur :
PersonController(com.app.person.controller)
 return
this._http.post(this.baseUrl+'/add',JSON.stringify(person),this.options).map((response:Response)=>response.json())
 .catch(this.errorHandle);
 }

 updatePerson(person:Person){

 // '/update' est une référence au @GetMapping("/add") dans le controlleur :
PersonController(com.app.person.controller)
 return
this._http.put(this.baseUrl+'/update',JSON.stringify(person),this.options).map((response:Response)=>response.json(
))
 .catch(this.errorHandle);
 }

 errorHandle(error:Response){
 return Observable.throw(error||"Server Error");

 }

 setter(person:Person){
 this.person=person;
 }

 getter(){
 return this.person;
 }

 }

46
 Ouvrir le fichier listperson.component.ts
import {Component, OnInit } from '@angular/core';
import {PersonService} from '../../shared-service/person.service';
import {Person} from '../../person';
import {splitClasses } from '@angular/compiler';
// pour la redirection
import {Router} from '@angular/router';

@Component({
selector: 'app-listperson',
templateUrl: './listperson.component.html',
styleUrls: ['./listperson.component.css']
})
export class ListpersonComponent implements OnInit {

private persons:Person[];
constructor(private _personService:PersonService, private _router:Router) { }

ngOnInit() {
// appel des méthodes de person.service.ts
this._personService.getPersons().subscribe((persons)=>{
console.log(persons);
this.persons=persons;
},(error)=>{console.log(error);
})
}
deletePerson(person){
this._personService.deletePerson(person.id).subscribe((data)=>{

this.persons.splice(this.persons.indexOf(person),1);
},(error)=>{console.log(error);
})

showPerson(person) {
// setter la personne
this._personService.setter(person);
this._router.navigate(['/add']);
}

addPerson() {
let person=new Person();
this._personService.setter(person);
this._router.navigate(['/add']);
}

 Modifier le ficher : personform.component.ts


Pour importer le service
import { Component, OnInit } from '@angular/core';
import {Person} from '../../person';
import {PersonService} from '../../shared-service/person.service';
import {Router} from '@angular/router';

@Component({
selector: 'app-personform',
templateUrl: './personform.component.html',
styleUrls: ['./personform.component.css']
})
export class PersonformComponent implements OnInit {
private person:Person;
constructor(private _personservice:PersonService, private _router:Router) { }

ngOnInit() {
this.person=this._personservice.getter();
}

47
-cliquer sur modifier

- Cliquer sur « Ajouter une personne »

a. Implémentation de la méthode d’ajout


- Modifier le fichier persform.component.html
- <div class="container">
-
- <form (ngSubmit)="saveForm()">
- <div class="form group">
-
- <label for="id">ID : </label>
- <input type="text" name="id" class="form-control" [(ngModel)]="person.id">
- </div>
-
- <label for="nom">Nom : </label>
- <div class="form group">
- <input type="text" name="nom" class="form-control" [(ngModel)]="person.nom">
- </div>
-
- <label for="prenom">Prénom : </label>
- <div class="form group">
- <input type="text" name="prenom" class="form-control" [(ngModel)]="person.prenom">
- </div>
-
- <input type="submit" value="Valider" class="btn btn-success">

48
-
- </form>
-
- </div>
-

- Modifier le fichier personform.component.ts


Pour ajouter ou modifier l’enregistrement
import { Component, OnInit } from '@angular/core';
import {Person} from '../../person';
import {PersonService} from '../../shared-service/person.service';
import {Router} from '@angular/router';

@Component({
selector: 'app-personform',
templateUrl: './personform.component.html',
styleUrls: ['./personform.component.css']
})
export class PersonformComponent implements OnInit {
private person:Person;
constructor(private _personservice:PersonService, private _router:Router) { }

ngOnInit() {
this.person=this._personservice.getter();
}

saveForm(){
if ( this.person.id==undefined){
this._personservice.savePerson(this.person).subscribe((person)=>{
console.log(person);
this._router.navigate(['/list']);
},(error)=>{console.log(error);});

}else{
this._personservice.updatePerson(this.person).subscribe((person)=>{
console.log(person);
this._router.navigate(['/list']);
},(error)=>{console.log(error);});
// fin else
}
///
}
}

- Résulat : visiter l’url http://localhost:4200/list


- Cliquer su « Modifier »

- Modifier le nom et le prénom puis cliquer sur le bouton Valider

49
- Ajouter un enregistrement : appuyer sur le bouton « Ajouter une personne »
Introduire les données puis « Valider »

50