SlideShare une entreprise Scribd logo
1  sur  23
Télécharger pour lire hors ligne
Java EE Spring – Introduction
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Java EE Spring
JDK
Java EE
Introduction 2
Définition
Ensemble de spécifications, de concepts et d'API
pour le développement en Java
d'applications d'entreprise
J2EE Java EE
1.0 1.1 1.2 1.3 1.4 5 6 7
Sun Microsystems Oracle
•
1
9
9
6
•
1
9
9
7
•
1
9
9
9
•
2
0
0
1
•
2
0
0
3
•
2
0
0
6
•
2
0
0
9
•
2
0
1
3
•
2
0
1
7
Historique
Eclipse Foundation
•
2
0
1
9
•
2
0
2
0
•
2
0
2
3
Jakarta EE
8 9 10
Notions générales
Introduction 3
Client-serveur
Notions générales
Introduction 4
Architecture client-serveur 3 tiers – n tiers (couches)
Modèle d’organisation des applications
Traitement
Données
Présentation
• Les tiers peuvent être distribués sur un réseau et accessibles en mode client/serveur
Notions générales
Introduction 5 Lionel Seinturier
Serveur d'applications
Un serveur qui héberge des applications accessibles via le réseau
Le plus utilisé pour Jakarta EE
Apache Tomcat
• 1ère version : 1999
• en octobre mars 2023 : version 10.1.7
• open source
• code développé en Java
Spring
Introduction 6
Définition
“Spring is an application framework for the Java platform
”
Outils et de règles facilitant le développement d'applications
Principes généraux
Introduction 7
Principes généraux mis en oeuvre dans Spring
• Approche MVC
• Injection de dépendances
Les applications web (mais pas uniquement)
Un écosystème vaste de plus de 50 sous-projets
MVC
Introduction 8
Définition
Un schéma de structuration des applications en trois parties
• Modèle données à présenter à l'utilisateur
• Vue affichage des données, interactions avec l'utilisateur
• Contrôleur gestion des actions de l'utilisateur
https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/
MVC et 3-tiers
Introduction 9 Lionel Seinturier
Traitement
Données
Services
Contrôleur
Présentation
Modèle Vue
Architecture type d'une application Spring
• contrôleur
• accède à des services
• traitements
• accès données SGBD
• construit un modèle
• crée une vue avec ce modèle
• souvent associée au pattern
DTO Data Transfert Object
Injection de dépendances
Introduction 10
Principe
Eviter de coder en dur les dépendances entre
• un service
• le code qui utilise ce service
Séparation
• interface de service
• implémentation du service
• utilisation du service
Injection de dépendances
Introduction 11
Sans injection de dépendances
interface GreeterItf {
String sayHello();
}
class GreeterImpl implements GreeterItf {
public String sayHello() {
return "Hello world!";
} }
class Client {
GreeterItf greeter = new GreeterImpl();
void run() {
var str = greeter.sayHello();
System.out.println(str);
} }
on code en dur la
dépendance entre un
service et son
utilisation
+ pb si plusieurs utilisations
Injection de dépendances
Introduction 12
Injection de dépendances
• découpler le service de son (ses) utilisation
• ce n'est plus le développeur qui créé le lien
• le framework (Spring) le fait
• utilisation d'annotations pour
• le service
• @Service
• le code qui utilise le service
• @Autowired
Injection de dépendances
Introduction 13
Sans injection de dépendances
interface GreeterItf {
String sayHello();
}
class GreeterImpl implements GreeterItf {
public String sayHello() {
return "Hello world!";
} }
class Client {
GreeterItf greeter = new GreeterImpl();
void run() {
var str = greeter.sayHello();
System.out.println(str);
} }
Injection de dépendances
Introduction 14
Avec injection de dépendances
interface GreeterItf {
String sayHello();
}
@Service
class GreeterImpl implements GreeterItf {
public String sayHello() {
return "Hello world!";
} }
class Client {
@Autowired
GreeterItf greeter;
void run() {
var str = greeter.sayHello();
System.out.println(str);
} }
Spring positionne automatiquement
la valeur de greeter avec la référence de
l'objet GreeterImpl
on dit que Spring "injecte" la référence
Java EE Spring – HTTP > servlet > contrôleur
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Java EE Spring
HTTP
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
HTTP
HTTP 17 Lionel Seinturier
HTTP
Hypertext Transfer Protocol (HTTP)
• protocole dit de niveau applicatif
• utilise TCP
ð garantie d'un transport fiable (sans erreur)
• pas de notion de connexion HTTP
• tous les commandes HTTP sont émises en mode texte (ASCII)
ð protocole simple, facilement implantable
• standardisé par une RFC
• existe depuis 1989 (v0.9)
• version 2 en 2015
• version 3 en 2022 (transport QUIC à la place de HTTP)
• cohabitation versions actuelles HTTP/2 et HTTP/3
HTTP 18 Lionel Seinturier
HTTP
2 messages (commandes) principaux
GET demande d'un document
POST envoi des données saisies dans un formulaire
Autres messages
• PUT dépôt (upload) d'un fichier sur le serveur
• DELETE suppression d'un fichier
• et aussi HEAD, OPTIONS, TRACE, PATCH, CONNECT
HTTP 19 Lionel Seinturier
HTTP
Requête
commande URL version_HTTP_comprise_par_le_client
en-tête_1_HTTP: valeur
....
en-tête_n_HTTP: valeur
informations envoyées par le client (par ex. texte saisi dans un formulaire HTML)
GET /index.html HTTP/2.0
Accept-language: fr
User-Agent: Mozilla/42.0
If-modified-since: Tue, 23 Jul 2020 10:24:05
POST /index.php HTTP/2.0
Accept-language: fr
nom=Seinturier&prenom=Lionel
HTTP 20 Lionel Seinturier
HTTP
Réponse
version_HTTP_du_serveur code_retour commentaire
en-tête_1_HTTP: valeur
....
en-tête_n_HTTP: valeur
document texte (HTML, …) ou binaire (GIF, JPG, …)
HTTP/2.0 200 OK
Content-Length: 9872
Content-Type: text/html
<HTML>
....
</HTML>
HTTP 21 Lionel Seinturier
HTTP
Réponse
code retour : renseigne sur le succès (200) ou l'échec (4xx) de la requête
• 200 : ok
• 404 : document inconnu
• 401 : authentification nécessaire
• 500 : erreur du serveur HTTP dans le traitement requête (servlet, PHP, …)
• 503 : serveur temporairement surchargé
• …
en-têtes HTTP : informations transmises par le serveur sur le document envoyé
• Content-Length : taille du document
• Last-Modified : date de dernière modification du document
• Server : nom du logiciel serveur
• Expire : date d'expiration du document
• Content-Type : type (MIME) du document
• … nombreux autres en-têtes possibles
REST
Java EE 22 Lionel Seinturier
Principe
• à la base HTTP requête-réponse pour le transfert de documents (HTML, etc.)
• REST
• HTTP comme moyen d'invoquer des services à distance
• on parle de ressources distantes
• chaque ressource = une URL
• ex. http://foo.com/myapp/users/Bob
• invocation d'un service
• une requête HTTP (GET, POST, PUT, DELETE, etc.)
• la réponse à une invocation de service
• le retour de la requête HTTP (souvent JSON, mais aussi …)
REST
Java EE 23 Lionel Seinturier
Pattern CRUD
• il n'y a pas de signification prédéfinie pour les requêtes GET, POST, PUT, DELETE, etc.
• laissée au choix du développeur
• souvent CRUD
• POST (C) create création
• GET (R) read lecture
• PUT (U) update mise à jour
• DELETE (D) delete suppression
Servlet
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Servlet
Page web dynamique côté serveur
Servlet 25
Servlet
Programme Java s'exécutant côté serveur Web
• permet de créer des pages web dynamiques
• exécuté par un "moteur" de servlet
• désigné par une URL ex. : http://www.fun.fr/myapp/prog
Ma première servlet
Servlet 26
Programmation
Ecriture d’une classe Java
• étend la classe HttpServlet
• redéfinit la méthode doGet
Ma première servlet
Servlet 27
Programmation
@WebServlet(urlPatterns={"/maservlet"})
public class HelloServlet extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
out.println( "<html><body>" );
out.println( "<h1>Bonjour</h1>" );
out.println( "</body></html>" );
}
}
Ma première servlet
Servlet 28
Résultat
Chargement dans un navigateur de l’URL http://.../maservlet
Instanciation et exécution
Servlet 29
Servlet
Chaque servlet est un objet Java
singleton
• 1 seule instance
• variables d’instance conservées
multi-threadé
• exécution concurrente, 1 thread par requête
• Conséquences :
ü protéger les variables
ü préférer les servlets stateless
Formulaires
Servlet 30
Récupération des données d'un formulaire
Exemple de formulaire
<HTML> <BODY>
<FORM ACTION="salutations"
METHOD=POST>
Nom <INPUT NAME="nom"> <P>
Prénom <INPUT NAME="prenom"> <P>
<INPUT TYPE=SUBMIT VALUE="Envoi">
</FORM>
</BODY> </HTML>
Formulaires
Servlet 31
Récupération des données d'un formulaire
String getParameter(String)
ð retourne le texte saisi
ð ou null si le nom de paramètre n'existe pas
Formulaires
Servlet 32
@WebServlet(urlPatterns={"/salutations"})
public class SalutationsServlet extends HttpServlet {
public void doPost(
HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
String nom = request.getParameter( "nom" );
String prenom = request.getParameter( "prenom" );
out.println( "<html><body>" );
out.println( "<h1>Exemple de résultat</h1>" );
out.println( "Bonjour " + prenom + " " + nom );
out.println( "</body></html>" );
}
}
Récupération des données d'un formulaire
Formulaires
Servlet 33
Récupération des données d'un formulaire
clic
HTTP
Servlet 34
Servlet
public class CompteurServlet extends HttpServlet {
public void doGet( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException {
// ... le traitement lorsque la servlet est invoquée avec GET
}
public void doPost( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException {
// ... le traitement lorsque la servlet est invoquée avec POST
}
// ... éventuellement autres méthodes doXXX
}
Cycle de vie
Servlet 35
Servlet
une servlet = une classe Java
1. Instanciation (constructeur)
2. Exécution de la méthode init
3. Exécution multi-threadée des requêtes
4. Exécution de la méthode destroy
Possibilité de surcharger les méthodes init et destroy
void init(ServletConfig conf) throws ServletException { ... }
void destroy() { ... }
Session
Servlet 36
Définition
• suivre l'activité d'un utilisateur
• isoler les activités des utilisateurs simultanés
• chaque utilisateur a sa session qui lui est propre
• existe dans d'autres langages que Java (ex. PHP)
• débute à l’initiative du serveur
• se termine au bout d'un délai d'inactivité
• gérée à l'aide de cookies
• fonctionne comme une Map
void setAttribute( String name, Object value )
Object getAttribute( String name )
void setMaxIntervalTime( int seconds )
Session
Servlet 37
Programmation
@WebServlet(urlPatterns={"/maservlet"})
public class HelloServlet extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
HttpSession session = request.getSession();
Panier panier = (Panier) session.getAttribute("monpanier");
if( panier == null ) {
panier = new Panier();
session.setAttribute("monpanier",panier);
}
}
}
En résumé
Servlet
Servlet
• programme Java
• s'exécutant côté serveur Web
• que l'on peut invoquer à l'aide d'une URL
• générant du code HTML
• bien adapté à l'écriture de traitement
• contenant majoritairement du code Java
• et quelques parties de code HTML
Contrôleur
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Contrôleur
Contrôleur
Contrôleur 40
Définition
Une classe/objet
• qui reçoit des requêtes
• et qui fournit une réponse destinée à être affichée par une vue
• nombreuses solutions pour les vues (HTML, JSON, etc.)
Architecture
générale
Spring
Contrôleur
Contrôleur 41
Un premier exemple
@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String sayHello() {
return "<h1>Hello world!</h1>";
}
}
Contrôleur
Contrôleur 42
Un contrôleur retourne
• une chaîne de caractères contenant du HTML
• mais surtout le plus souvent
• (le nom d') une vue
• des données formattées en JSON
• etc.
Vue
Vue 43
Définition
• Partie présentation des applications Spring
• 2 solutions
• des vues gérées par des frameworks front
• Angular, React, Vue.js, etc.
• (hors de l'objectif de ce cours)
• des vues préparées côté serveur
• HTML, Thymeleaf, JSP, JSTL, etc.
CONTROLLEUR VUE
requête modèle
Vue
Vue 44
Contrôleur
• retourner le nom de la vue
• la vue peut être une "simple" page HTML
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "hello";
}
}
Fichier hello.html
<html>
<body>
<h1>Hello world!</h1>
</body>
</html>
Modèle
Vue 45 Lionel Seinturier
Modèle
• les données à transmettre à la vue
• utilisation de l'API org.springframework.ui.Model
• fonctionne comme une Map
Model addAttribute( String name, Object value )
Object getAttribute( String name )
boolean containsAttribute( String name )
Modèle
Vue 46
Modèle
• paramètre dans les arguments de la méthode
• sa valeur est injectée par Spring
• le modèle est transmis à la vue
@Controller
public class HelloController {
@GetMapping("/hello2")
public String sayHello( Model model ) {
model.addAttribute("nom","Doe");
model.addAttribute("prenom","John");
return "home";
}
}
Vue Thymeleaf
Java EE 47 Lionel Seinturier
Vue Thymeleaf
• un moteur de template HTML pour des vues construites côté serveur
• accès aux variables du modèle
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Hello
<span th:text="${prenom}"/>
<span th:text="${nom}"/>
</h1>
</body>
</html>
Contrôleur
Java EE 48 Lionel Seinturier
Les routes
• mécanisme pour aiguiller les requêtes vers les contrôleurs/méthodes
• cf. annotation @GetMapping
• autre annotation @RequestMapping
@Controller
@RequestMapping("/myapp")
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "hello";
}
}
Accès
http://localhost:8080/myapp/hello
Contrôleur
Java EE 49 Lionel Seinturier
Les variables dans les routes
• mécanisme pour paramétrer les routes
• { … } dans l'URL
• accès à la valeur via une variable associée à l'annotation @PathVariable
@Controller
@RequestMapping("/ecommerce")
public class ArticleController {
@GetMapping("/article/{id}")
public String getArticle( @PathVariable String id ) { ... }
}
Accès
http://localhost:8080/ecommerce/article/smartphone
http://localhost:8080/ecommerce/article/tv
http://localhost:8080/ecommerce/article/170482365
...
Contrôleur
Java EE 50 Lionel Seinturier
Les variables dans les routes
• plusieurs variables peuvent être utilisées dans les routes
@Controller
@RequestMapping("/ecommerce")
public class CommandeController {
@GetMapping("/commande/{annee}/{mois}")
public List<Commande> findCommandeByAnneeAndMois(
@PathVariable String annee,
@PathVariable String mois )
{ ... }
}
Accès
http://localhost:8080/ecommerce/commande/2024/janvier
http://localhost:8080/ecommerce/commande/2020/mars
...
Contrôleur
Java EE 51 Lionel Seinturier
Différentes requêtes HTTP dans un contrôleur
• un même contrôleur peut gérer différentes requêtes HTTP (GET, POST, etc.)
• annotation @PostMapping, etc.
@Controller
@RequestMapping("/user")
public class UserController {
@PostMapping("/create")
public String create(
@RequestParameter String nom,
@RequestParameter String prenom )
{ ... }
@GetMapping("/read/{id}")
public String read( ... ) { ... }
}
<html> <body>
<form action="/user/create"
method="POST">
Nom <input name="nom">
Prénom <input name="prenom">
<input type="SUBMIT">
</form></body> </html>
Contrôleur REST
Contrôleur 52
Pattern REST + retours JSON
@RestController
public class ClientRestController {
@PostMapping(value="/client")
public Client create( @RequestBody Client client ) {
return service.create(client); }
@GetMapping("/client/{id}")
public Client read( @PathVariable long id ) {
return service.read(id); }
@PutMapping("/client/{id}")
public Client update( @PathVariable long id, @RequestBody Client client ) {
return service.update(id,client); }
@DeleteMapping("/client/{id}")
public void delete( @PathVariable long id ) {
service.delete(id); } }
Contrôleur
Contrôleur 53
Accès à la session
• paramètre HttpSession dans les arguments de la méthode
• sa valeur est injectée par Spring
@Controller
@RequestMapping("ecommerce")
public class MagasinController {
@GetMapping("/ajouter/{id}")
public String ajouter( HttpSession session, @PathVariable String id ) {
Panier monPannier = (Panier) session.getAttribute("panier");
if( monPannier == null ) {
monPannier = new Pannier();
session.setAttribute("panier", monPannier);
}
monPannier.ajouter(id);
} }
En résumé
Contrôleur 54
Contrôleur
• une classe annotée
• qui définit des méthodes
• pour recevoir des requêtes HTTP
• les traiter
• renvoyer un contenu
• HTML
• JSON
• etc.
Java EE Spring – Vues avec Thymeleaf
Lionel Seinturier
Université de Lille
Java EE Spring
Thymeleaf
Java EE 56 Lionel Seinturier
Thymeleaf
• un moteur de template HTML pour des vues construites côté serveur
• des parties fixes (HTML pur)
• des parties variables
• un namespace (ici associé au prefix th)
• avec des variables ${ ... }
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Hello
<span th:text="${prenom}"/>
<span th:text="${nom}"/>
</h1>
</body>
</html>
Thymeleaf
Java EE 57 Lionel Seinturier
Variables
• tous les types sont possibles (String, List, objets Java, etc.)
• pour les chaînes de caractères
• concaténation avec +
• chaînes de caractètres constantes '…….'
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="'Hello '+${prenom}+' '+${nom}" />
</body>
</html>
Thymeleaf
Java EE 58 Lionel Seinturier
Variables
• pour les objets Java accès au variable ${objet.champ}
public class Personne {
private String nom;
private int age;
// + constructeurs, getters et setters pour nom et age
}
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="${personne.nom}+' a '+${personne.age}+' ans'" />
</body>
</html>
• variable prédéfinie session
<h1 th:text="${session.email}" />
Thymeleaf
Vue 59
Itération
• balise each pour itérer sur les éléments d'une collection
• ici collection ${auteurs}
<html xmlns:th="https://www.thymeleaf.org" >
<body>
<h1>Liste des auteurs</h1>
<table border="1">
<tr><th>Id</th><th>Nom</th><th>Prénom</th></tr>
<tr th:each="auteur : ${auteurs}">
<td th:text="${auteur.id}" />
<td th:text="${auteur.nom}" />
<td th:text="${auteur.prenom}" />
</tr>
</table>
</body>
</html>
Thymeleaf
Java EE 60 Lionel Seinturier
Itération
• transmission de la collection dans le modèle
@Controller
@RequestMapping("/bib")
public class BibliothequeController {
@GetMapping("/home")
public String home( Model model ) {
List<Auteur> auteurs = new ArrayList<>();
auteurs.add( new Auteur("Hugo","Victor") );
auteurs.add( new Auteur("Zola","Emile") );
model.addAttribute("auteurs",auteurs);
return "home";
}
}
Thymeleaf
Vue 61 Lionel Seinturier
Itération
Résultat
Thymeleaf
Vue 62 Lionel Seinturier
Conditionnel
• balise if : action si la condition est vraie
• balise unless : idem faux
<td>
<span th:if="${personne.age >= 18}">Majeur</span>
<span th:unless="${personne.age >= 18}">Mineur</span>
</td>
• balises switch et case pour tester différents cas
Thymeleaf
Java EE 63 Lionel Seinturier
Thymeleaf
• un moteur de template HTML pour des vues construites côté serveur
• le moteur de template "officiel" de Spring
• permet de manipuler des variables
• itérations, conditionnels
• plus d'informations https://www.thymeleaf.org
Java Persistence API
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
JPA
Java Persistence API
JPA 65
Définition
Java Persistence API
interface de programmation pour la gestion de données relationnelles
appelé Jakarta Persistance depuis la version 3.0 en 2020
• Manipulation de données et de leurs relations
• 3 parties
• les annotations
• l'API pour manipuler les données
• JPQL
JPA et ORM
JPA 66
Définition
Object Relation Mapping
Technique de programmation
Schéma de données Objets
ORM
• opérations SQL courantes
• vision homogène
• haut niveau
• transfert automatique des données
ORM
Vocabulaire JPA
JPA 67
Définitions
Entité
• un ensemble de données d'un même type (eg. Personne)
Persistance / persister
• action de sauvegarder des données dans une base de données (SGBD)
JPA et SGBD
JPA 68
Principes de mise en correspondance
• une classe Java une table SQL
• une propriété d'une classe une colonne dans une table SQL
• une référence entre classes une relation entre tables SQL
• un objet Java un enregistrement dans une table SQL
Remarques
• nb objets ≠ nb enregistrements
• les données peuvent être chargées de façon dite paresseuse (lazy)
Annotation @Entity
JPA 69
Entité
• à déclarer sur les classes dont les données doivent être prises en charge par JPA
@Entity
public class Personne {
private String nom;
private int age;
public Personne( String nom, int age ) {
this.nom = nom;
this.age = age;
}
public String getNom() { return nom; }
public void setNom( String nom ) { this.nom = nom; }
public int getAge() { return age; }
public void setAge( int age ) { this.age = age; }
}
Annotations @Id et @GeneratedValue
JPA 70
Entité
@Id : clé primaire
@GeneratedValue : générer automatiquement la clé
@Entity
public class Personne {
private long id;
private String nom;
private int age;
public Personne( String nom, int age ) {
this.nom = nom;
this.age = age;
}
@Id
@GeneratedValue
public long getId() { return id; }
public void setId( long id ) { this.id = id; }
// méthodes getNom, setNom, getAge, setAge
}
Repository
JPA 71 Lionel Seinturier
Repositoy
• un composant pour gérer les instances d'une entité
• fournit des méthodes pour accéder et sauvegarder les instances de l'entité
• traduit ces méthodes en requêtes SQL exécutées par la base de données
• CRUDRepository : un repository qui fournit les 4 opérations CRUD
• un type générique avec 2 paramètres : l'entité et la clé de l'entité
import org.springframework.data.repository.CrudRepository;
public interface PersonneRepository
extends CrudRepository<Personne, Long> {}
Rq : Repository spécifique à JPA avec Spring
si JPA sans Spring, il existe un autre composant : EntityManager
CRUD Repository
JPA 72 Lionel Seinturier
Méthodes définies par CrudRepository
Accès au repository par injection de dépendances
@Autowired
private PersonneRepository repo;
Création d'une entité
Personne bob = new Personne("Bob",42);
repo.save(bob);
// requête SQL executée : INSERT INTO PERSONNE VALUES (1,'Bob',42)
CRUD Repository
JPA 73 Lionel Seinturier
Méthodes définies par CrudRepository
Accès à une entité à partir de sa clé primaire
Personne bob = repo.findById(1);
// requête SQL exécutée : SELECT * FROM PERSONNE WHERE ID=1
Modificiation d'une entité
bob.setAge( bob.getAge() + 1 );
repo.save(bob);
// requête SQL exécutée : UPDATE PERSONNE SET AGE=43 WHERE ID=1
Supprésion d'une entité
repo.delete(bob);
// requête SQL exécutée : DELETE FROM PERSONNE WHERE ID=1
CRUD Repository
JPA 74
Repository étendu
• définition de requêtes propres au domaine de l'Entity
• convention de nommage pour les méthodes
• findBy attribut
public interface PersonneRepository
extends CrudRepository<Personne, Long> {
List<Personne> findByNom( String nom );
List<Personne> findByNomAndAge( String nom, int age );
List<Personne> findByNomIgnoreCase( String nom );
List<Personne> findByNomOrderByAgeAsc( String nom );
List<Personne> findByNomOrderByAgeDesc( String nom );
}
And, Or,
LessThan,
GreaterThan
Like, Between
Relations entre entités
JPA 75
Relations entre entités
Liens entre des types de données
Cardinalités
• 1-n
• n-1
• 1-1
• n-n
Annotation JPA
• @OneToMany
• @ManyToOne
• @OneToOne
• @ManyToMany
Relations entre entités
JPA 76
Exemple
@Entity
public class Ecrivain {
@Id long id;
String nom;
@OneToMany
List<Livre> oeuvres;
// constructeur
// getters/setters
}
@Entity
public class Livre {
@Id long id;
String titre;
int annee;
@ManyToOne
Ecrivain auteur;
// constructeur
// getters/setters
}
Ecrivain Livre
1 *
Relations entre entités
JPA 77 Lionel Seinturier
Traduction en schéma relationnel
• 3 tables
• 1 pour chaque entité
• 1 pour la relation
• table ECRIVAIN
• 1 colonne pour ID et 1 colonne pour NOM
• table LIVRE
• 1 colonne pour ID, 1 colonne pour TITRE et 1 colonne pour ANNEE
• 1 colonne supplémentaire AUTEUR_ID comme clé étrangère
• table ECRIVAIN_OEUVRES pour la relation
• 1 colonne ECRIVAIN_ID
• 1 colonne OEUVRES_ID
Relations entre entités
JPA 78 Lionel Seinturier
Notion de mise à jour en cascade
Problématique
• si un côté de la relation est mis à jour, il faut propager la mise à jour de l'autre côté
• exemple
• ajout d'un livre
• => il faut mettre à jour la liste des oeuvres de l'auteur
• la notion de cascade permet de propager les mises à jour
@Entity
public class Ecrivain {
@Id long id;
String nom;
@OneToMany
(cascade=CascadeType.ALL)
List<Livre> oeuvres;
@Entity
public class Livre {
@Id long id;
String titre;
int annee;
@ManyToOne
(cascade=CascadeType.ALL)
Ecrivain auteur;
Relations entre entités
JPA 79 Lionel Seinturier
Types de cascade (CascadeType)
• PERSIST : creation d'une entité
• MERGE : mise à jour d'une entité
• REMOVE : suppression d'une entité
• ALL : toutes les opérations
Modèle de données existant
JPA 80
Principe
• Correspondance attributs et colonnes
• Annotations @Table et @Column
@Entity
@Table(name="AUTEURS")
public class Ecrivain {
@Column("NOM_ID")
String nom;
@OneToMany
List<Livre> oeuvres;
// bean
}
@Entity
@Table(name="OUVRAGES")
public class Livre {
@Column("TITRE_ID")
String titre;
int annee;
@ManyToOne
Ecrivain auteur;
// bean
}
CRUD Repository
JPA 81
Requêtes spécifiques
public interface EcrivainRepository extends CrudRepository<Ecrivain, Long> {
@Query("SELECT DISTINCT a
FROM Ecrivain e INNER JOIN e.oeuvres l
WHERE l.annee = :annee")
public List<Ecrivain> findByAnnee( @Param("annee") int annee );
}
CRUD Repository
JPA 82
Data Transfert Object
• un pattern pour transférer des données entre des couches
• on ne transfère que les données nécessaires
public class NomPrenomDTO {
private String nom;
private String prenom;
public NomPrenomDTO(String nom, String prenom) { ... }
// getters, setters
}
public interface AuteurRepository extends CrudRepository<Auteur, Long> {
@Query("SELECT DISTINCT new NomPrenomDTO(a.nom,a.prenom)
FROM Auteur a INNER JOIN a.livres l
WHERE l.annee=:annee")
public List<NomPrenomDTO> findByAnnee( @Param("annee") int annee );
}
Transaction
JPA 83
Définition
Groupe de requêtes devant être exécutées de façon indivisible
Objectifs
• Concurence des traitements et Consistance des données
Opérations
• début de transaction (begin)
• engagement de la transaction (commit)
• annulation de la transaction (rollback)
Transaction
JPA 84
Exemple (1/3)
Transfert d'argent entre deux comptes bancaires
Contraintes
1. le solde d'un compte ne peut être négatif
2. des transferts (lectures et écritures du solde) simultanés ne doivent pas
mener à des incohérences
=> les transferts simultanés doivent mener au même résultat
que s'ils avaient été exécutés en séquence
Définition de contraintes
JPA 85
Entité
@Entity
public class Account {
@Id
@GeneratedValue
public long id;
public String owner;
@Column(columnDefinition = "FLOAT CHECK( amount >= 0 )")
public double amount;
// ...
Transaction
JPA 86
Exemple (2/3)
Soit une entité Compte avec un attribut solde
@Transactional
public void transfert( Accounf bob, Account anne, double montant ) {
anne.setSolde( anne.getSolde() + montant );
bob.setSolde( bob.getSolde() - montant );
}
Contrainte #1 (le solde ne peut pas être négatif)
• si au départ bob.solde = 42
• => il faut annuler la transaction
Transaction
JPA 87
Exemple (3/3)
Contrainte #2 (pas d'incohérence en cas de parallélisme)
• 2 transferts simultanés de 100, au départ anne.solde=42 et bob.solde=200
• t1 anne.getSolde -> t1 anne.setSolde -> t1 bob.getSolde -> t1 bob.setSolde
• t2 anne.getSolde -> t2 anne.setSolde -> t2 bob.getSolde -> t2 bob.setSolde
• si enchaînement
• t1 anne.getSolde 42 anne.solde=42, bob.solde=200
• t2 anne.getSolde 42 anne.solde=42, bob.solde=200
• t1 anne.setSolde anne.solde=142, bob.solde=200
• t2 anne.setSolde anne.solde=142, bob.solde=200 bug !!
• => la transaction permet d'éviter ce cas
JPA & Hiérarchie de classes
JPA 88
Principe
• par défaut : 1 classe = 1 table
• POO : héritage de classes
Problématique
• lien hiérarchie classes
tables SGBD ?
JPA & Hiérarchie de classes
JPA 89
Solutions
3 politiques proposées par JPA
• SINGLE_TABLE
• une seule table
• colonne discrimante
• TABLE_PER_CLASS
• une table par classe
• données héritées dans toutes les tables
• JOINED
• une table par classe
• chaque table ne contient que les données propres à la classe
JPA & Hiérarchie de classes
JPA 90
Avantages / inconvénients
• SINGLE_TABLE
+ vision globale
- espace inutilisé des entités intermédiaires
• TABLE_PER_CLASS
+ simple, intuitif
- perte du couplage avec les entités héritées
• JOINED
+ plus proche de la hiérarchie de classe
- navigation entre tables pour recontituer les données d'une entité
En résumé
JPA 91
Java Persistence API
• Interface de programmation pour la gestion de données relationnelles
• Manipulation des données d'un SGBD comme des objets
• Sauvegarde des informations transparentes
• Abstraction de SQL

Contenu connexe

Similaire à spring.pdf

Université de la performance - Devoxx France
Université de la performance - Devoxx FranceUniversité de la performance - Devoxx France
Université de la performance - Devoxx France
Marc Bojoly
 
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - CoursENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
Horacio Gonzalez
 

Similaire à spring.pdf (20)

Support JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.YoussfiSupport JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.Youssfi
 
Introduction au web cours.pdf
Introduction au web cours.pdfIntroduction au web cours.pdf
Introduction au web cours.pdf
 
Support NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDBSupport NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDB
 
Les Servlets et JSP
Les Servlets et JSPLes Servlets et JSP
Les Servlets et JSP
 
Java Entreprise Edition
Java Entreprise EditionJava Entreprise Edition
Java Entreprise Edition
 
0570-les-services-web.pdfbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
0570-les-services-web.pdfbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0570-les-services-web.pdfbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
0570-les-services-web.pdfbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
 
Meetup python-bottle-telosys-2018-lgu-v1.0
Meetup python-bottle-telosys-2018-lgu-v1.0Meetup python-bottle-telosys-2018-lgu-v1.0
Meetup python-bottle-telosys-2018-lgu-v1.0
 
Les nouveautés du Framework .NET 4.5
Les nouveautés du Framework .NET 4.5Les nouveautés du Framework .NET 4.5
Les nouveautés du Framework .NET 4.5
 
Chap7_JavaNet.pdf
Chap7_JavaNet.pdfChap7_JavaNet.pdf
Chap7_JavaNet.pdf
 
soapC1.pdfnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
soapC1.pdfnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnsoapC1.pdfnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
soapC1.pdfnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
 
Perf university
Perf universityPerf university
Perf university
 
Serveurs
ServeursServeurs
Serveurs
 
Université de la performance - Devoxx France
Université de la performance - Devoxx FranceUniversité de la performance - Devoxx France
Université de la performance - Devoxx France
 
La plateforme JEE
La plateforme JEELa plateforme JEE
La plateforme JEE
 
Cours 8 squid.pdf
Cours 8 squid.pdfCours 8 squid.pdf
Cours 8 squid.pdf
 
.NET DotNet CF - 3
.NET DotNet CF - 3.NET DotNet CF - 3
.NET DotNet CF - 3
 
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - CoursENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
ENIB cours CAI Web - Séance 3 - JSP/Servlet - Cours
 
Les socket ing1_issat
Les socket ing1_issatLes socket ing1_issat
Les socket ing1_issat
 
Ns python web 1
Ns python web 1Ns python web 1
Ns python web 1
 
De l'Open Source à l'Open API (in French)
De l'Open Source à l'Open API (in French)De l'Open Source à l'Open API (in French)
De l'Open Source à l'Open API (in French)
 

spring.pdf

  • 1. Java EE Spring – Introduction Guillaume Dufrêne – Lionel Seinturier Université de Lille Java EE Spring JDK Java EE Introduction 2 Définition Ensemble de spécifications, de concepts et d'API pour le développement en Java d'applications d'entreprise J2EE Java EE 1.0 1.1 1.2 1.3 1.4 5 6 7 Sun Microsystems Oracle • 1 9 9 6 • 1 9 9 7 • 1 9 9 9 • 2 0 0 1 • 2 0 0 3 • 2 0 0 6 • 2 0 0 9 • 2 0 1 3 • 2 0 1 7 Historique Eclipse Foundation • 2 0 1 9 • 2 0 2 0 • 2 0 2 3 Jakarta EE 8 9 10 Notions générales Introduction 3 Client-serveur Notions générales Introduction 4 Architecture client-serveur 3 tiers – n tiers (couches) Modèle d’organisation des applications Traitement Données Présentation • Les tiers peuvent être distribués sur un réseau et accessibles en mode client/serveur
  • 2. Notions générales Introduction 5 Lionel Seinturier Serveur d'applications Un serveur qui héberge des applications accessibles via le réseau Le plus utilisé pour Jakarta EE Apache Tomcat • 1ère version : 1999 • en octobre mars 2023 : version 10.1.7 • open source • code développé en Java Spring Introduction 6 Définition “Spring is an application framework for the Java platform ” Outils et de règles facilitant le développement d'applications Principes généraux Introduction 7 Principes généraux mis en oeuvre dans Spring • Approche MVC • Injection de dépendances Les applications web (mais pas uniquement) Un écosystème vaste de plus de 50 sous-projets MVC Introduction 8 Définition Un schéma de structuration des applications en trois parties • Modèle données à présenter à l'utilisateur • Vue affichage des données, interactions avec l'utilisateur • Contrôleur gestion des actions de l'utilisateur https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/
  • 3. MVC et 3-tiers Introduction 9 Lionel Seinturier Traitement Données Services Contrôleur Présentation Modèle Vue Architecture type d'une application Spring • contrôleur • accède à des services • traitements • accès données SGBD • construit un modèle • crée une vue avec ce modèle • souvent associée au pattern DTO Data Transfert Object Injection de dépendances Introduction 10 Principe Eviter de coder en dur les dépendances entre • un service • le code qui utilise ce service Séparation • interface de service • implémentation du service • utilisation du service Injection de dépendances Introduction 11 Sans injection de dépendances interface GreeterItf { String sayHello(); } class GreeterImpl implements GreeterItf { public String sayHello() { return "Hello world!"; } } class Client { GreeterItf greeter = new GreeterImpl(); void run() { var str = greeter.sayHello(); System.out.println(str); } } on code en dur la dépendance entre un service et son utilisation + pb si plusieurs utilisations Injection de dépendances Introduction 12 Injection de dépendances • découpler le service de son (ses) utilisation • ce n'est plus le développeur qui créé le lien • le framework (Spring) le fait • utilisation d'annotations pour • le service • @Service • le code qui utilise le service • @Autowired
  • 4. Injection de dépendances Introduction 13 Sans injection de dépendances interface GreeterItf { String sayHello(); } class GreeterImpl implements GreeterItf { public String sayHello() { return "Hello world!"; } } class Client { GreeterItf greeter = new GreeterImpl(); void run() { var str = greeter.sayHello(); System.out.println(str); } } Injection de dépendances Introduction 14 Avec injection de dépendances interface GreeterItf { String sayHello(); } @Service class GreeterImpl implements GreeterItf { public String sayHello() { return "Hello world!"; } } class Client { @Autowired GreeterItf greeter; void run() { var str = greeter.sayHello(); System.out.println(str); } } Spring positionne automatiquement la valeur de greeter avec la référence de l'objet GreeterImpl on dit que Spring "injecte" la référence Java EE Spring – HTTP > servlet > contrôleur Guillaume Dufrêne – Lionel Seinturier Université de Lille Java EE Spring HTTP Guillaume Dufrêne – Lionel Seinturier Université de Lille HTTP
  • 5. HTTP 17 Lionel Seinturier HTTP Hypertext Transfer Protocol (HTTP) • protocole dit de niveau applicatif • utilise TCP ð garantie d'un transport fiable (sans erreur) • pas de notion de connexion HTTP • tous les commandes HTTP sont émises en mode texte (ASCII) ð protocole simple, facilement implantable • standardisé par une RFC • existe depuis 1989 (v0.9) • version 2 en 2015 • version 3 en 2022 (transport QUIC à la place de HTTP) • cohabitation versions actuelles HTTP/2 et HTTP/3 HTTP 18 Lionel Seinturier HTTP 2 messages (commandes) principaux GET demande d'un document POST envoi des données saisies dans un formulaire Autres messages • PUT dépôt (upload) d'un fichier sur le serveur • DELETE suppression d'un fichier • et aussi HEAD, OPTIONS, TRACE, PATCH, CONNECT HTTP 19 Lionel Seinturier HTTP Requête commande URL version_HTTP_comprise_par_le_client en-tête_1_HTTP: valeur .... en-tête_n_HTTP: valeur informations envoyées par le client (par ex. texte saisi dans un formulaire HTML) GET /index.html HTTP/2.0 Accept-language: fr User-Agent: Mozilla/42.0 If-modified-since: Tue, 23 Jul 2020 10:24:05 POST /index.php HTTP/2.0 Accept-language: fr nom=Seinturier&prenom=Lionel HTTP 20 Lionel Seinturier HTTP Réponse version_HTTP_du_serveur code_retour commentaire en-tête_1_HTTP: valeur .... en-tête_n_HTTP: valeur document texte (HTML, …) ou binaire (GIF, JPG, …) HTTP/2.0 200 OK Content-Length: 9872 Content-Type: text/html <HTML> .... </HTML>
  • 6. HTTP 21 Lionel Seinturier HTTP Réponse code retour : renseigne sur le succès (200) ou l'échec (4xx) de la requête • 200 : ok • 404 : document inconnu • 401 : authentification nécessaire • 500 : erreur du serveur HTTP dans le traitement requête (servlet, PHP, …) • 503 : serveur temporairement surchargé • … en-têtes HTTP : informations transmises par le serveur sur le document envoyé • Content-Length : taille du document • Last-Modified : date de dernière modification du document • Server : nom du logiciel serveur • Expire : date d'expiration du document • Content-Type : type (MIME) du document • … nombreux autres en-têtes possibles REST Java EE 22 Lionel Seinturier Principe • à la base HTTP requête-réponse pour le transfert de documents (HTML, etc.) • REST • HTTP comme moyen d'invoquer des services à distance • on parle de ressources distantes • chaque ressource = une URL • ex. http://foo.com/myapp/users/Bob • invocation d'un service • une requête HTTP (GET, POST, PUT, DELETE, etc.) • la réponse à une invocation de service • le retour de la requête HTTP (souvent JSON, mais aussi …) REST Java EE 23 Lionel Seinturier Pattern CRUD • il n'y a pas de signification prédéfinie pour les requêtes GET, POST, PUT, DELETE, etc. • laissée au choix du développeur • souvent CRUD • POST (C) create création • GET (R) read lecture • PUT (U) update mise à jour • DELETE (D) delete suppression Servlet Guillaume Dufrêne – Lionel Seinturier Université de Lille Servlet
  • 7. Page web dynamique côté serveur Servlet 25 Servlet Programme Java s'exécutant côté serveur Web • permet de créer des pages web dynamiques • exécuté par un "moteur" de servlet • désigné par une URL ex. : http://www.fun.fr/myapp/prog Ma première servlet Servlet 26 Programmation Ecriture d’une classe Java • étend la classe HttpServlet • redéfinit la méthode doGet Ma première servlet Servlet 27 Programmation @WebServlet(urlPatterns={"/maservlet"}) public class HelloServlet extends HttpServlet { public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); out.println( "<html><body>" ); out.println( "<h1>Bonjour</h1>" ); out.println( "</body></html>" ); } } Ma première servlet Servlet 28 Résultat Chargement dans un navigateur de l’URL http://.../maservlet
  • 8. Instanciation et exécution Servlet 29 Servlet Chaque servlet est un objet Java singleton • 1 seule instance • variables d’instance conservées multi-threadé • exécution concurrente, 1 thread par requête • Conséquences : ü protéger les variables ü préférer les servlets stateless Formulaires Servlet 30 Récupération des données d'un formulaire Exemple de formulaire <HTML> <BODY> <FORM ACTION="salutations" METHOD=POST> Nom <INPUT NAME="nom"> <P> Prénom <INPUT NAME="prenom"> <P> <INPUT TYPE=SUBMIT VALUE="Envoi"> </FORM> </BODY> </HTML> Formulaires Servlet 31 Récupération des données d'un formulaire String getParameter(String) ð retourne le texte saisi ð ou null si le nom de paramètre n'existe pas Formulaires Servlet 32 @WebServlet(urlPatterns={"/salutations"}) public class SalutationsServlet extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); String nom = request.getParameter( "nom" ); String prenom = request.getParameter( "prenom" ); out.println( "<html><body>" ); out.println( "<h1>Exemple de résultat</h1>" ); out.println( "Bonjour " + prenom + " " + nom ); out.println( "</body></html>" ); } } Récupération des données d'un formulaire
  • 9. Formulaires Servlet 33 Récupération des données d'un formulaire clic HTTP Servlet 34 Servlet public class CompteurServlet extends HttpServlet { public void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException { // ... le traitement lorsque la servlet est invoquée avec GET } public void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException { // ... le traitement lorsque la servlet est invoquée avec POST } // ... éventuellement autres méthodes doXXX } Cycle de vie Servlet 35 Servlet une servlet = une classe Java 1. Instanciation (constructeur) 2. Exécution de la méthode init 3. Exécution multi-threadée des requêtes 4. Exécution de la méthode destroy Possibilité de surcharger les méthodes init et destroy void init(ServletConfig conf) throws ServletException { ... } void destroy() { ... } Session Servlet 36 Définition • suivre l'activité d'un utilisateur • isoler les activités des utilisateurs simultanés • chaque utilisateur a sa session qui lui est propre • existe dans d'autres langages que Java (ex. PHP) • débute à l’initiative du serveur • se termine au bout d'un délai d'inactivité • gérée à l'aide de cookies • fonctionne comme une Map void setAttribute( String name, Object value ) Object getAttribute( String name ) void setMaxIntervalTime( int seconds )
  • 10. Session Servlet 37 Programmation @WebServlet(urlPatterns={"/maservlet"}) public class HelloServlet extends HttpServlet { public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { HttpSession session = request.getSession(); Panier panier = (Panier) session.getAttribute("monpanier"); if( panier == null ) { panier = new Panier(); session.setAttribute("monpanier",panier); } } } En résumé Servlet Servlet • programme Java • s'exécutant côté serveur Web • que l'on peut invoquer à l'aide d'une URL • générant du code HTML • bien adapté à l'écriture de traitement • contenant majoritairement du code Java • et quelques parties de code HTML Contrôleur Guillaume Dufrêne – Lionel Seinturier Université de Lille Contrôleur Contrôleur Contrôleur 40 Définition Une classe/objet • qui reçoit des requêtes • et qui fournit une réponse destinée à être affichée par une vue • nombreuses solutions pour les vues (HTML, JSON, etc.) Architecture générale Spring
  • 11. Contrôleur Contrôleur 41 Un premier exemple @Controller public class HelloController { @GetMapping("/hello") @ResponseBody public String sayHello() { return "<h1>Hello world!</h1>"; } } Contrôleur Contrôleur 42 Un contrôleur retourne • une chaîne de caractères contenant du HTML • mais surtout le plus souvent • (le nom d') une vue • des données formattées en JSON • etc. Vue Vue 43 Définition • Partie présentation des applications Spring • 2 solutions • des vues gérées par des frameworks front • Angular, React, Vue.js, etc. • (hors de l'objectif de ce cours) • des vues préparées côté serveur • HTML, Thymeleaf, JSP, JSTL, etc. CONTROLLEUR VUE requête modèle Vue Vue 44 Contrôleur • retourner le nom de la vue • la vue peut être une "simple" page HTML @Controller public class HelloController { @GetMapping("/hello") public String sayHello() { return "hello"; } } Fichier hello.html <html> <body> <h1>Hello world!</h1> </body> </html>
  • 12. Modèle Vue 45 Lionel Seinturier Modèle • les données à transmettre à la vue • utilisation de l'API org.springframework.ui.Model • fonctionne comme une Map Model addAttribute( String name, Object value ) Object getAttribute( String name ) boolean containsAttribute( String name ) Modèle Vue 46 Modèle • paramètre dans les arguments de la méthode • sa valeur est injectée par Spring • le modèle est transmis à la vue @Controller public class HelloController { @GetMapping("/hello2") public String sayHello( Model model ) { model.addAttribute("nom","Doe"); model.addAttribute("prenom","John"); return "home"; } } Vue Thymeleaf Java EE 47 Lionel Seinturier Vue Thymeleaf • un moteur de template HTML pour des vues construites côté serveur • accès aux variables du modèle <html xmlns:th="http://www.thymeleaf.org"> <body> <h1>Hello <span th:text="${prenom}"/> <span th:text="${nom}"/> </h1> </body> </html> Contrôleur Java EE 48 Lionel Seinturier Les routes • mécanisme pour aiguiller les requêtes vers les contrôleurs/méthodes • cf. annotation @GetMapping • autre annotation @RequestMapping @Controller @RequestMapping("/myapp") public class HelloController { @GetMapping("/hello") public String sayHello() { return "hello"; } } Accès http://localhost:8080/myapp/hello
  • 13. Contrôleur Java EE 49 Lionel Seinturier Les variables dans les routes • mécanisme pour paramétrer les routes • { … } dans l'URL • accès à la valeur via une variable associée à l'annotation @PathVariable @Controller @RequestMapping("/ecommerce") public class ArticleController { @GetMapping("/article/{id}") public String getArticle( @PathVariable String id ) { ... } } Accès http://localhost:8080/ecommerce/article/smartphone http://localhost:8080/ecommerce/article/tv http://localhost:8080/ecommerce/article/170482365 ... Contrôleur Java EE 50 Lionel Seinturier Les variables dans les routes • plusieurs variables peuvent être utilisées dans les routes @Controller @RequestMapping("/ecommerce") public class CommandeController { @GetMapping("/commande/{annee}/{mois}") public List<Commande> findCommandeByAnneeAndMois( @PathVariable String annee, @PathVariable String mois ) { ... } } Accès http://localhost:8080/ecommerce/commande/2024/janvier http://localhost:8080/ecommerce/commande/2020/mars ... Contrôleur Java EE 51 Lionel Seinturier Différentes requêtes HTTP dans un contrôleur • un même contrôleur peut gérer différentes requêtes HTTP (GET, POST, etc.) • annotation @PostMapping, etc. @Controller @RequestMapping("/user") public class UserController { @PostMapping("/create") public String create( @RequestParameter String nom, @RequestParameter String prenom ) { ... } @GetMapping("/read/{id}") public String read( ... ) { ... } } <html> <body> <form action="/user/create" method="POST"> Nom <input name="nom"> Prénom <input name="prenom"> <input type="SUBMIT"> </form></body> </html> Contrôleur REST Contrôleur 52 Pattern REST + retours JSON @RestController public class ClientRestController { @PostMapping(value="/client") public Client create( @RequestBody Client client ) { return service.create(client); } @GetMapping("/client/{id}") public Client read( @PathVariable long id ) { return service.read(id); } @PutMapping("/client/{id}") public Client update( @PathVariable long id, @RequestBody Client client ) { return service.update(id,client); } @DeleteMapping("/client/{id}") public void delete( @PathVariable long id ) { service.delete(id); } }
  • 14. Contrôleur Contrôleur 53 Accès à la session • paramètre HttpSession dans les arguments de la méthode • sa valeur est injectée par Spring @Controller @RequestMapping("ecommerce") public class MagasinController { @GetMapping("/ajouter/{id}") public String ajouter( HttpSession session, @PathVariable String id ) { Panier monPannier = (Panier) session.getAttribute("panier"); if( monPannier == null ) { monPannier = new Pannier(); session.setAttribute("panier", monPannier); } monPannier.ajouter(id); } } En résumé Contrôleur 54 Contrôleur • une classe annotée • qui définit des méthodes • pour recevoir des requêtes HTTP • les traiter • renvoyer un contenu • HTML • JSON • etc. Java EE Spring – Vues avec Thymeleaf Lionel Seinturier Université de Lille Java EE Spring Thymeleaf Java EE 56 Lionel Seinturier Thymeleaf • un moteur de template HTML pour des vues construites côté serveur • des parties fixes (HTML pur) • des parties variables • un namespace (ici associé au prefix th) • avec des variables ${ ... } <html xmlns:th="http://www.thymeleaf.org"> <body> <h1>Hello <span th:text="${prenom}"/> <span th:text="${nom}"/> </h1> </body> </html>
  • 15. Thymeleaf Java EE 57 Lionel Seinturier Variables • tous les types sont possibles (String, List, objets Java, etc.) • pour les chaînes de caractères • concaténation avec + • chaînes de caractètres constantes '…….' <html xmlns:th="http://www.thymeleaf.org"> <body> <h1 th:text="'Hello '+${prenom}+' '+${nom}" /> </body> </html> Thymeleaf Java EE 58 Lionel Seinturier Variables • pour les objets Java accès au variable ${objet.champ} public class Personne { private String nom; private int age; // + constructeurs, getters et setters pour nom et age } <html xmlns:th="http://www.thymeleaf.org"> <body> <h1 th:text="${personne.nom}+' a '+${personne.age}+' ans'" /> </body> </html> • variable prédéfinie session <h1 th:text="${session.email}" /> Thymeleaf Vue 59 Itération • balise each pour itérer sur les éléments d'une collection • ici collection ${auteurs} <html xmlns:th="https://www.thymeleaf.org" > <body> <h1>Liste des auteurs</h1> <table border="1"> <tr><th>Id</th><th>Nom</th><th>Prénom</th></tr> <tr th:each="auteur : ${auteurs}"> <td th:text="${auteur.id}" /> <td th:text="${auteur.nom}" /> <td th:text="${auteur.prenom}" /> </tr> </table> </body> </html> Thymeleaf Java EE 60 Lionel Seinturier Itération • transmission de la collection dans le modèle @Controller @RequestMapping("/bib") public class BibliothequeController { @GetMapping("/home") public String home( Model model ) { List<Auteur> auteurs = new ArrayList<>(); auteurs.add( new Auteur("Hugo","Victor") ); auteurs.add( new Auteur("Zola","Emile") ); model.addAttribute("auteurs",auteurs); return "home"; } }
  • 16. Thymeleaf Vue 61 Lionel Seinturier Itération Résultat Thymeleaf Vue 62 Lionel Seinturier Conditionnel • balise if : action si la condition est vraie • balise unless : idem faux <td> <span th:if="${personne.age >= 18}">Majeur</span> <span th:unless="${personne.age >= 18}">Mineur</span> </td> • balises switch et case pour tester différents cas Thymeleaf Java EE 63 Lionel Seinturier Thymeleaf • un moteur de template HTML pour des vues construites côté serveur • le moteur de template "officiel" de Spring • permet de manipuler des variables • itérations, conditionnels • plus d'informations https://www.thymeleaf.org Java Persistence API Guillaume Dufrêne – Lionel Seinturier Université de Lille JPA
  • 17. Java Persistence API JPA 65 Définition Java Persistence API interface de programmation pour la gestion de données relationnelles appelé Jakarta Persistance depuis la version 3.0 en 2020 • Manipulation de données et de leurs relations • 3 parties • les annotations • l'API pour manipuler les données • JPQL JPA et ORM JPA 66 Définition Object Relation Mapping Technique de programmation Schéma de données Objets ORM • opérations SQL courantes • vision homogène • haut niveau • transfert automatique des données ORM Vocabulaire JPA JPA 67 Définitions Entité • un ensemble de données d'un même type (eg. Personne) Persistance / persister • action de sauvegarder des données dans une base de données (SGBD) JPA et SGBD JPA 68 Principes de mise en correspondance • une classe Java une table SQL • une propriété d'une classe une colonne dans une table SQL • une référence entre classes une relation entre tables SQL • un objet Java un enregistrement dans une table SQL Remarques • nb objets ≠ nb enregistrements • les données peuvent être chargées de façon dite paresseuse (lazy)
  • 18. Annotation @Entity JPA 69 Entité • à déclarer sur les classes dont les données doivent être prises en charge par JPA @Entity public class Personne { private String nom; private int age; public Personne( String nom, int age ) { this.nom = nom; this.age = age; } public String getNom() { return nom; } public void setNom( String nom ) { this.nom = nom; } public int getAge() { return age; } public void setAge( int age ) { this.age = age; } } Annotations @Id et @GeneratedValue JPA 70 Entité @Id : clé primaire @GeneratedValue : générer automatiquement la clé @Entity public class Personne { private long id; private String nom; private int age; public Personne( String nom, int age ) { this.nom = nom; this.age = age; } @Id @GeneratedValue public long getId() { return id; } public void setId( long id ) { this.id = id; } // méthodes getNom, setNom, getAge, setAge } Repository JPA 71 Lionel Seinturier Repositoy • un composant pour gérer les instances d'une entité • fournit des méthodes pour accéder et sauvegarder les instances de l'entité • traduit ces méthodes en requêtes SQL exécutées par la base de données • CRUDRepository : un repository qui fournit les 4 opérations CRUD • un type générique avec 2 paramètres : l'entité et la clé de l'entité import org.springframework.data.repository.CrudRepository; public interface PersonneRepository extends CrudRepository<Personne, Long> {} Rq : Repository spécifique à JPA avec Spring si JPA sans Spring, il existe un autre composant : EntityManager CRUD Repository JPA 72 Lionel Seinturier Méthodes définies par CrudRepository Accès au repository par injection de dépendances @Autowired private PersonneRepository repo; Création d'une entité Personne bob = new Personne("Bob",42); repo.save(bob); // requête SQL executée : INSERT INTO PERSONNE VALUES (1,'Bob',42)
  • 19. CRUD Repository JPA 73 Lionel Seinturier Méthodes définies par CrudRepository Accès à une entité à partir de sa clé primaire Personne bob = repo.findById(1); // requête SQL exécutée : SELECT * FROM PERSONNE WHERE ID=1 Modificiation d'une entité bob.setAge( bob.getAge() + 1 ); repo.save(bob); // requête SQL exécutée : UPDATE PERSONNE SET AGE=43 WHERE ID=1 Supprésion d'une entité repo.delete(bob); // requête SQL exécutée : DELETE FROM PERSONNE WHERE ID=1 CRUD Repository JPA 74 Repository étendu • définition de requêtes propres au domaine de l'Entity • convention de nommage pour les méthodes • findBy attribut public interface PersonneRepository extends CrudRepository<Personne, Long> { List<Personne> findByNom( String nom ); List<Personne> findByNomAndAge( String nom, int age ); List<Personne> findByNomIgnoreCase( String nom ); List<Personne> findByNomOrderByAgeAsc( String nom ); List<Personne> findByNomOrderByAgeDesc( String nom ); } And, Or, LessThan, GreaterThan Like, Between Relations entre entités JPA 75 Relations entre entités Liens entre des types de données Cardinalités • 1-n • n-1 • 1-1 • n-n Annotation JPA • @OneToMany • @ManyToOne • @OneToOne • @ManyToMany Relations entre entités JPA 76 Exemple @Entity public class Ecrivain { @Id long id; String nom; @OneToMany List<Livre> oeuvres; // constructeur // getters/setters } @Entity public class Livre { @Id long id; String titre; int annee; @ManyToOne Ecrivain auteur; // constructeur // getters/setters } Ecrivain Livre 1 *
  • 20. Relations entre entités JPA 77 Lionel Seinturier Traduction en schéma relationnel • 3 tables • 1 pour chaque entité • 1 pour la relation • table ECRIVAIN • 1 colonne pour ID et 1 colonne pour NOM • table LIVRE • 1 colonne pour ID, 1 colonne pour TITRE et 1 colonne pour ANNEE • 1 colonne supplémentaire AUTEUR_ID comme clé étrangère • table ECRIVAIN_OEUVRES pour la relation • 1 colonne ECRIVAIN_ID • 1 colonne OEUVRES_ID Relations entre entités JPA 78 Lionel Seinturier Notion de mise à jour en cascade Problématique • si un côté de la relation est mis à jour, il faut propager la mise à jour de l'autre côté • exemple • ajout d'un livre • => il faut mettre à jour la liste des oeuvres de l'auteur • la notion de cascade permet de propager les mises à jour @Entity public class Ecrivain { @Id long id; String nom; @OneToMany (cascade=CascadeType.ALL) List<Livre> oeuvres; @Entity public class Livre { @Id long id; String titre; int annee; @ManyToOne (cascade=CascadeType.ALL) Ecrivain auteur; Relations entre entités JPA 79 Lionel Seinturier Types de cascade (CascadeType) • PERSIST : creation d'une entité • MERGE : mise à jour d'une entité • REMOVE : suppression d'une entité • ALL : toutes les opérations Modèle de données existant JPA 80 Principe • Correspondance attributs et colonnes • Annotations @Table et @Column @Entity @Table(name="AUTEURS") public class Ecrivain { @Column("NOM_ID") String nom; @OneToMany List<Livre> oeuvres; // bean } @Entity @Table(name="OUVRAGES") public class Livre { @Column("TITRE_ID") String titre; int annee; @ManyToOne Ecrivain auteur; // bean }
  • 21. CRUD Repository JPA 81 Requêtes spécifiques public interface EcrivainRepository extends CrudRepository<Ecrivain, Long> { @Query("SELECT DISTINCT a FROM Ecrivain e INNER JOIN e.oeuvres l WHERE l.annee = :annee") public List<Ecrivain> findByAnnee( @Param("annee") int annee ); } CRUD Repository JPA 82 Data Transfert Object • un pattern pour transférer des données entre des couches • on ne transfère que les données nécessaires public class NomPrenomDTO { private String nom; private String prenom; public NomPrenomDTO(String nom, String prenom) { ... } // getters, setters } public interface AuteurRepository extends CrudRepository<Auteur, Long> { @Query("SELECT DISTINCT new NomPrenomDTO(a.nom,a.prenom) FROM Auteur a INNER JOIN a.livres l WHERE l.annee=:annee") public List<NomPrenomDTO> findByAnnee( @Param("annee") int annee ); } Transaction JPA 83 Définition Groupe de requêtes devant être exécutées de façon indivisible Objectifs • Concurence des traitements et Consistance des données Opérations • début de transaction (begin) • engagement de la transaction (commit) • annulation de la transaction (rollback) Transaction JPA 84 Exemple (1/3) Transfert d'argent entre deux comptes bancaires Contraintes 1. le solde d'un compte ne peut être négatif 2. des transferts (lectures et écritures du solde) simultanés ne doivent pas mener à des incohérences => les transferts simultanés doivent mener au même résultat que s'ils avaient été exécutés en séquence
  • 22. Définition de contraintes JPA 85 Entité @Entity public class Account { @Id @GeneratedValue public long id; public String owner; @Column(columnDefinition = "FLOAT CHECK( amount >= 0 )") public double amount; // ... Transaction JPA 86 Exemple (2/3) Soit une entité Compte avec un attribut solde @Transactional public void transfert( Accounf bob, Account anne, double montant ) { anne.setSolde( anne.getSolde() + montant ); bob.setSolde( bob.getSolde() - montant ); } Contrainte #1 (le solde ne peut pas être négatif) • si au départ bob.solde = 42 • => il faut annuler la transaction Transaction JPA 87 Exemple (3/3) Contrainte #2 (pas d'incohérence en cas de parallélisme) • 2 transferts simultanés de 100, au départ anne.solde=42 et bob.solde=200 • t1 anne.getSolde -> t1 anne.setSolde -> t1 bob.getSolde -> t1 bob.setSolde • t2 anne.getSolde -> t2 anne.setSolde -> t2 bob.getSolde -> t2 bob.setSolde • si enchaînement • t1 anne.getSolde 42 anne.solde=42, bob.solde=200 • t2 anne.getSolde 42 anne.solde=42, bob.solde=200 • t1 anne.setSolde anne.solde=142, bob.solde=200 • t2 anne.setSolde anne.solde=142, bob.solde=200 bug !! • => la transaction permet d'éviter ce cas JPA & Hiérarchie de classes JPA 88 Principe • par défaut : 1 classe = 1 table • POO : héritage de classes Problématique • lien hiérarchie classes tables SGBD ?
  • 23. JPA & Hiérarchie de classes JPA 89 Solutions 3 politiques proposées par JPA • SINGLE_TABLE • une seule table • colonne discrimante • TABLE_PER_CLASS • une table par classe • données héritées dans toutes les tables • JOINED • une table par classe • chaque table ne contient que les données propres à la classe JPA & Hiérarchie de classes JPA 90 Avantages / inconvénients • SINGLE_TABLE + vision globale - espace inutilisé des entités intermédiaires • TABLE_PER_CLASS + simple, intuitif - perte du couplage avec les entités héritées • JOINED + plus proche de la hiérarchie de classe - navigation entre tables pour recontituer les données d'une entité En résumé JPA 91 Java Persistence API • Interface de programmation pour la gestion de données relationnelles • Manipulation des données d'un SGBD comme des objets • Sauvegarde des informations transparentes • Abstraction de SQL