0% ont trouvé ce document utile (0 vote)
438 vues44 pages

Cours Spring Boot Rest Controller

Le document décrit l'utilisation de Spring Boot pour créer des services web REST. Il présente des annotations comme @ResponseBody et @RestController. Il explique le rôle du contrôleur et donne un exemple de contrôleur PersonneRestController pour gérer des ressources de type Personne.

Transféré par

Kamel Ahmed
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
438 vues44 pages

Cours Spring Boot Rest Controller

Le document décrit l'utilisation de Spring Boot pour créer des services web REST. Il présente des annotations comme @ResponseBody et @RestController. Il explique le rôle du contrôleur et donne un exemple de contrôleur PersonneRestController pour gérer des ressources de type Personne.

Transféré par

Kamel Ahmed
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Spring Boot : services web REST

Wejdene
Achref El SAIED
Mouelhi

Docteur de l’université d’Aix-Marseille


Maitre Technolgue
Chercheur en Informatique
en programmation par contrainte (IA)
IngISET
énieurZaghouan
en génie logiciel

wejdenesaied@[Link]
[Link]@[Link]

H & H: Research and Training 1 / 55


Plan

1 Introduction

2 Quelques annotations
@ResponseBody
@RequestBody
@RestController
@JsonIgnoreProperties
@CrossOrigin

3 Commande curl

4 Gestion d’erreurs

H & H: Research and Training 2 / 55


Introduction

Spring Boot

Service web (WS pour Web Service) ?

Un programme (ensemble de fonctionnalités exposées en temps


réel et sans intervention humaine)
H I ©
Accessible via internet, ou intranet
UEL
O
f E LM
Indépendant de tout système d’exploitation

ch r e
Indépendant de tout langage de programmation

©A
Utilisant un système standard d’échange (XML ou JSON), ces
messages sont généralement transportés par des protocoles
internet connus HTTP (ou autres comme FTP, SMTP...)
Pouvant communiquer avec d’autres WS

H & H: Research and Training 3 / 55


Introduction

Spring Boot

Les WS peuvent utiliser les technologies web suivantes :

HTTP (Hypertext Transfer Protocol) : le protocole, connu, utilisé par le


World Wide Web et inventé par Roy Fiedling.

H I ©
U EL
REST (Representational State Transfer) : une architecture de services Web,
créée aussi par Roy Fielding en 2000 dans sa thèse de doctorat.
M O
E L : unla transmission
SOAP (Simple object Access Protocol)
f
protocole, défini par Microsoft et IBM

h r e
ensuite standarisé par W3C, permettant de messages entre

© Ac
objets distants (physiquement distribués).

WSDL (Web Services Description Language) : est un langage de description de


service web utilisant le format XML (standardisé par le W3C depuis 2007).

UDDI (Universal Description, Discovery and Integration) : un annuaire de WS.

H & H: Research and Training 4 / 55


Introduction

HTTP, REST (Representational State Transfer) et RESTful ?

Les API REST sont basées sur le protocole HTTP (architecture client/serveur) et
utilisent le concept de ressource.

Une ressource est identifiée par une URI unique.

I ©
L’API REST utilise donc des méthodes suivantes pour l’échange de données
H
entre client et serveur
U EL
O
LM
GET pour la récupération,
POST pour l’ajout,
r e f E
ch
DELETE pour la suppression,

©A
PUT pour la modification,
...

Plusieurs formats possibles pour les données échangées : texte, XML, JSON...

RESTful est l’adjectif qui désigne une API REST.

H & H: Research and Training 5 / 55


Introduction

Spring Boot

Rôle du contrôleur dans une application MVC

Le contrôleur reçoit une requête HTTP et communique avec

H I ©
modèle, service, constructeur de formulaires pour retourner une

EL
réponse HTTP contenant une page HTML.

O U
Le contrôleur peut aussi retourner une réponse HTTP ne contenant
pas de vue.
f E LM
Il retourne des c r e
h ées sous format JSON, XML...
donn
© A

H & H: Research and Training 6 / 55


Introduction

Spring Boot

Rôle du contrôleur dans une application MVC

Le contrôleur reçoit une requête HTTP et communique avec

H I ©
modèle, service, constructeur de formulaires pour retourner une

EL
réponse HTTP contenant une page HTML.

O U
Le contrôleur peut aussi retourner une réponse HTTP ne contenant
pas de vue.
f E LM
Il retourne des c r e
h ées sous format JSON, XML...
donn
© A

Ceci est l’objet de ce chapitre.

H & H: Research and Training 6 / 55


Introduction

Considérons le contrôleur PersonneRestController


@Controller
public class PersonneRestController {
@Autowired
private PersonneRepository personneRepository;

@GetMapping("/personnes")
public String getPersonnes(Model model) {

I ©
List<Personne> personnes = [Link]();
H
EL
[Link]("personnes", personnes);

}
return "showPersonnes";

O U
@GetMapping("/personnes/{id}")

f E LM
public String getPersonne(@PathVariable("id") long id, Model model) {

r e
Personne personne = [Link](id).orElse(null);
ch
©A
[Link]("personne", personne);
return "showPersonne";
}
@PostMapping("/addPersonne")
public String addPersonne(Personne personne, Model model) {
Personne personne2 = [Link](personne);
[Link]("personne", personne2);
return "showPersonne";
}
}
H & H: Research and Training 7 / 55
Introduction

Spring Boot

Explication

Le contrôleur PersonneRestController contient trois


H I ©
méthodes permettant soit de récupérer une ou plusieurs per-
U EL
sonnes de la base de données et d’afficher le résultat dans la vue,
O
l’afficher dans la vue. f E LM
soit d’ajouter une nouvelle personne dans la base de données et

r e
h deux vues (soit showPersonnes, soit
cretourne
© A
Le contrôleur
showPersonne) qui servent principalement à afficher des
données récupérées de la base de données

H & H: Research and Training 8 / 55


Introduction

Spring Boot
Commençons par modifier le point d’entrée (qui implémentera l’interface
ApplicationRunner) pour ajouter des tuples dans la base de données avant d’appeler
nos services web REST
@SpringBootApplication
public class FirstSpringBootApplication implements ApplicationRunner {

@Autowired
H I ©
EL
private PersonneRepository personneRepository;

O U
LM
public static void main(String[] args) {
[Link]([Link], args);
}
r e f E
ch
©A
@Override
public void run(ApplicationArguments args) throws Exception {
// TODO Auto-generated method stub
Personne personne1 = new Personne("wick", "john");
Personne personne2 = new Personne("dalton", "jack");
[Link](personne1);
[Link](personne2);
}
}

H & H: Research and Training 9 / 55


Quelques annotations @ResponseBody

Spring Boot

Remarques
H I ©
EL
Comment fait-on si le contrôleur doit récupérer et retourner les
U
O
données sans les afficher dans une vue (Notre projet Spring de-
vient donc un service web) ?
f E LM
ch r e
L’affichage sera accordé à un framework Front-end tel que Angular
ou autre ©A

H & H: Research and Training 10 / 55


Quelques annotations @ResponseBody

Nouveau contenu du contrôleur PersonneRestController

@Controller
public class PersonneRestController {

@Autowired
private PersonneRepository personneRepository;

@GetMapping("/personnes")
public String getPersonnes() {
H I ©
return [Link]().toString();
U EL
}
O
@GetMapping("/personnes/{id}")
f E LM
r e
public String getPersonne(@PathVariable("id") long id) {

ch
return [Link](id).orElse(null).toString();
}
©A
@PostMapping("/personnes")
public String addPersonne(Personne personne) {
[Link](personne);
return [Link](personne).toString();
}
}

H & H: Research and Training 11 / 55


Quelques annotations @ResponseBody

Spring Boot

Problématique
Si on saisit l’URL localhost:8080/firstspringmvc/personnes
dans la barre d’adresse, la méthode getPersonnes sera
H I ©
exécutée
U EL
O
f E LM
La liste de personnes sera récupérée de la base de données

r e
Comme le type de la valeur de retour de cette méthode est
ch
©A
String, le contrôleur va chercher à afficher la vue dont le nom
est précisé après return
Mais cette valeur ne correspond pas à une vue, elle correspond
plutôt à des valeurs récupérées de la base de données.

H & H: Research and Training 12 / 55


Quelques annotations @ResponseBody

Pour corriger ça, on peut utiliser l’annotation @ResponseBody


@Controller
public class PersonneRestController {

@Autowired
private PersonneRepository personneRepository;

@GetMapping("/personnes")
@ResponseBody
H I ©
EL
public String getPersonnes() {

}
return [Link]().toString();
O U
@GetMapping("/personnes/{id}")
@ResponseBody
f E LM
ch r e
public String getPersonne(@PathVariable("id") long id) {

©A
return [Link](id).orElse(null).toString();
}

@PostMapping("/personnes")
@ResponseBody
public String addPersonne(Personne personne) {
[Link](personne);
return [Link](personne).toString();
}
}
H & H: Research and Training 13 / 55
Quelques annotations @ResponseBody

Spring Boot

Pour tester
allez à l’URL
localhost:8080/firstspringmvc/personnes
H I ©
Ou localhost:8080/firstspringmvc/personnes/1
U EL
O
f E LM
ch r e
©A

H & H: Research and Training 14 / 55


Quelques annotations @ResponseBody

Spring Boot

Pour tester
allez à l’URL
localhost:8080/firstspringmvc/personnes
H I ©
Ou localhost:8080/firstspringmvc/personnes/1
U EL
O
f E LM
ch r e
Constat
© A
Le résultat obtenu est une chaı̂ne de caractère ou un tableau de
chaı̂ne de caractère
Sachant que Spring nous offre la possibilité de récupérer le
résultat sous format JSON

H & H: Research and Training 14 / 55


Quelques annotations @ResponseBody

Pour corriger ça, on peut utiliser l’annotation @ResponseBody


@Controller
public class PersonneRestController {

@Autowired
private PersonneRepository personneRepository;

@GetMapping("/personnes")
@ResponseBody
H I ©
EL
public List<Personne> getPersonnes() {

}
return [Link]();
O U
@GetMapping("/personnes/{id}")
@ResponseBody
f E LM
ch r e
public Personne getPersonne(@PathVariable("id") long id) {

©A
return [Link](id).orElse(null);
}

@PostMapping("/personnes")
@ResponseBody
public Personne addPersonne(Personne personne) {
[Link](personne);
return [Link](personne);
}
}
H & H: Research and Training 15 / 55
Quelques annotations @ResponseBody

Spring Boot

Comment préciser le format (JSON ou XML) souhaité ?


H I ©
Utilisez Postman en choisissant la méthode GET
U EL
O
f E LM
Dans Headers, ajoutez les deux clés Accept et Content-Type
avec la valeur application/json (ou application/xml)
ch r e
©A
Envoyez

H & H: Research and Training 16 / 55


Quelques annotations @ResponseBody

On peut aussi indiquer avec l’attribut produces les formats acceptés


@Controller
public class PersonneRestController {
@Autowired
private PersonneRepository personneRepository;

@GetMapping(value = "/personnes", produces = { MediaType.


APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
@ResponseBody
H I ©
EL
public List<Personne> getPersonnes() {

}
return [Link]();
O U
@GetMapping("/personnes/{id}")
@ResponseBody
f E LM
ch r e
public Personne getPersonne(@PathVariable("id") long id) {

©A
return [Link](id).orElse(null);
}

@PostMapping("/personnes")
@ResponseBody
public Personne addPersonne(Personne personne) {
[Link](personne);
return [Link](personne);
}
}
H & H: Research and Training 17 / 55
Quelques annotations @RequestBody

Spring Boot
Pour ajouter une personne

Utilisez Postman en précisant la méthode POST


Dans Headers, ajoutez les clés Accept et Content-Type avec
la valeur application/json
H I ©
Dans Body, cochez raw et sélectionnez JSON U EL
L MO
r e f E
Ajoutez l’objet JSON suivant
{
A h
c"maggio",
©
"nom":
"prenom": "carol"
}

Envoyez

H & H: Research and Training 18 / 55


Quelques annotations @RequestBody

Spring Boot

Résultat
H I ©
Erreur et la personne n’a pas été ajoutée E
U L la base de
dans
données
L MO
r
Message affiché danse f
la E : {"num":null,
console
h
"nom":null,c"prenom":null}
A
©

H & H: Research and Training 19 / 55


Quelques annotations @RequestBody

Spring Boot

Pour récupérer l’objet défini dans le corps de la requête HTTP et assurer le


binding avec l’objet défini comme paramètre de la méthode addPersonne(), on
doit utiliser l’annotation @RequestBody
H I ©
@PostMapping("/personnes")
U EL
@ResponseBody
O
f E LM
public Personne addPersonne(@RequestBody Personne personne) {

ch
[Link](personne);r e
©A
return [Link](personne);

H & H: Research and Training 20 / 55


Quelques annotations @RequestBody

Spring Boot

On peut aussi indiquer avec l’attribut consumes les formats acceptés

@PostMapping(value = "/personnes", consumes = { MediaType.


H I ©
APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
U EL
@ResponseBody
O
public Personne addPersonne(Personne personne) {
f E LM
[Link](personne);

ch r e
return [Link](personne);
}
©A

H & H: Research and Training 21 / 55


Quelques annotations @RestController

Spring Boot

Constats

H I ©
Toutes les méthodes du contrôleur ne retournent pas de vue

U EL
Toutes ces méthodes sont annotées par @ResponseBody

L MO
r e f E
A ch
©

H & H: Research and Training 22 / 55


Quelques annotations @RestController

Spring Boot

Constats

H I ©
Toutes les méthodes du contrôleur ne retournent pas de vue

U EL
Toutes ces méthodes sont annotées par @ResponseBody

L MO
r e f E
A ch
©
On peut optimiser
On peut utiliser l’annotation @RestController

H & H: Research and Training 22 / 55


Quelques annotations @RestController

Spring Boot
Remplaçons @ResponseBody par @RestController
@RestController
public class PersonneRestController {

@Autowired
private PersonneRepository personneRepository;

H I ©
@GetMapping("/personnes")
public List<Personne> getPersonnes() {
U EL
O
LM
return [Link]();
}

r e f E
ch
@GetMapping("/personnes/{id}")

©A
public Personne getPersonne(@PathVariable("id") long id) {
return [Link](id).orElse(null);
}

@PostMapping("/personnes")
public Personne addPersonne(@RequestBody Personne personne) {
[Link](personne);
return [Link](personne);
}
}
H & H: Research and Training 23 / 55
Quelques annotations @RestController

Spring Boot

H I ©
Exercice 1
U EL
O
LM
Écrire puis tester les deux méthodes HTTP put et delete qui permet-
f E
tront de modifier ou supprimer une personne.
r e
ch
©A

H & H: Research and Training 24 / 55


Quelques annotations @RestController

Spring Boot

Pour la suite

I ©
supposons qu’une personne peut avoir une ou plusieurs adresses
H
U EL
commençons par créer une entité Adresse avec 4 attributs id,
rue, ville et codePostal MO
f E L liste de Adresse
hr e
déclarons dans Personne
c
une
utilisons© A
Postman pour ajouter des personnes dans la base de
données avec leurs adresses

H & H: Research and Training 25 / 55


Quelques annotations @RestController

Spring Boot

La classe Adresse
@Entity
public class Adresse {

H I ©
@Id
U EL
O
@GeneratedValue(strategy = [Link])
private Long id;
private String rue;
f E LM
private String codePostal;
ch r e
©A
private String ville;

// N'oublions pas les getters / setters / toString /


Constructeur sans paramètre
}

H & H: Research and Training 26 / 55


Quelques annotations @RestController

Spring Boot

Le nouveau contenu de la classe Personne

@Entity
public class Personne {

@Id
H I ©
@GeneratedValue(strategy = [Link])
private Long num;
U EL
O
LM
private String nom;
private String prenom;

r e f E
ch
@ManyToMany(cascade = { [Link], [Link]},

©A
fetch = [Link])
private List<Adresse> adresses = new ArrayList<Adresse>();

// N'oublions pas les getters / setters / toString


}

Seules les propriétés MERGE et REFRESH sont demandées.

H & H: Research and Training 27 / 55


Quelques annotations @RestController

Spring Boot

Le contenu de AdresseRepository

package [Link];
H I ©
import [Link];
U EL
O
LM
import [Link];

e f E
public interface AdresseRepository extends JpaRepository<Adresse, Long>
r
ch
{

}
©A

H & H: Research and Training 28 / 55


Quelques annotations @RestController

Spring Boot

Exemple d’objet JSON à persister (en utilisant Postman)


{
"nom": "el mouelhi",
"prenom": "achref",
H I ©
"adresses": [
U EL
{
O
"rue": "paradis",
f E LM
"ville": "marseille",
ch r e
©A
"codePostal": "13015"
}
]
}

Message d’erreur parlant d’un objet faisant référence à une


instance non sauvegardée

H & H: Research and Training 29 / 55


Quelques annotations @RestController

Spring Boot
Modifions PersonneRestController afin qu’il puisse attacher les entités
inverses avant de les persister
@PostMapping("/personnes")
public Personne addPersonne(@RequestBody Personne personne) {

[Link](personne);
H I ©
List <Adresse> adresses = [Link]();
U EL
for (Adresse adresse : adresses) {
O
Adresse adr = null;
if ([Link]() != null) {
f E LM
ch r e
adr = [Link]([Link]()).orElse(

©A
null);
[Link]([Link](adresse), adr);
} else {
adr = [Link](adresse);
}
}
return [Link](personne);
}

H & H: Research and Training 30 / 55


Quelques annotations @RestController

Spring Boot

La réponse de la requête précédente (avec les clés primaires)


{
"num": 1,
"nom": "el mouelhi",
H I ©
EL
"prenom": "achref",
"adresses": [
O U
{
f E LM
"id": 1,
"rue": "paradis", ch r e
©A
"ville": "marseille",
"codePostal": "13015"
}
]
}

H & H: Research and Training 31 / 55


Quelques annotations @RestController

Spring Boot
Et si on voulait ajouter une personne en lui affectant l’adresse
précédente
{
"nom": "wick",
"prenom": "john",
H I ©
"adresses": [
U EL
{
O
"id": 1,
f E LM
"rue": "paradis",
ch r e
"codePostal": "13015",

}
©A
"ville": "marseille"

]
}

H & H: Research and Training 32 / 55


Quelques annotations @RestController

Spring Boot
Et si on voulait ajouter une personne en lui affectant l’adresse
précédente
{
"nom": "wick",
"prenom": "john",
H I ©
"adresses": [
U EL
{
O
"id": 1,
f E LM
"rue": "paradis",
ch r e
"codePostal": "13015",

}
©A
"ville": "marseille"

]
}

Pour l’adresse, seule la clé primaire compte, les autres attributs sont
facultatifs.

H & H: Research and Training 32 / 55


Quelques annotations @RestController

Spring Boot

En renvoyant l’objet précédent, la réponse est :


{
"num": 2,
"nom": "wick",
H I ©
EL
"prenom": "john",
"adresses": [
O U
{
f E LM
"id": 1,
ch r
"rue": "paradis",
e
©A
"codePostal": "13015",
"ville": "marseille"
}
]
}

H & H: Research and Training 33 / 55


Quelques annotations @JsonIgnoreProperties

Spring Boot
Modifions la classe Adresse pour rendre son association avec la classe
Personne bidirectionnelle

@Entity
public class Adresse {

H I ©
@Id
@GeneratedValue(strategy = [Link])
U EL
O
LM
private Long id;
private String rue;
private String codePostal;
r e f E
ch
©A
private String ville;
@ManyToMany(fetch = [Link] ,mappedBy="adresses")
private List<Personne> personnes = new ArrayList<Personne>();

// N'oublions pas les getter et setter


}

Relancer le projet, en cas d’erreur, supprimer et recréer la base de données.

H & H: Research and Training 34 / 55


Quelques annotations @JsonIgnoreProperties

Spring Boot

Remarque
En essayant de consulter la liste de personnes (avec leurs adresses
respectives), on a une boucle infinie (circular reference) car
H I ©
l’association est désormais bidirectionnelle.
U EL
O
f E LM
ch r e
©A

H & H: Research and Training 35 / 55


Quelques annotations @JsonIgnoreProperties

Spring Boot

Remarque
En essayant de consulter la liste de personnes (avec leurs adresses
respectives), on a une boucle infinie (circular reference) car
H I ©
l’association est désormais bidirectionnelle.
U EL
O
f E LM
ch r e
Solution
©A
Pou arrêter la boucle infinie, on peut ajouter l’annotation
@JsonIgnoreProperties dans la classe Adresse

H & H: Research and Training 35 / 55


Quelques annotations @JsonIgnoreProperties

Spring Boot
Nouveau contenu de la classe Adresse

import [Link];

//autres imports

@Entity
H I ©
EL
public class Adresse {

@Id
O U
private Long id;
f E LM
@GeneratedValue(strategy = [Link])

private String rue;


ch r e
©A
private String codePostal;
private String ville;

@JsonIgnoreProperties("adresses")
@ManyToMany(fetch = [Link],mappedBy="adresses")
private List<Personne> personnes = new ArrayList<Personne>();

// + le contenu précédent
}

H & H: Research and Training 36 / 55


Quelques annotations @JsonIgnoreProperties

Spring Boot
Nouveau contenu de la classe Personne

@Entity
public class Personne {

@Id
@GeneratedValue(strategy = [Link])
H I ©
EL
private Long num;
@Size(min = 2)

O
@NotEmpty(message = "le champ nom est obligatoire") U
private String nom;

f E LM
@NotEmpty(message = "le champ prénom est obligatoire")
@Size(min = 2)
ch r e
©A
private String prenom;

@JsonIgnoreProperties("personnes")
@ManyToMany(cascade = { [Link], [Link] },
fetch = [Link])
private List<Adresse> adresses = new ArrayList<Adresse>();

// + le contenu précédent
}

H & H: Research and Training 37 / 55


Quelques annotations @CrossOrigin

Spring Boot

Exercice 2
Créer une application Angular qui permet à un utilisateur, via des in-
terfaces graphiques) la gestion de personnes (ajout, modification, sup-
H I ©
EL
pression, consultation et recherche) en utilisant les web services définis
U
par Spring. O
f E LM
ch r e
©A

H & H: Research and Training 38 / 55


Quelques annotations @CrossOrigin

Spring Boot

Exercice 2
Créer une application Angular qui permet à un utilisateur, via des in-
terfaces graphiques) la gestion de personnes (ajout, modification, sup-
H I ©
EL
pression, consultation et recherche) en utilisant les web services définis
U
par Spring. O
f E LM
ch r e
© A
Pour régler le problème CORS

Il faut ajouter l’annotation @CrossOrigin au contrôleur.

H & H: Research and Training 38 / 55

Vous aimerez peut-être aussi