JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam

 
CONTINUER À LIRE
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE / Spring - Une introduction

NSY102 - 2019

Stéphane Bruyère
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - Les outils

Pour JEE                                      Pour le serveur Tomcat
https://www.eclipse.org/downloads/packages/   https://tomcat.apache.org/download-90.cgi

2
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - SPRING - Les outils

                            Pour Spring
                            https://spring.io/tools

3
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - Introduction

Java EE ou JEE (maintenant Jakarta EE) est une est une
spécification pour la plate-forme Java destinée aux applications
d'entreprise.
L'objectif majeur de JEE est de faciliter le développement
d'applications web robustes et distribuées, déployées et
exécutées sur un serveur d'applications.
JEE étend donc Java SE en fournissant un ensemble de concepts
et d’API pour le développement d’applications web.
JEE est défini à l’aide d’un ensemble de standards (JSR - java
specification request) spécifiques.

4
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - Introduction

Un serveur d'applications est l’infrastructure logicielle qui
permet d’héberger les applications developpées selon le
standard JEE.
Il en existe plusieurs implémentations, dont une de référence
(Oracle Glassfish).
Parmi les implémentations complètes open source, on citera
notamment Wildly (RedHat) et Payara (dérivé de Glassfish),
et Apache Tomcat ou encore Jetty pour les conteneurs web
légers.

5
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - Introduction

Les serveurs d’applications implémentant JEE doivent être
certifiés pour une version donnée de JEE.
Un outils existe : le TCK (test compatibility kit) est un ensemble
de tests (environ 20,000) qui accompagne les spécifications Java
EE et permet de verifier qu’un serveur d’applications donné
répond bien aux standards JEE.

6
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - principes

Java Enterprise Edition, comme son nom l'indique, a été créé
pour le développement d'applications d'entreprises.
Ses spécifications ont été pensées dans cette optique, afin de
permettre le développement le plus rapide possible
d’applications d’entreprise qualitatives, sûres, sécurisées,
portables, performantes, disponibles, maintenables,
extensibles ...

7
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - notions générales - client / serveur

                       client / serveur  requête / réponse

    html, css, javascript                          php, python, C#, javascript ...
    interprétés par le navigateur du client        ... et java

8
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - notions générales - client / serveur

9
JEE / Spring - Une introduction - NSY102 - 2019 Stéphane Bruyère - Cnam
JEE - notions générales - client / serveur

10
JEE - notions générales - architecture 3 tiers

modèle systématique d’organisation des applications JEE :

Présentation   :     JSP, Servlet ...
métier         :     code métier, EJB
Données        :     JDBC, JPA, frameworks ORM ...

Chaque couche est associée à des technologies JEE.
Decouplage fort entre les couches

11
JEE - quelques exemples d’API

●
    Servlets, JSP(Java Server Pages), JSF (Java Server Faces) : pages
    web dynamiques
●
    EJB (Entreprise Java Beans) : objets métiers
●
    JDBC : API d'accès à des SGBD
●
    JNDI (Java Naming an Directory Interface) : API pour nommage des
    objets
●
    JPA (Java Persistence API) : gestion de la persistence et du mapping
    objet-relationnel (correspondances entre les schémas de la base de
    données et les classes du programme applicatif)
●
    JTA (Java Transaction API) ; API pour gestion des transactions

12
JEE - Enterprise Java Bean ou EJB

Ce sont des composants distribués (càd déployés sur des
serveurs distants) hébergés au sein d'un serveur applicatif
permettant de représenter des données (EJB dit « entity bean »),
de proposer des services avec ou sans conservation d'état entre
les appels (EJB dit « session bean »), ou encore d'accomplir des
tâches de manière asynchrone (EJB dit « message-driven bean »).
Tous les EJB peuvent évoluer dans un contexte transactionnel.
Depuis la version 3.0, le modèle EJB utilise le principe
d'annotation java (vs fichier de config xml) pour spécifier la
configuration et les propriétés transactionnelles de l'objet.

13                                                     source wikipedia
JEE - Enterprise Java Bean ou EJB

Les EJB « session » fournissent des services sous forme de
méthodes écrites par le développeur.
Il sont créés, gérés et partagés par le serveur applicatif.
Ils sont récupérés par appels JNDI ou Injection de dépendance.
Ils ne sont donc jamais appelés par new !
Les Session beans sont des objets façade pour les couches
métier.
Ils peuvent être « stateless » s’ils ne conservent pas leur état
entre deux appels, ou « stateful » dans le cas contraire.

14                                                      source S. Rosmorduc GLG203
JEE - Enterprise Java Bean ou EJB

Les EJB « entity » sont des beans ayant majoritairement pour vocation
d'être persistants, c'est-à-dire pouvant être stockés sur un support
physique entre deux sessions.
Depuis la version 3.0 de la spécification EJB, il sont directement liés à la
base de données via un mapping objet-relationnel géré par des
annotations (via JPA).
Les EJB «message-driven» permettent de déclencher un processus côté
serveur applicatif lors de la publication d'un message asynchrone. Le
client ne s'adresse pas directement aux composants mais publie un
message sur un réceptacle JMS (queue ou topic) configuré sur le serveur
applicatif qui va alors déclencher l'activation par ce serveur d'une
instance de l'EJB concerné pour pouvoir traiter ce message.

15                                                             source wikipedia
JEE - architecture

16
JEE - Patrons de conception

Nouveau patrons de conception mis en jeu :

●
     Data Access Object (DAO)
●
     Data Transfer Object (DTO)
●
     Facade
●
     MVC

17
JEE - MVC

JEE permet une utilisation assez naturelle du patron MVC

Dans une application Java EE :
Modèle = objets Java
Vue = pages JSP
Contrôle = servlets (aiguillage les requêtes entrantes vers les traitements et vues
correspondants).

18
JEE - Servlets

2 packages :
●
     javax.servlet : support de servlets génériques indépendants du
     protocole
●
     javax.servlet.http : fonctionnalités spécifiques au protocole
     HTPP
Pour écrire une servlet, il faut :
●
     écrire une classe héritant de javax.servlet.http.HttpServlet
●
     redéfinir les méthodes nécessaires

19
JEE - Servlets

Le cycle de vie d’une servlet est géré par le serveur (web
container)

●
     Initialisation :
     ●
         Chargement de la classe (au démarrage ou sur requête).
     ●
         Instanciation d’un objet.
     ●
         Appel de la méthode init() (de la classe javax.servlet.GenericServlet dont
         hérite HttpServlet. « Called by the servlet container to indicate to a servlet
         that the servlet is being placed into service »)

20
JEE - Servlets

●
     Utilisation :
     ●
         Appel de la méthode service() (« Receives standard HTTP requests from the
         public service method and dispatches them to the doXXX methods defined in
         this class ... There's no need to override this method. »)
     ●
         Dans le cas d’une HttpServlet : appel vers doGet(), doPost().
●
     Destruction :
     ●
         Peut être provoquée pour optimiser la mémoire
     ●
         appel de la méthode destroy() (de la classe GenericServlet. « Called by the
         servlet container to indicate to a servlet that the servlet is being taken out of
         service. »)

21
JEE - invoquer une Servlet

La Servlet est invoquée par une URL dans un navigateur

        http://localhost:8080/MyApp/HelloWorld

       protocole
                   serveur     port
                               contexte de la Servlet
                             nom de l’appli sur le serveur

                                                     url pattern
                                                   pour la Servlet

22
JEE - HttpServletRequest et HttpServletResponse

Ces objet sont notamment passés en paramètre des méthodes
service() et doXXX().
Ils sont instanciés par le conteneur de servlets, qui les transmet à
la méthode service, qui les transmet au méthodes doXXX.

23
JEE - HttpServletRequest extends ServletRequest

HttpServletRequest contient les informations relatives à la requête.
Elle possède notamment les méthodes :
 ●
     getAttribute(String name) : Returns the value of the named attribute as an Object,
     or null if no attribute of the given name exists.
 ●
     setAttribute(String name, Object o) : Stores an attribute in this request.
 ●
     getParameter(String name) : Returns the value of a request parameter as a String,
     or null if the parameter does not exist.
 ●
     getMethod() : Returns the name of the HTTP method with which this request was
     made, for example, GET, POST, or PUT.
 ●
     getSession(boolean create) : Returns the current HttpSession associated with this
     request or, if there is no current session and create is true, returns a new session.

24
JEE - HttpServletResponse extends
ServletResponse

HttpServletResponse permet de construire et renvoyer une
réponse au client. Elle possède notamment les méthodes :
     ●
         setContentType(String type) : Sets the content type of the response being
         sent to the client (ex : text/html;charset=UTF-8).
     ●
         getWriter() : Returns a PrintWriter object that can send character text to the
         client.
     ●
         sendRedirect(String location) : Sends a temporary redirect response to the
         client using the specified redirect location URL and clears the buffer.

25
JEE - HttpServlet ->forward

Transmettre une demande d'un servlet à une autre ressource
(servlet, fichier JSP ou fichier HTML) sur le serveur :

getServletContext().getRequestDispatcher(String path).
forward(ServletRequest request, ServletResponse response)

     ●
         ServletContext : Defines a set of methods that a servlet uses to communicate
         with its servlet container
     ●
         RequestDispatcher : Defines an object that receives requests from the client
         and sends them to any resource on the server.

26
JEE - Execution des Servlets

Une Servlet est un Singleton (1 seule instance par classe).
Les servlets sont donc multithread.
Si le conteneur reçoit plusieurs reqûetes pour une servlet , la
méthode service () de ce servlet sera exécutée simultanément dans
plusieurs threads.
Conséquence : les variables (de classe et d’instance) d’une Servlet
sont des ressources partagées. Seules les variables locales sont
toujours thread safe.
Il faut donc protéger les ressources des accès concurrents ou plus
généralement privilégier les Servlets Stateless

27
JEE - notre 1ère Servlet
                     http://localhost:8080/NSY102/bonjour?param=Bill
@WebServlet(urlPatterns={"/bonjour"})
public class HelloBill extends HttpServlet {
public void doGet(final HttpServletRequest request, final HttpServletResponse response)
                                                                 throws IOException, ServletException {
response.setContentType("text/html");
final PrintWriter out = response.getWriter();
String param = request.getParameter("param");
out.println( "" );
out.println("");
out.println("Hello " + param + "");
out.println(LocalDateTime.now().toLocalDate());
out.println( "" );
out.close();
}
}

28
JEE - notre 1ère Servlet ... avec doPost()

 http://localhost:8080/NSY102/MyForm.html

                                public void doPost(final HttpServletRequest request, final HttpServletResponse response)
                                                   throws IOException, ServletException {
                        response.setContentType("text/html");
Mon Formulaire                      final PrintWriter out = response.getWriter();
                                                   String nom = request.getParameter( "nom" );
                                             String prenom = request.getParameter( "prenom" );
                                              out.println( "" );
                 out.println( "Retour de l'envoi du Formulaire" );
 Nom                           out.println( "Bonjour " + prenom + " " + nom );
 Prénom                     out.println( "" );
                  out.close();

                                     }   post

  29
JEE - Conclusion sur les Servlets

programme Java s'exécutant côté serveur (Servlet container)

• que l'on peut invoquer à l'aide d'une URL

• adapté à l'écriture de traitements complexes (contenant donc
principalement du code java)

• peu adapté à l’écriture de code html complexe

30
JEE - Java Server Page (JSP)

Une JSP est une page HTML avec du code Java s'exécutant côté
serveur.
La technologie JSP permet de créer des pages web dynamiques
exécutées par un moteur de JSP.
Une JSP accessible par son chemin.
Les JSP sont plus adaptées que les servlets pour l’affichage, mais
pas pour les traitements.
Lorsque la JSP est appelée pour la 1ère fois, le serveur crée une
Servlet correspondant à cette JSP.

31
JEE - Java Server Page (JSP)

Dans une JSP, le code java est introduit par 
Ce code sera recopié dans la méthode _jspService de la Servlet
créée. Il ne peut donc contenir que des instructions.
Variables disponibles dans la JSP :
 ●
     request et response, la requête et la réponse
 ●
     out , le flux de sortie pour écrire
 ●
     session session courante du client
 ●
     application pour accéder à l’espace de données partagée (ServletContext)
 ●
     page désigne la JSP courante
 ●
     config pour accéder à l’objet ServletConfig

32
JEE - Java Server Page (JSP)

Les imports :

La balise  permet d’écrire des directives qui concernent la
classe engendrée

L’inclusion de JSP :
●
     : recopie directement le code de toto.jsp
    dans la servlet courante (risque de conflits avec les noms de variables)
●
     inclut le résultat de l’exécution de la jsp
    toto.jsp dans la sortie de la jsp courante. La page incluse est déterminée à
    l’exécution (pas de conflit de nom)

33                                                                source S. Rosmorduc GLG203
JEE - Collaboration JSP/Servlet

La servlet reçoit une requête puis la traite.
Elle utilise ensuite un requestDispatcher pour déléguer la fin du
traitement à une jsp (elle appelle la méthode _jspService de la jsp).
Elle doit dire à la jsp quoi afficher.
●
    problème : passer des information de la servlet à la jsp
●
    solution : les passer en bean request (request.setAttribute() côté
    Servlet et request.getAttribute côté JSP)
La JSP peut être masquée (non accessible directement mais
uniquement via la Servlet) en étant placée dans un sous-répertoire
de WEB-INF

34                                                         source S. Rosmorduc GLG203
JEE - notre 1ère JSP

     Factorielles
     
     Table des factorielles
     
35
JEE - notre 2ème JSP

Mon Formulaire       
                             Bonjour
                              
                        salutations
 Nom           
                             
 36
JEE - une petite dernière
package cnam.fr;
import   java.io.IOException;                             
import   javax.servlet.ServletException;                  
import   javax.servlet.annotation.WebServlet;             
import   javax.servlet.http.HttpServlet;                  
import   javax.servlet.http.HttpServletRequest;           
import   javax.servlet.http.HttpServletResponse;          Signin Template
                                                          
@WebServlet(urlPatterns = { "/signin" })                  
public class SigninServlet extends HttpServlet {          Login
                                                          
public void doGet(final HttpServletRequest request,       
final HttpServletResponse response)                       
throws IOException, ServletException {                    
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").   ${message}
forward(request, response);                               Please sign in
}                                                         Email address 
final HttpServletResponse response)                       Password 
String email = request.getParameter("email");             Sign
String mdp = request.getParameter("mdp");                 in
if (email == null || mdp == null || "".equals(email)      
|| "".equals(mdp)) {                                      
request.setAttribute("message",                           
"Tous les champs doivent être remplis");                  
} else {
request.setAttribute("email", email);
url = "/WEB-INF/jsp/loggedin.jsp";
}
request.getRequestDispatcher(url).
forward(request, response);
}
}

  37
JEE - une petite dernière
package cnam.fr;
import   java.io.IOException;
import   javax.servlet.ServletException;
import   javax.servlet.annotation.WebServlet;
import   javax.servlet.http.HttpServlet;
import   javax.servlet.http.HttpServletRequest;
import   javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = { "/signin" })
public class SigninServlet extends HttpServlet {
public void doGet(final HttpServletRequest request,
final HttpServletResponse response)
throws IOException, ServletException {
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").
forward(request, response);
}
public void doPost(final HttpServletRequest request,
final HttpServletResponse response)
throws IOException, ServletException {
String url = "/WEB-INF/jsp/login.jsp";                    
String email = request.getParameter("email");             
String mdp = request.getParameter("mdp");                 
if (email == null || mdp == null || "".equals(email)      
|| "".equals(mdp)) {                                      
request.setAttribute("message",                           Signin Template
"Tous les champs doivent être remplis");                  
} else {                                                  
request.setAttribute("email", email);                     Login
url = "/WEB-INF/jsp/loggedin.jsp";                        
}                                                         
request.getRequestDispatcher(url).                        
forward(request, response);                               Vous êtes authentifié avec l'adresse e-mail ${email}
}                                                         
}                                                         
                                                          
  38
JEE - Les sessions

●
    Http étant un protocole sans état, une session permettra de
    suivre l’activité d’un internaute.
●
    Objet prédéfini de type HttpSession en java (methode
    HttpSession getSession(boolean) sur HttpServletRequest pour
    le récupérer)
●
    Garantie d’isolation des sessions les unes des autres sur une
    même application.
●
    Opérations sur la session :
    ●
        void setAttribute( String name, Object value )
    ●
        Object getAttribute( String name )

39
JEE - Les sessions ... vite, un exemple !
     La Servlet 1/2

@WebServlet(urlPatterns = { "/checkSession" })
public class SessionServlet extends HttpServlet {
public void doGet(final HttpServletRequest request, final HttpServletResponse response)
     throws IOException, ServletException {

// Calcule le temps de persistence de la session http
long created = System.currentTimeMillis();
long current = request.getSession().getCreationTime();
int totalSeconds = (int) (created - current) / 1000;
//

String refresh = request.getParameter("refresh");

// Si on clique sur le bouton rafraichir avec une session active
if (refresh != null && request.getSession().getAttribute("sessionUser") !=null)
     request.setAttribute("message", "La valeur " + request.getSession().
          getAttribute("sessionUser") est stockée en session depuis " + totalSeconds + " secondes!
          ");
request.getRequestDispatcher("/WEB-INF/jsp/essaiSession.jsp").forward(request, response);
}
...

40
JEE - Les sessions ... vite, un exemple !
...   La Servlet 2/2
public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException,
ServletException {

HttpSession session = request.getSession();
String sessionUser = (String) session.getAttribute("sessionUser");

// Calcule le temps de persistence de la session http
long created = System.currentTimeMillis(); long current = session.getCreationTime();
int totalSeconds = (int) (created - current) / 1000;
//
String user = request.getParameter("user");
String invalidate = request.getParameter("invalidate");
// Si la session est nouvelle
if (sessionUser == null || sessionUser.length() < 0) {
// Si le nom de l'utilisateur est saisi
if (user != null && user.length() > 0) {
request.setAttribute("message", "La valeur " + user + " est stockée en session");
session.setAttribute("sessionUser", user);
}
// Si on clique sur le bouton invalider session
} else if (invalidate != null && invalidate.length() > 0) {
session.invalidate();
// La session existe, on affiche sa durée
} else {
request.setAttribute("message",
"Session en cours pour " + sessionUser + " depuis " + totalSeconds + " secondes !Veuillez invalider pour
changer d'utilisateur");
}
request.getRequestDispatcher("/WEB-INF/jsp/essaiSession.jsp").forward(request, response);
}
}

41
JEE - Les sessions ... vite, un exemple !
     La JSP 1/1

                  Signin Template
                  
                  Login
                  
                  ${message}
                  
                  Utilisateur: 
                  
                  Rafraichir
                  
42
JEE - JDBC
  Package Java pour l'accès aux SGDBR :
 java.sql                                   driver 100% java       Mise en oeuvre :
                                                                   1. Enregistrer le driver JDBC
                                                                   2. Ouvrir une connexion sur la
                                                                   base
                                                                   3. Créer la requête (un
                                                                   Statement)
                                                                   4. Exécuter la requête
                                                                   5. Traiter le résultat retourné
                                                                   (un ResultSet)
                                                                   6. Fermer les objets

 ●
     JDBC permet d' accéder à un SGBDR
 ●
     Une application basée sur JDBC est indépendante du SGBDR utilisé
 ●
     JDBC permet un accès SQL mais n’automatise pas la gestion de la persistance des objets java

43                                                                           source P. Graffion GLG203
JDBC - DAO

Séparation des préoccupations : accès aux données / mise en
oeuvre
●
     bas niveau : requête SQL JDBC
●
     haut niveau : interface java pour l’accès aux données :
     ●
         interface PersonneDAO { List findAll( ); }
●
     3 éléments :
     ●
         interface (suffxée DAO)
     ●
         une classe d’implémentation (suffixée DAOImpl)
     ●
         une classe contenant les données

44
JDBC - DAO

CRUD, acronyme pour Create, Read, Update, Delete
    interface PersonneDAO {
     void add( Personne p );             // Create
     Personne find( int id );            // Read
     List findAll();           // Read
     void update( Personne p );          // Update
     void delete( int id ); }            // Delete

●
     Sépare la logique métier des détails de mise en oeuvre
●
     Permet de se concentrer sur les opération de haut niveau
●
     ... et facilite l’optimisation des requêtes de bas niveau

45
JEE - JPA

Java Persistence API
●
     interface de programmation pour la gestion des données
     relationnelles
●
     plusieurs implémentations : Hibernate, EclipseLink, TopLink ...
●
     Mapping objet-relationnel (ORM ou Object Relation Mapping)
     ●
         Opérations SQL courantes
     ●
         haut niveau
     ●
         transfert automatique des données

46
JEE - JPA

Principes de correspondance :
classe java               table SQL
attribut d’une classe     colonne de table SQL
références en classes     relations entre tables SQL
objet java                enregistrement dans une table SQL

Les modifications apportées à l’objet en mémoire sont
répercutées dans la base.
constructeur, getters / setters obligatoires
47
JEE - annotations JPA

@Entity : à déclarer sur une classe dont les données doivent être prises en
charge par JPA.
@Id : clé primaire (obligatoire)
@GeneratedValue : génération automatique de la clé
@Table : correspondance classe / table
@Column : correspondance attribut / colonne
@OneToMany : cardinalité 1-n
@ManyToOne : cardinalité n-1
@OneToOne : cardinalité 1-1
@ManyToMany : cardinalité n-n

48
JEE - JPA

@Entity
public class Eleve implements Serializable {
@id                                            @Entity
@Column(name= « ELEVE_ID »)                    public class Eleve implements Serializable{
private Long Id                                ...
 private String nom;                           @ManyToMany
 @ManyToOne                                    @JoinTable(name="ELEVE_COURS",
@JoinColumn(name= « ECOLE_ID »)                joinColumns=@JoinColumn(name="EC_ELEVE_ID"),
 private Ecole ecole;                          inverseJoinColumns=@JoinColumn(name="EC_COURS_ID"))
  // constructeur                               private Collection cours;
  // getters/setters                           ...
}                                              }
la classe java qui gère la relation
correspond à la table qui contient
la clé étrangère

49
JEE -           L’Entity Manager de JPA

L’EntityManager assure la liaison entre java et le SGBD.
Il fournit les méthodes courantes d’accès aux données.
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("myApp");
     EntityManager em = emf.createEntityManager();

     Personne bill = new Personne("Bill", 37);

     em.persist(bill);

     Personne p123 = em.find(Personne.class, 123); // recherche de la personne d’id 123

     bill.setAge(38);
     em.merge(bill);

     em.remove(bill);

50
JEE -     JPA et JTA (Java Transaction API)

Les transactions sont un élément fondamental de la persistance. Une
transaction de base de données consiste en un ensemble d'opérations
SQL validées ou non, mais de façon indivisible.
Une transaction au niveau objet est une opération dans laquelle un
ensemble de modifications apportées à un ensemble d'objets est
validé dans la base de données comme un groupe indivisible.
Objectif : permettre la concurrence des traitements tout en
garantissant la cohérence des données.
Les transactions dans JPA se font toujours au niveau objet. Cela
signifie que toutes les modifications apportées à tous les objets
intégrés au contexte de persistance font partie de la transaction.

51
JEE -    JPA et JTA

Par défaut, les méthodes des EJB sont transactionnelles. Dans un
EJB, l’appel d’une méthode démarre une transaction JTA si aucune
n'est en cours.
On injecte l’EntityManager en utilisant l’annotation
@PersistenceContext. Ensuite, les méthodes sont transactionnelles
par défault.     @Stateless
               public class MaClasseService {

                @PersistenceContext(unitName = "annuairePU")
                EntityManager em;

                public void enregistrer(List personnes) {
                  for (Personne p: personnes) {
                    em.persist(p);
                  }
                }
52
JEE -           JPA et JTA

Gestion des erreurs :
Quand la fonction se termine correctement :
     ●
         commit automatique
Quand elle échoue sur une exception :
     ●
         RuntimeException -> rollback
     ●
         Exceptions déclarées -> commit

53
JEE -       JPA et JTA

Initier une transaction dehors du mode géré par le container.
EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName)
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();

Compte bill = em.find( Compte.class, "Bill" );
Compte martin = em.find( Compte.class, "Martin" );
tx.begin();
try {
  bill.setSolde( bill.getSolde() - 100 );
  martin.setSolde( martin.getSolde() + 100);
  em.persist(bill);
  em.persist(martin);
  tx.commit();
}
catch( Exception e ) {
  tx.rollback();
}
em.close();
emf.close();

54
JEE - JPA Persitence Unit

La configuration de l’accès à la bd est est paramétrée dans le
fichier META-INF/persistence.xml.
     
                org.hibernate.jpa.HibernatePersistenceProvider
                
55
JEE - exemple d’implémentation JPA
                 3 classes « métier » : Ecole, Matière, Elève
@Entity                                     @Entity
public class Ecole {                        public class Matiere {

     @Id                                         @Id
     @GeneratedValue                             @GeneratedValue
     private int id;                             private int id;

     private String nom;                         private String nom;

     public Ecole() {}                           public Matiere() {}

     public int getId() {                        public int getId() {
          return id;                                  return id;
     }                                           }

     public void setId(int id) {                 public void setId(int id) {
          this.id = id;                               this.id = id;
     }                                           }

     public String getNom() {                    public String getNom() {
          return nom;                                 return nom;
     }                                           }

     public void setNom(String nom) {            public void setNom(String nom) {
          this.nom = nom;                             this.nom = nom;
     }                                           }
}                                           }

56
JEE - exemple d’implémentation JPA
@Entity
public class Eleve {                                       ...
                                                           public String getNom() {
     @Id                                                              return nom;
     @GeneratedValue                                            }
     private int id;
                                                                public void setNom(String nom) {
     private String nom;                                             this.nom = nom;
                                                                }
     @ManyToOne
     @JoinColumn(name="ECOLE_ID")                               public Ecole getEcole() {
     private Ecole ecole;                                            return ecole;
                                                                }
     @ManyToMany
     @JoinTable(name="ELEVE_COURS",                             public void setEcole(Ecole ecole) {
     joinColumns=@JoinColumn(name="EC_ELEVE_ID"),                    this.ecole = ecole;
     inverseJoinColumns=@JoinColumn(name="EC_COURS_ID"))        }
     private Collection matieres;
                                                                public Collection
     public Eleve() {                                      getMatieres() {
          matieres = new HashSet();                                 return matieres;
     }                                                          }

     public int getId() {                                       public void
          return id;                                       setMatieres(Collection matieres) {
     }                                                                this.matieres = matieres;
                                                                }
     public void setId(int id) {                           }
           this.id = id;
     } ...
     ●
         1 élève est dans 1 école (une école a plusieurs élèves)
     ●
         1 élève suit plusieurs cours (un cours comprend également plusieurs élèves)
57
JEE - exemple d’implémentation JPA
public class App {
      public static void main(String[] args) {

           EntityManagerFactory emf = Persistence.createEntityManagerFactory("PU");
           EntityManager em = emf.createEntityManager();
           Ecole cnam = new Ecole();
           cnam.setNom("CNAM");
           Matiere NFP121 = new Matiere();
           NFP121.setNom("NFP121");
           Matiere NSY102 = new Matiere();
           NSY102.setNom("NSY102");
           Matiere GLG203 = new Matiere();
           GLG203.setNom("GLG203");
           Matiere SMB116 = new Matiere();                    EntityTransaction tx = em.getTransaction();
           SMB116.setNom("SMB116");                                      tx.begin();
           Eleve jean = new Eleve();                                     try {
           jean.setNom("Jean");                                                em.persist(cnam);
           jean.setEcole(cnam);                                                em.persist(NFP121);
           jean.getMatieres().add(NFP121);                                     em.persist(NSY102);
           jean.getMatieres().add(NSY102);                                     em.persist(GLG203);
           Eleve paul = new Eleve();                                           em.persist(SMB116);
           paul.setNom("paul");                                                em.persist(jean);
           paul.setEcole(cnam);                                                em.persist(paul);
           paul.getMatieres().add(GLG203);                               tx.commit();
           paul.getMatieres().add(SMB116);                               } catch (Exception e) {
           paul.getMatieres().add(NSY102);                                     tx.rollback();
                                                                         }
                                                                         em.close();
                                                                         emf.close();
                                                                   }
                                                              }

 58
JEE - implementation JPA ... dans une servlet

@WebServlet(urlPatterns = {"/show"})
public class AffichageServlet extends HttpServlet{

     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("PU");
            EntityManager em = emf.createEntityManager();
            DisplayService service = new DisplayService(em);

              List ecoles = service.findAllSchools();
              List matieres = service.findAllCourses();
              List eleves = service.findAllStudents();
              em.close();                                                                  il faut construire
              emf.close();
              req.setAttribute("eleves", eleves);                                          notre Service !
              req.setAttribute("matieres", matieres);
         req.setAttribute("ecoles", ecoles);
         req.getRequestDispatcher("/WEB-INF/jsp/affichage.jsp").forward(req, resp);
     }
}

59
JEE - implementation JPA ... le DAO

public class DisplayService {
     private EntityManager em;

     public DisplayService(EntityManager em) {
          this.em = em;
     }
     public List findAllSchools() {
          Query query = em.createQuery("SELECT e FROM Ecole e");
          return (List) query.getResultList();
     }
     public List findAllStudents() {
          Query query = em.createQuery("SELECT e FROM Eleve e");
          return (List) query.getResultList();
     }
     public List findAllCourses() {
          Query query = em.createQuery("SELECT e FROM Matiere e");
          return (List) query.getResultList();
     }
}

60
JEE - implementation JPA ... la JSP 1/2

SHOW Template

Login

     ----- ECOLES -----
                
                            ID--
                            NAME---
                      
           ${ecole.id}${ecole.nom}
           
           ----- MATIERES -----
                
                            ID--
                            NAME---
                      
           ${matiere.id}${matiere.nom}
           
61
JEE - implementation JPA ... la JSP 2/2

----- ELEVES -----
                
                            ID--
                            NAME---
                            ECOLE---
                            MATIERE 1-
                            MATIERE 2-
                            MATIERE 3-
                      
           ${eleve.id}
           ${eleve.nom}
           ${eleve.ecole.nom}

          ${elevMat.nom}
JEE - la JSTL ou Java Standard Tags Library

●
     jeu de tags pour remplacer la plupart des constructions java
     dans les JSP
     ●
         exemple pour une boucle foreach, vu dans les pages précédentes :
         ●   
         ●   ${ecole.id}${ecole.nom}
         ●   

●
     travaille de très près avec l’expression language
●
     il faut insérer la ligne suivante en début du fichier
     ●
         jsp :
●
     insérer la bibliothèque JSTL dans le classpath

63
Utiliser MAVEN pour la création d’un projet Spring

Maven est un outil de gestion de dépendances et de build
spécifiquement créé pour java.
Un projet Maven est structuré et normé. Un fichier Pom.xml
définit les propriétés et les dépendances (librairies) dont a
besoin le projet pour compiler ou s’exécuter.
Arborescence d’un projet Maven       /src
                                          /main
                                                /java
                                                /resources
                                                /webapp
                                          /test
                                                /java
                                                /resources
                                     /target             // fichiers compilés
64
Utiliser MAVEN pour la création d’un projet Spring

Ensemble de tâches pour compiler ou préparer une librairie :
 ●
     compile
 ●
     clean
 ●
     test
 ●
     package
Les dépendances sont distribué à travers les repositories.
Repository central : https://mvnrepository.com/
Repository local : là où l’ensemble des dépendances sont téléchargées
lorsqu’on utilise un projet maven : C:\Users\xxx\.m2\repository

65
Spring - introduction

Spring est un framework open source pour le développement
d’applications java, qui n'est pas standardisé par le JCP (java
community process qui émet les JSR) ...
... mais est un standard de facto du fait de sa large utilisation.
Il permet d’intégrer les framework open source (Hibernate ...) et
les principales API java (Servlet, JMS ...)
Spring peut s’utiliser dans un simple conteneur web (Tomcat) ...
... car il utilise de simples POJO pour développer des
applications plutôt que d'utiliser des EJB dans un conteneur.

66
Spring - introduction

Le noyau de Spring est basé sur une fabrique générique de
composants informatiques (beans) et un conteneur capable de
stocker ces beans.

De plus, le noyau de Spring permet de forcer le contrôle de ces
composants de leur extérieur, par l’inversion de contrôle.

Le principal avantage est de composer les beans de façon plus
déclarative plutôt que de façon impérative dans le programme

67                                                   source wikipedia
Spring - l’inversion de contrôle

Spring s’appuie donc sur l’inversion de contrôle, assurée de deux
façons différentes : la recherche de dépendances et l'injection de
dépendances.
 Pour mémoire (NFP121), l’inversion de contrôle fournit un
moyen cohérent de configuration et de gestion des objets Java à
l'aide de l’introspection.

68
Spring - l’inversion de contrôle

●
     La recherche de dépendance consiste à interroger le conteneur,
     afin d’obtenir un objet avec un nom spécifique ou d'un type
     spécifique. C’est un cas de fonctionnement similaire aux EJBs.
●
     L’injection de dépendances - cette injection peut être effectuée
     de trois manières possibles :
     ●
         L’injection de dépendance via le constructeur.
     ●
         L’injection de dépendance via les modificateurs (setters).
     ●
         L’injection de dépendance via une interface.
Les deux premières sont les plus utilisées par Spring.

69                                                                    source wikipedia
Spring - l’inversion de contrôle

     Avec Spring, on ne crée pas directement d'objet, mais on décrit
     comment un objet doit être créé. Le framework se charge de la
     création.
     De même, les services et les composants ne sont pas appelés
     directement. Les services et les composants devant être
     appelés sont définit dans un fichier de configuration .
     L’inversion de contrôle est destinée à augmenter la facilité de
     maintenance et de test.

70
Spring - l’inversion de contrôle

Les annotations de Spring permettent de marquer des classes
comme beans, afin qu’ils soit reconnus comme tels par le
container et puissent être « injectés ».
Avec les annotations @Component, @Repository, @Service et
@Controller et l'analyse automatique des composants activée,
Spring importera automatiquement les beans dans le conteneur
et les « injectera » quand nécessaire.
L’annotation @Autowired gère le câblage. Elle est à placer au-
dessus de l’attribut à récupérer par injection dans une classe. Cet
objet devra avoir été annoté par l’une des annotations vues
précédemment.
71
Spring - l’inversion de contrôle

L'annotation @Component marque une classe java comme un
bean afin que le mécanisme d'analyse des composants de Spring
puisse la repérer et l'intégrer au contexte de l'application.
Les autres annotations sont des spécialisations de celle-ci pour
les DAO (@Repository), les services -« Business Service Facade »-
(@Service) et les contrôleurs (@Controller).
Elles permettent de préciser l’intention, et peuvent amener des
fonctionnalités supplémentaires, comme la gestion des
exceptions par DataAccessException pour @Repository, ou la
possibilité d’utiliser l’annotation additionnelle
@RequestMapping pour @Controller.
72
Spring - programmation orientée aspect

Ce type de programmation (AOP) permet de prendre en compte les
fonctionnalités transverses.
Par exemple, une couche logicielle dédiée à gérer la logique métier applicative
(par exemple un système bancaire), va se retrouver dépendante de modules
gérant les aspects transactionnels, de journalisation, etc. ; la croissance de ces
dépendances conduit à une complexification du code, de son développement et
de sa maintenance. La programmation par aspect va permettre d'extraire les
dépendances entre modules concernant des aspects techniques entrecroisés et
de les gérer depuis l'extérieur de ces modules en les spécifiant dans des
composants du système à développer nommés « aspects » ; ils sont développés à
un autre niveau d'abstraction (source wikipedia).
Spring va utiliser les concepts de la programmation par aspects via les notions
d’intercepteur et de coupe, notamment pour la mise en oeuvre des transactions.

73
Spring - la couche d’abstraction

La couche d’abstraction de Spring permet d’intégrer d’autres
frameworks et bibliothèques avec une plus grande facilité.
Grâce à cette couche, Spring ne concurrence pas d’autres
frameworks dans une couche spécifique d’un modèle
architectural MVC mais s’avère être un framework multi-couches
pouvant s’insérer au niveau de toutes les couches ; modèle, vue
et contrôleur. Ainsi il permet d’intégrer Hibernate pour la couche
de persistance ou encore JavaServer Faces (JSF)pour la couche
présentation.

74                                                   source wikipedia
Spring - modules

Spring fournit un ecosystème particulièrement riche avec plus
de 50 sous-projets :
Spring Boot : Spring Boot makes it easy to create stand-alone, production-grade Spring based
Applications that you can "just run".

Spring Data : Spring Data’s mission is to provide a familiar and consistent, Spring-based
programming model for data access while still retaining the special traits of the underlying data store.

Spring MVC : Spring Web MVC is the original web framework built on the Servlet API and has been
included in the Spring Framework from the very beginning.

Spring Security, Spring Websocket, Spring AMPQ, Spring Web
Services, Spring Kafka, Spring Cloud, Spring Mobile ...

75
Spring - Spring Boot
La configuration de Spring est particulièrement compliquée.
Spring Boot a donc été créé dans le but de faciliter la configuration d’un projet Spring et
de réduire le temps alloué à son démarrage.
Pour cela Spring Boot propose :
 ●
     Un site web (https://start.spring.io/) permettant de générer rapidement la structure d’un
     projet en y incluant toutes les dépendances Maven nécessaires.
 ●
     des « Starters » pour gérer les dépendances. Les dépendances Maven sont regroupées dans
     des « méga dépendances » afin de faciliter leur gestion.
 ●
     L’auto-configuration, qui applique une configuration par défaut au démarrage de
     l’application pour toutes dépendances présentes . Cette configuration s’active à partir du
     moment où l’application est annotée avec « @SpringBootApplication » (cette configuration
     peut-être surchargée). L’auto-configuration simplifie la configuration sans pour autant vous
     restreindre dans les fonctionnalités de Spring.
 ●
     possibilité d’intégrer directement un serveur Tomcat dans l’exécutable. Un Tomcat
     embarqué sera démarré au lancemenbt afin de faire tourner l’application.

76
Spring - architecture modèle web

          Front
        controller

77
Spring - Le POM Spring Boot
     
           4.0.0
           
                  org.springframework.boot
                  spring-boot-starter-parent
                  2.1.4.RELEASE
                   
           fr.cnam
           NSY102
           0.0.1-SNAPSHOT
                                                                                          généré via https://start.spring.io/
           jar
           NSY102                                                            ou via Eclipse
           Demo project for Spring Boot
                                                                                          pour les éléments pricipaux
           
                 1.8
           
                                                                                          (web, jpa, json, Thymeleaf)
           
                        org.springframework.boot
                        spring-boot-starter-data-jpa
                 
                        org.springframework.boot
                        spring-boot-starter-jdbc
                 
                        org.springframework.boot
                        spring-boot-starter-thymeleaf
                 
78
Spring - Le POM Spring Boot
                 
                        nz.net.ultraq.thymeleaf
                        thymeleaf-layout-dialect
                 
                        org.springframework.boot
                        spring-boot-starter-web
                 
                        com.h2database
                        h2
                        runtime
                 
                        com.fasterxml.jackson.dataformat
                        jackson-dataformat-csv
                 
                        org.webjars
                        bootstrap
                        4.3.1
                 
                        org.webjars
                        jquery
                        3.4.0
                 
                        org.springframework.boot
                        spring-boot-starter-test
                        test
                 
                              org.springframework.boot
                              spring-boot-maven-plugin
                        
79
Spring - arborescence Spring Boot

                     Fichier de config application.properties
                   # ===============================
                   # DATABASE
                   # ===============================
                   spring.datasource.driver-class-name=org.h2.Driver
                   spring.datasource.url=jdbc:h2:./db
                   spring.datasource.username=user
                   spring.datasource.password=user

                   # ===============================
                   # JPA / HIBERNATE
                   # ===============================
                   spring.jpa.show-sql=true
                   spring.jpa.hibernate.ddl-auto=update
                   spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

80
Spring - le fichier de lancement de Spring Boot

 Généré par Spring boot
regroupe les annotations :
●
  @EnableAutoConfiguration :           package fr.cnam.nsy102;
  permet le mécanisme d’auto-
                                       import org.springframework.boot.SpringApplication;
  configuration                        import
                                       org.springframework.boot.autoconfigure.SpringBootApplication;
●
  @ComponentScan : indique à
                                       @SpringBootApplication
  Spring dans quels packages           public class Nsy102Application {
  rechercher les beans (classes             public static void main(String[] args) {
                                                 SpringApplication.run(Nsy102Application.class, args);
  annotées)                                 }
                                       }
●
  @Configuration : Les classes où
  elle est apposée se substituent
  aux traditionnels fichiers de
  configuration XML. On y trouve la
  déclaration de beans Spring,
  l’import de fichiers ou de classes
  de configuration.

81
Spring - un 1er exemple

 un première appli web « Hello World ! »
annotation @Controller, le contrôleur MVC
            servlet en JEE
                               @Controller
                               public class SimpleController {
                                                                 annotation @RequestMapping,
                               @RequestMapping("/simple")        donne l’URL par laquelle on
                               @ResponseBody
                               public String simple() {          pourra invoquer l’action
                               return "Hello World !";
                               }
                               }
      annotation @ResponseBody
      signifie que le résultat s’affichera
      dans le corps de la page html

 82
Spring - un 2ème exemple

  url paramétrée avec @PathVariable
       ●
           pattern matching possible                              annotation @RequestMapping
                                                                  possible au niveau de la classe
                                   @Controller
                                   @RequestMapping("/hello")
                                   public class SimpleController {
                                                                          ... avec une spécialisation
                                        @RequestMapping("/simple")
                                        @ResponseBody                     au niveau des méthodes
 name est ici une variable              public String simple() {          ( ./hello/simple )
                                            return "Hello World !";
                                        }
                                        @RequestMapping("/details/{name}")
l’annotation @PathVariable signifie     @ResponseBody
                                        public String details(@PathVariable String name) {
que la variable de l’url est injectée       return "Hello "+name;
dans le paramètre de la méthode         }
et sera donc utilisable dans celle-ci
                                   }

  83
Spring - Femto Application

Nous allons construire une application très
basique, qui comprend une seule classe
métier, « article ».
Nous devrons pouvoir créer des articles,
les afficher, les supprimer, les mettre dans
notre panier (dans le cadre d’une session).
Classement de nos classes dans
l’arborescence selon leur typologie (métier,
contrôleur, service, dao)

84
Spring - Application : classe métier
                                              @Entity
               prise en charge par JPA        public class Article {

                          clé primaire            @Id
                                                  private String id;

                                                  private String name;

                                                  private double price;
Compte tenu de notre configuration                public String getId() {
                                                       return id;
(spring.jpa.hibernate.ddl-auto=update),           }
Spring créera la db si elle n’existe pas au       public void setId(String id) {
                                                       this.id = id;
lancement du programme.                           }
                                                  public String getName() {
                                                       return name;
                                                  }
                                                  public void setName(String name) {
                                                       this.name = name;
                                                  }
                                                  public double getPrice() {
                                                       return price;
                                                  }
                                                  public void setPrice(double price) {
                                                       this.price = price;
                                                  }
                                              }

85
Spring - Application : classe métier

public class Panier {
     private List articles;
     public Panier() {
         articles = new ArrayList();
     }
     public List getArticles() {
         return this.articles;
     }
     public void setArticles(List articles) {
         this.articles = articles;
     }
}

                  Le panier, que nous ne persisterons pas

86
Spring - Application : DAO
Interfaces Spring xxxRepository, spécifiques pour l’accès aux données via JPA.
Les repositories génériques fournis par Spring permettent de réaliser les opérations
courantes d’accès aux données.
On trouve notamment les Interfaces Repository, CrudRepository ...
Il suffit de créer une interface héritant d’un de ces repositories pour utiliser ses
méthodes, et en définir de plus spécifiques si nécessaire (en respectant les
conventions de nommage, par ex findByAttribut).
2 paramètres génériques : le type de l’entité et le type de sa clé primaire.
Le code sera généré par Spring Data à partir de notre interface, sans que nous ayons
à fournir nous mêmes l’implémentation !

           public interface ArticleRepository
           extends JpaRepository {}

87
Spring - application : business service facade

@Service                                             composant / bean de type service.
public class ArticleService {                        L’annotation permettra au bean d’être importé
     @Autowired                                      dans le conteneur et injectable à la demande
     private ArticleRepository articleRepository;

     @Transactional
     public Article enregistrer(Article article) {   injection du bean DAO
          return articleRepository.save(article);
     }

     @Transactional                                  méthode transactionnelle (cf slide suivante)
     public void supprimer(String id) {
          articleRepository.deleteById(id);
     }
     )
     public List lister() {
          return articleRepository.findAll();
     }

     public Optional trouver(String id) {
          return articleRepository.findById(id);
     }

}

88
Spring - Les transactions avec Spring Boot

La gestion des transactions est configurée par défaut avec Spring Boot, pour
autant qu’une dépendance de type « spring-data-* » soit dans le classpath.
L’annotation @Transactional au niveau d’une classe ou d’une méthode
(forcément public) suffira à la rendre transactionnelle.
L'annotation prend également en charge les configurations suivantes (entre
autres) :
 ●
     le type de propagation de la transaction (la propagation décrit ce qui se passe si une transaction
     doit être ouverte dans le cadre d'une transaction déjà existante).
 ●
     le niveau d'isolement de la transaction (l'isolement détermine entre autres si une transaction peut
     voir des écritures non validées d'une autre transaction)
 ●
     un indicateur readOnly (indicateur pour le fournisseur de persistance que la transaction doit être
     en lecture seule)
 ●
     les règles de roll-back pour la transaction

89
Spring - Application : un contrôleur 1/2
@Controller
public class ManageArticlesController {                           - composant / bean de type contrôleur.
       @Autowired                                                 - injection du bean Service
       ArticleService articleService;
                                                                  - annotation possible dans un bean de type Controller
       @GetMapping("/show")
       public String viewTemplate(Model model) {                  (= @RequestMapping + méthode HTTP GET)
             List catalog = articleService.lister();
             model.addAttribute("catalog", catalog);
                                                                  - appelle ShowCatalog.html
             return "showCatalog";
       }
                                                                  - Model = objet permettant de transmettre des
       @GetMapping("/new")
       public String createArticle(Model model) {                 paramètres à la vue
             model.addAttribute("article", new Article());
             return "createArticle";
       }
                                                                  - paramètre de l’URL transmis à la méthode
       @GetMapping("/delete/{id}")
       public String deleteArticle(@PathVariable String id) {
             articleService.supprimer(id);                        - ModelAttribute = indique que l'argument doit être
             return "redirect:/show";
       }                                                          extrait du modèle. Ici, article est rempli avec les
       @PostMapping("/new")                                       données du formulaire transmis
       public String newArticle(@ModelAttribute Article article, Model model) {
             if (article.getId() != "" && article.getId() != null && article.getName() != "" && article.getName() != null
                         && article.getPrice() != 0.0) {
                   articleService.enregistrer(article);
             } else {
                   model.addAttribute("error", true);
                   return "createArticle";
             }
             return "redirect:/show";                                - redirige vers l’URL /show, càd appelle la méthode
       }
                                                                  ViewTemplate de ce contrôleur

  90
Spring - Application : un contrôleur 2/2
         @GetMapping("/addToBasket/{id}")
         public String addToBasket(HttpSession session, @PathVariable String id) {
              Double totalPrice = 0.0;
              Panier monPanier = (Panier) session.getAttribute("panier");
              if (monPanier == null) {
                    monPanier = new Panier();
                    session.setAttribute("panier", monPanier);                       injection de l’objet session ...
              }
              Article art = articleService.trouver(id).get();
              monPanier.getArticles().add(art);
              for (Article a : monPanier.getArticles()) {                            ... auquel on ajoute des
                    totalPrice += a.getPrice();
              }                                                                      attributs qui survivront tout au
              session.setAttribute("totalPrice", totalPrice);
              session.removeAttribute("emptyBasket");
                                                                                     long du cycle de vie de l’objet
              return "redirect:/show";
         }

         @GetMapping("/removeFromBasket/{index}")
         public String removeFromBasket(HttpSession session, @PathVariable int index) {
              Double totalPrice = 0.0;
              ((Panier) session.getAttribute("panier")).getArticles().remove(index);
              Panier monPanier = (Panier) session.getAttribute("panier");
              for (Article a : monPanier.getArticles()) {
                    totalPrice += a.getPrice();
              }
              session.setAttribute("totalPrice", totalPrice);
              if (totalPrice == 0)
                    session.setAttribute("emptyBasket", "yes");
              else
                    session.removeAttribute("emptyBasket");
              return "redirect:/show";
         }
}

    91
Spring - Application : un contrôleur REST

                                                  annotation qui combine @Controller et @ResponseBody, et
                                                  nous évite ainsi de devoir annoter chaque méthode de la
@RestController                                   classe avec l’annotation @ResponseBody
public class ArticlesRestController {

         @Autowired
         ArticleService articleService;

         @GetMapping(path="/showJson", produces = MediaType.APPLICATION_JSON_UTF8_VALUE )
         public List viewJson(Model model) {
              List catalog=articleService.lister();
              return catalog;
         }

         @GetMapping(path="/showJson/{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE )
         public Article viewSingleJson(@PathVariable String id) {
              Article article = articleService.trouver(id).get();
              return article;
         }
}
                                                              « produces » donne le type du contenu produit
                                                              par la méthode (type JSON ici)

    92
Spring - Application : default.html

NSY102

              NSY102
       
              Cnam 2019 
       
93
Spring - Application : CreateArticle.html

                                   fichier messages.properties

                   article.id= ID de l'article
                                                                                article.name= Nom de l'article
                                                                                 article.price= Prix de l'article
                                               article.error=Tous les champs doivent être complétés
             basket.empty=Votre panier est vide
             
                                  Article id
                                  
                                  Article name
                                  
                                  Article price
                                  
                           SEND
                    
94
Spring - Application : showCatalog.html

table {
       font-family: arial, sans-serif;
       border-collapse: collapse;
       width: 100%;
}
td, th {
       border: 1px solid #dddddd;
       text-align: left;
       padding: 8px;
}
tr:nth-child(even) {
       background-color: #dddddd;
}

              ----- CATALOGUE -----
              
                           ID
                           NAME
                           PRICE
                           REMOVE
                           BASKET +
                    
                           59.9
                           Supprimer
                           ajouter au panier
                    
95
Spring - Application : showCatalog.html

                       ----- PANIER -----
                       
                                    ARTICLE
                                    BASKET -
                             
                                    retirer du panier
                             
                       Prix total
                       
                        € H.T.
                
96
JEE - SPRING

               THE END

97
Vous pouvez aussi lire