Cours Spring Boot Rest Controller
Cours Spring Boot Rest Controller
Wejdene
Achref El SAIED
Mouelhi
wejdenesaied@[Link]
[Link]@[Link]
1 Introduction
2 Quelques annotations
@ResponseBody
@RequestBody
@RestController
@JsonIgnoreProperties
@CrossOrigin
3 Commande curl
4 Gestion d’erreurs
Spring Boot
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
Spring Boot
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).
Les API REST sont basées sur le protocole HTTP (architecture client/serveur) et
utilisent le concept de ressource.
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...
Spring Boot
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
Spring Boot
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
@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
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
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);
}
}
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
@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();
}
}
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.
@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
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
@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
}
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
Envoyez
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
©
Spring Boot
ch
[Link](personne);r e
©A
return [Link](personne);
Spring Boot
ch r e
return [Link](personne);
}
©A
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
©
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
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
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
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;
Spring Boot
@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>();
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
Spring Boot
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);
}
Spring Boot
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"
]
}
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.
Spring Boot
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>();
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
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
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])
@JsonIgnoreProperties("adresses")
@ManyToMany(fetch = [Link],mappedBy="adresses")
private List<Personne> personnes = new ArrayList<Personne>();
// + le contenu précédent
}
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
}
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
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