Spring BOOT
PLAN
Introduction
Un premier projet Spring Boot
Le controleur
DevTools
La vue
Model, ModelMap et ModelAndView
Paramètres de requête et variables de chemin
Le modèle
Thymeleaf
L’internationalisation (i18n)
Les services web Rest
Spring Boot : Introduction
Spring MVC
un des premiers framework Spring
basé sur l’API Servlet de Java JEE
permettant de simplifier le développement d’applications web en respectant le patron
de conception MVC 2
Problèmes
trop de dépendance a gérer (ce qui pose souvent un problème d’incompatibilité entre
les versions)
beaucoup de configuration (JPA, Sécurité, contrôleurs, vues...)
Spring Boot
Spring Boot : Introduction
Spring Boot : encore de l’abstraction
Pour éviter les problèmes de Spring MVC, Spring Boot propose :
Les démarreurs (starter) : un démarreur est une dépendance, contenant un paquet de
dépendance, permettant de réaliser un type de projet (Web, Rest...). Ainsi, le développeur n’a
plus à gérer, lui même le problème d’incompatibilité entre les versions.
l’auto-configuration : c’est-a-dire laisser Spring Boot configurer le projet a partir de
dépendances ajoutées par le développeur.
Exemple, pour créer un projet web, il faut ajouter la dépendance Spring Boot
suivante :
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Les démarreurs Spring Boot ont la forme suivante : spring-boot-starter-*
Spring Boot : Introduction
La dépendance spring-boot-starter-web <dependency>
inclut les six dépendances suivantes : <groupId>[Link]</groupId>
<dependency> <artifactId>hibernate-validator</artifactId>
<groupId>[Link]</groupId> </dependency>
<artifactId>spring-boot-starter</artifactId> <dependency>
</dependency> <groupId>[Link]</groupId>
<dependency> <artifactId>spring-web</artifactId>
<groupId>[Link]</groupId> </dependency>
<artifactId>spring-boot-starter-json</artifactId> <dependency>
</dependency> <groupId>[Link]</groupId>
<dependency> <artifactId>spring-webmvc</artifactId>
<groupId>[Link]</groupId> </dependency>
<artifactId>spring-boot-starter-
tomcat</artifactId>
</dependency>
Spring Boot : Introduction
La dépendance spring-boot-starter-web permet donc de créer un projet web
contenant :
un serveur Apache Tomcat
Spring Framework et Spring MVC
les validateurs d’Hibernate
jackson pour les donnees sous format JSON ´
...
Spring Boot : les fondamentaux
Installer le plugin "aka Spring Tool Suite" à partir du market place d’eclipse
Création de projet Spring Boot :
Aller dans File > New > Other
Chercher Spring, dans Spring Boot sélectionner Spring Starter Project et cliquer sur
Next >
Saisir :
FirstSpringBoot dans Name,
[Link] dans Group,
FirstSpringBoot dans Artifact
[Link] dans Package
Cliquer sur Next >
Chercher et cocher les cases correspondantes aux Web puis cliquer sur Next >
Valider en cliquant sur Finish
Spring Boot : les fondamentaux
Pourquoi a-t-on coche la case Web a la création du projet ?
pour ajouter la dépendance spring-boot-starter-web
Contenu de la section dependencies de [Link]
<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Spring Boot : les fondamentaux
Pour la compatibilité d’ Apache Tomcat avec les JSP, on ajoute la dependance
suivante :
<!-- [Link] -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>9.0.12</version>
</dependency>
La version d’Apache Tomcat doit être la même que celles qui existent dans
Maven Dependencies
Spring Boot : les fondamentaux
Remarques
1. Le package contenant le point d’entrée de notre application (la classe contenant le
public static void main) est [Link]
2. Tous les autres packages dao, model... doivent être dans le package demo.
3. Le point de demarrage de l’application :
package [Link];
import [Link];
import [Link];
@SpringBootApplication
public class FirstSpringBootApplication {
public static void main(String[] args) {
[Link]([Link], args);
}
}
Spring Boot : les fondamentaux
Explication
SpringApplication : la classe de démarrage d’une application Spring et qui va créer
une instance de la classe ApplicationContext
ApplicationContext : l’interface centrale d’une application Spring permettant de
fournir des informations de configuration a l’application. `
@SpringBootApplication : contient les 3 annotations suivantes
@Configuration : fait partie du noyau de Spring Framework et indique que la classe annotée
peut contenir des méthodes annotées par @Bean. Ainsi, Spring Container peut traiter la classe
et générer des beans qui seront utilisés par l’application.
@EnableAutoConfiguration : permet, au démarrage de Spring, de générer automatiquement
les configurations nécessaires en fonction des dépendances ajoutées.
@ComponentScan : demande de scanner ce package contenant des Beans de configuration
Spring Boot : les fondamentaux
Pour exécuter :
Faire un clic droit sur FirstSpringBoot dans Package Explorer
Aller dans Run As et cliquer sur Spring Boot App
La console nous indique
Tomcat started on port(s): 8080 (http) with context path ’ ’
Allons donc à [Link]
Résultat : message d’erreur
On a créé un projet web, mais on n’a aucune page HTML, JSP ou autre
Spring Boot, comme Spring MVC, implémente le patron de conception MVC, donc il
nous faut au moins un contrôleur et une vue.
Avantages de Spring Boot
Faciliter le développement d’applications complexes
Faciliter l’injection des dépendances
Faciliter la gestion des dépendances avec Maven
Réduire les fichiers de configuration et supporter l’auto-configuration
Fournir un conteneur léger embarqué (Tomcat)
Spring Boot : Le contrôleur
Le contrôleur est :
un des composants du modèle MVC
une classe Java annotée par Controller ou RestController
Il reçoit une requête du contrôleur frontal et communique avec le modèle pour
préparer et retourner une réponse à la vue
Création du contrôleur:
Faire clic droit sur le projet
Aller dans new > class
Choisir le package [Link]
Saisir HomeController comme nom de classe
Ensuite valider
Spring Boot : Le contrôleur
Remplaçons le contenu du HomeController par le code suivant :
package [Link];
import [Link] ;
import [Link];
import [Link];
@Controller
public class HomeController {
@RequestMapping(value="/hello", method = [Link])
public void sayHello() {
[Link]("Hello World!");
}
}
La valeur de l’annotation @RequestMapping indique la route (/hello ici) et la méthode permet
d’indiquer la méthode HTTP (get ici, c’est la méthode par défaut). On peut aussi utiliser le raccourci
@GetMapping(value="/hello")
Pour tester tout cela Démarrer le serveur Apache Tomcat Aller sur l’url [Link] et
vérifier qu’un "Hello World!" a bien été affiché dans la console (d’Eclipse)
DevTools
Les DevTools est un outil de développement, fonctionnant en mode
développement (non production), qui permet d’automatiser le redémarrage et
le rechargement de votre application lorsque les fichiers sources sont
recompilés ou modifiés.
Configuration
Pour installer DevTools il faut simplement ajouter la dépendance au projet
SpringBoot.
Dépendance Maven à ajouter :
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
Avant l’utilisation de DevTools, il faut vider le cache du projet le mettre a
jour
Spring Boot : La vue
Les vues sous Spring
Permettent d’afficher des données
Communiquent avec le contrôleur pour récupérer ces données
Doivent être créées dans le répertoire views dans WEB-INF
Peuvent être créées avec un simple code JSP, JSTL ou en utilisant un moteur de
template comme Thymeleaf ...
Par défaut Spring cherche les vues dans un répertoire webapp situe dans
"src/main". Le répertoire n’existe pas, il faut le créer.
Créons une première vue que nous appelons [Link] dans webapp
[Link]
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "[Link]
[Link]">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JSP - First JSP called from controller</title>
</head>
<body>
First JSP called from controller
</body>
</html>
Spring Boot : La vue
Appelons [Link] a partir du contrôleur
package [Link];
import [Link];
import [Link];
@Controller
public class HomeController {
@GetMapping(value="/hello")
public String sayHello() {
return "[Link]";
}
}
Dans le return, on précise le nom de la vue à afficher (ici c’est [Link])
Spring Boot : La vue
Remarques :
On peut préciser un autre répertoire pour les vues (il faut qu’il soit dans
webapp)
Pour éviter de préciser chaque fois l’extension de la vue, on peut l’indiquer
dans [Link] situé dans src/main/resources
Nouveau contenu d’[Link]
[Link]=/views/
[Link]=.jsp
Toutes les propriétés possibles de [Link] sont ici :
[Link]
html/[Link]
Spring Boot : La vue
Nouveau contenu du controleur
package [Link];
import [Link];
import [Link];
@Controller
public class HomeController {
@GetMapping(value="/hello")
public String sayHello() {
return "hello";
}
}
N’oublions pas de déplacer [Link] dans views qu’il faut le créer dans webapp
Spring Boot : La vue
Deux questions se posent :
Comment passer des données d’une vue à un contrôleur et d’un contrôleur à une vue
?
Une vue peut-elle appeler un contrôleur ?
Spring Boot : La vue
Comment le contrôleur passe des données à la vue ?
package [Link];
import [Link];
import [Link];
import [Link];
@Controller
public class HomeController {
@GetMapping(value="/hello")
public String sayHello(Model model) {
[Link]("nom", "Spring");
return "hello";
}
}
Dans la déclaration de la méthode, on injecte l’interface Model qui nous permettra
d’envoyer des attributs à la vue
[Link]
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JSP - First JSP called from controller</title>
</head>
<body>
First JSP called from controller
Je m’appelle ${ nom }
</body>
</html>
Exactement comme dans la plateforme JEE
Spring Boot : La vue
Comment le contrôleur passe des données à la vue ?
package [Link];
import [Link];
import [Link];
import [Link];
@Controller
public class HomeController {
@GetMapping(value="/hello")
public String sayHello(ModelAndView mv) {
[Link]("hello");
[Link]("nom", "Spring");
return mv;
}
}
Spring Boot : La vue
Model vs ModelMap vs ModelAndView
Model : est une interface permettant d’ajouter des attributs et de les passer a la vue
ModelMap : est une classe implémentant l’interface Map et permettant d’ajouter des
attributs sous forme de key – value et de les passer à la vue. On peut donc chercher un
élément selon la valeur de la clé ou de la valeur
ModelAndView : est un conteneur à la fois d’un ModelMap pour les attributs et d’un
View Object. Le contrôleur pourra ainsi retourner une seule valeur
Exemple Hello_Word avec sts
Etape 1 :
Télécharger et lance STS (Spring Tool Suite)
Créer un projet Spring Starter
Exemple Hello_Word avec sts
Etape 1 :
Télécharger et lance STS (Spring Tool Suite)
Créer un projet Spring
Exemple Hello_Word avec sts
Etape 2 : Ajouter les propriétés db de l’application dans [Link]:
[Link]=jdbc:mysql://localhost:3306/spring?useUnicode=true&useJDBCC
ompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
[Link]=root
[Link]=pwd
[Link]-class-name=[Link]
[Link]-platform = [Link].MySQL5Dialect
[Link]-ddl=true
[Link]-auto = update
Exemple Hello_Word avec sts
Etape 2 : Ajouter les propriétés db de l’application dans [Link]:
Exemple Hello_Word avec sts
Etape 3 : Tester l’exécution
de l’application
Exemple Hello_Word avec sts
Etape 4 : Ajouter un controller dans le sous package controller
Exemple Hello_Word avec sts
Etape 4 : Ajouter un controller dans le sous package controller
Exemple Hello_Word avec sts
Etape 5 : Ajouter
une view html
Exemple Hello_Word avec sts
Etape 5 : Ajouter une propriété dans [Link]
[Link]: Ipsas
Etape 6 : Ajouter une feuille de style css
src/main/resources/static/css/[Link]
Exemple Hello_Word avec sts
Etape 7 : Tester votre application
Utilisation de Spring Data au niveau de la
couche DAO
Une autre façon pour accéder aux données
Rappel de notre architecture
Back-end
Couche
Couche de Couche d’accès
d’exposition de
services métier aux données
services
DAO
Service
Spring
RESTful data
Controller
JPA
Entities
Hibernate
39
Principe Spring Data (1/3)
Spring Data offre plusieurs interfaces dont les interfaces des Repository
peuvent hériter, afin de disposer automatiquement lors de leur génération des
implémentations fonctionnelles :
CrudRepository<T,ID>
PagingAndSortingRepository<T, ID>
JpaRepository<T,ID>
40
Principe Spring Data (2/3)
CrudRepository est définie par des templates Generics, prototypant
dans sa signature de classe :
La définition d’un Type associé à une classe de modèle (elle même étant par
ailleurs une Entity JPA, une classe déclarant @Entity).
Et un type , permettant de définir le type de la clé primaire associée à l’entité,
soit un Number (Integer, Long), soit pour une Clé Composée au travers d’une
classe dédiée, dans les deux cas, le type est forcément Serializable (contrainte
imposée).
CrudRepository fournit une implémentation standard et par défaut
pour les méthodes usuelles suivantes : save, findOne, findAll, count,
delete, exists, ... Permettant ainsi de disposer de méthodes principales
éprouvées dans le cadre des service DAO (inutile de les ré-
implémenter)
41
Principe Spring Data (3/3)
PagingAndSortingRepository Hérite de l’interface CrudRepository, en
suivant la même définition de templating Generics,
fournit des méthodes supplémentaires pour le tri findAll(Sort), et la pagination
findAll(Pageable).
JpaRepository Hérite de l’interface PagingAndSortingRepository, en lui
ajoutant quelques méthodes spécifiques
Cette interface, la plus avancée, regroupe l’ensemble de toutes les
fonctionnalités proposées par Spring Data JPA.
42
Spring Data via l’exemple (1/2)
Pour utiliser Spring Data, il faut declarer spring-boot-starter-data-jpa comme
dépendance dans le [Link]
Créer pour chaque entité persistante, une interface Héritant de l’interface
JpaRepository
public interface MedecinRepository extends JpaRepository<Medecin, Long>
{
43
Spring Data via l’exemple (2/2)
On peut spécifier ses propres Query JPQL directement dans le corps de
l’interface, en redéfinissant l’implémentation standard par une @nnotation
@Query(« select... » ).
public interface MedecinRepository extends JpaRepository<Medecin, Long>
{
@Query("select m from Medecin m where [Link] like :x")
public List<Medecin> chercher(@Param("x")String mc);
}
44
Rappel de notre architecture
Back-end
Couche
Couche de Couche d’accès
d’exposition de
services métier aux données
services
DAO
Service
Spring
RESTful data
Controller
JPA
Entities
Hibernate
45
Implémentation de la couche métier (1/4)
Définir des interfaces contenant la spécification de la partie métier d’une
application
Définir des classes implémentant ces interfaces et utilisant l’annotation
@Service
Cette annotation est une forme spécialisée de l'annotation @Component
destinée à être utilisée dans la couche de service.
Exemple:
Définir l’interface IPatientService ainsi que son implémentation
Définir l’interface IMedecinService ainsi que son implémentation
Définir l’interface IConsultationService ainsi que son implémentation
46
Implémentation de la couche métier (2/4)
public interface IPatientService {
//Crud Methods
public Patient addPatient(Patient p) ;
public void deletePatient(Long id) ;
public Patient updatePatient(Patient p) ;
public Patient findPatient(Long id) ;
public List<Patient> findAll();
//Other methods
public MedecinGeneraliste findMG(Long patientID);
public Collection<MedecinSpecialiste> findMS(Long patientID);
}
@Service
@Transactional
public class PatientService implements IPatientService {
@Autowired
PatientRepository patDao;
47
Implémentation de la couche métier (3/4)
@Service
@Transactional
public class PatientService implements IPatientService {
@Autowired
PatientRepository patDao;
public Patient addPatient(Patient p) {
return [Link](p);
}
public void deletePatient(Long id) {
Optional<Patient> p= [Link](id);
if (p!=null)
[Link]([Link]());
}
public Patient updatePatient(Patient p) {
return [Link](p);
}
public Patient findPatient(Long id) {
return [Link](id);
}
48
Implémentation de la couche métier (4/4)
public List<Patient> findAll() {
return [Link]();
}
public MedecinGeneraliste findMG(Long patientID) {
Optional<Patient> p= [Link](patientID);
if (p!=null)
return [Link]().getGeneraliste();
return null;
}
public Collection<MedecinSpecialiste> findMS(Long patientID) {
Optional<Patient> p= [Link](patientID);
if (p!=null)
return [Link]().getSpecialistes();
return null;
}
}
49
Rappel de notre architecture
Back-end
Couche
Couche de Couche d’accès
d’exposition de
services métier aux données
services
DAO
Service
Spring
RESTful data
Controller
JPA
Entities
Hibernate
50
Implémentation de la couche métier en utilisant des
services Web RESTful
Un service Web RESTful est une classe Java décorée par l’annotation
@RestController
@RestController est simplement la combinaison des deux annotations:
@Controller de Spring qui permet de désigner une classe comme contrôleur, ayant
la capacité de traiter les requêtes de type GET, POST, etc.
Cette annotation peut être utilisée pour identifier les contrôleurs pour Spring MVC
@ResponseBody sera ajouté au niveau des méthodes qui devront répondre
directement sans passer par une vue.
51
Implémentation de la couche métier en utilisant des
services Web RESTful
Nous allons créer des web services RESTful exposant des API REST gérant
les opération CRUD des entités patient, médecin et consultation
[Link]
[Link]
[Link]
Chaque contrôleur s'occupera de répondre aux requêtes CRUD et de faire
les opérations nécessaires.
52
Implémentation de la couche métier en utilisant des
services Web RESTful
Nous cherchons à appeler par exemple le micro-service gérant les patients
sur les URLs suivantes :
Requête GET à /Patients : affiche la liste de tous les patients;
Requête GET à /Patients/{id} : affiche un patient par son Id ;
Requête PUT à /Patients/{id} : met à jour un patient par son Id ;
Requête POST à /Patients : ajoute un patient;
Requête DELETE à /Patients/{id} : supprime un patient par son Id.
53
Implémentation de la couche métier en utilisant des
services Web RESTful
@RestController
public class PatientController {
@Autowired
PatientRepository pRep;
@RequestMapping(value="/patients ", method=[Link])
public List<Patient> findPatients ()
{
return [Link]();
}
}
@RequestMapping permet de faire le lien entre l'URI "/patients", invoquée via
GET, et la méthode findPatients()
Cette annotation est utilisée au niveau de la classe et de la méthode.
On peut utiliser à la place @GetMapping
54
Implémentation de la couche métier en utilisant des
services Web RESTful
@RequestMapping(value="/patients/{id}", method=[Link])
public Patient findOnePatient(@PathVariable Long id)
{
return [Link](id).get();
}
@PathVariable Cette annotation est utilisée pour annoter les arguments de la
méthode du gestionnaire de requêtes.
Cette méthode doit répondre uniquement aux requêtes avec une URI de
type /Patients/2 par exemple.
55
Implémentation de la couche métier en utilisant des
services Web RESTful
Réponse JSON obtenue
56
Implémentation de la couche métier en utilisant des
services Web RESTful
@RequestMapping(value="/patients/MG/{id}", method=[Link])
public Medecin findMG(@PathVariable Long id)
{ Chercher le
Patient p=[Link](id).get(); médecin
return [Link](); généraliste
}
@PostMapping(value="/Patients")
public Patient savePatient(@RequestBody Patient p)
{
return [Link](p); Ajouter
}
@RequestBody Cette annotation demande à Spring que le JSON contenu dans
le corps de la requête sera transformé en Objet
57
Implémentation de la couche métier en utilisant des
services Web RESTful
@RequestMapping(value="/patients/{id}", method=[Link])
public void deletePatient(@PathVariable Long id)
{
[Link](id);
} Supprimer
@RequestMapping(value="/patients/{id}", method=[Link])
public Patient updateContact(@PathVariable(name="id") Long id,
@RequestBody Patient p)
{
[Link](id);
return [Link](p);
} Modifier
58