Académique Documents
Professionnel Documents
Culture Documents
anne
Prsentation
Services mtier
Persistance
Prsentation
Interface utilisateur pour interagir avec l'application
Interface classique type GUI (ex : traitement de texte) Interface Web, plus lgre
Persistance
Enregistrement sur support physique des donnes de l'application
Simple Avec redondance pour fiabilit Multiples : fdration de bases de donnes ...
Services mtier
Intgre la logique mtier
Ex: un document est compos de sections, elles mmes composes de sous-sections ... Ex: crer un document, le modifier, ajouter des sections, l'enregistrer ...
Partieapplicative Sont intgres et cooprent pour le fonctionnement de l'application En anglais, on les appele aussi des tiers (tages)
Trois parties
Modle centralis
Architecture 2 tiers
Architecture 2 tiers
Ex : traitement de texte avec serveur de fichiers distants Ex : application accdant une BDD distante
La partie client ne gre que l'interface utilisateur L'interface utilisateur peut mme tre excute sur le serveur
Fonctionnement mode terminal / mainframe L'utilisateur a simplement devant lui cran / clavier / souris pour interagir distance avec l'application s'excutant entirement sur le serveur
Architecture 2 tiers
Prsentation Client
Prsentation Client
Persistance
Serveur 7
Architecture 2 tiers
Prsentation
Persistance
Client
Architecture 3 tiers
Architecture 3 tiers
Les 3 principaux tiers s'excutent chacun sur une machine diffrente Prsentation
Machine client Serveur d'applications Serveur de (base de) donnes Services Mtiers Serveur applicatif Persistance Serveur 9 donnes
Applicatif / mtier
Persistance
Prsentation Client
Architecture 3 tiers
Trs dveloppe de nos jours
Avec gnralement un fonctionnement au dessus du Web Navigateur web sur machine cliente
Couche prsentation
Client lger
Serveur HTTP excutant des composants / lments logiciels qui gnrent dynamiquement du contenu HTML Via des requtes des BDD distantes
Couche persistance
10
Architecture n tiers
Architecture n tiers
Rajoute des tages / couches en plus La couche applicative n'est pas monolitique
Service mtier utilise d'autres services mtiers Les services mtiers peuvent aussi s'appuyer sur des services techniques
Composition verticale
Architecture n tiers
Rutilisation de services existants Dcouplage des aspects mtiers et technique et des services entre eux : meilleure modularit Facilite volution : nouvelle version de service Facilite passage l'chelle : volution de certains services On recherche en gnral un couplage faible entre les services
Permet de faire voluer les services un par un sans modification du reste de l'application
Inconvnients
En gnral, les divers services s'appuient sur des technologies trs varies : ncessite de grer l'htrognit et l'interoprabilit Utilisation de framework / outils supplmentaires Les services tant plus dcoups et distribus, pose plus de problmes lis la distribution
12
Logique de prsentation
Ralise par la GUI d'un client lourd : boutons, listes, menus, ... Ralise par le navigateur pour un client web
Via interaction plus basique : formulaires, liens vers des URLs ...
La logique de prsentation
Le traitement des donnes retournes par les services mtiers et leur prsentation destination de l'utilisateur Ralise par un client lourd qui gnralement fait directement l'appel des services mtiers sur le serveur Pour un client web
Navigateur se contente d'afficher du code HTML qui ne peut pas tre statique ici vu que le contenu dpend des donnes retournes Doit donc excuter du code qui rcupre les donnes retournes par les services mtiers et gnre dynamiquement du code HTML Logique de prsentation peut tre excute cot client ou cot serveur mais se fait gnralement dans un tiers part cot serveur
13
Persistance
Couche de persistance
Stockage et manipulation des donnes de l'application Plusieurs supports physique
Fichiers binaires, textes de base Fichiers XML Une base de donnes ou un ensemble de bases de donnes Ncessit d'envoyer distance des requtes (types SQL) et d'en rcuprer les rsultats Pour raliser cela
Soit c'est natif dans le langage utilis (ex : PHP) Soit on passe par des frameworks ou des API ddis
14
Persistance
RDA (Remote Data Access) de l'ISO ODBC (Open Data Base Connectivity) de Microsoft JDBC (Java Data Base Connectivity) de Sun
Fonctionnement gnral
Gestion de requtes SQL mais avec indpendance du SGBDR utilis (mySQL, PostgreSQL, Oracle ...) En gnral, seule la phase de connexion au SGBDR est spcifique
Exemples : Hibernate (Sun, J2EE), NHibernate (libre, pour .Net) Principe gnral
On dfinit de manire abstraite (via XML par exemple) la structure des donnes manipuler L'outil gnre un ensemble d'oprations de manipulation de donnes (en java par exemple) utilisable dans un programme 15 L'outil fait en interne le lien avec le support physique (SGBDR ...) considr
Frameworks globaux
Prsentation : HTML, GUI ... Applicatif : objets, composants, scripts excutables, services ... BDD : fichiers XML, SGBDR, ... Protocoles de communication : RPC / RMI, HTTP
J2EE / Java EE chez Sun .Net chez Microsoft Serveur permettant d'excuter les parties applicatives dans le contexte de ces framewoks
Serveur d'application
16
Sun J2EE
Norme / standard dfini par Sun pour le langage Java Technologies intgres
Composants logiciels : EJB Applications orientes Web : JSP, servlet Communication distance : Java RMI, IIOP, JMS (Java Message Service : communication par message), Web Services Gestion donnes distantes : JDBC, JPA (Java Persistance API) Gestion d'annuaires (type LDAP) : JNDI Transactions : JTA Et bien d'autres ...
Versions libres
GlassFish, JBoss, Apache Geronimo, Jonas ... Versions d'diteurs Sun Java System Application Server (bas sur GlassFish), IBM17 WebSphere, BEA WebLogic, Oracle Container for Java EE, ...
Microsoft .Net
Particularit : multi-langage
Permet interoprabilit d'lments crits en C, Java, C#, J#, Eiffel, VB, ... (plus de 20 langages) Traduction en code intermdiaire (MSIL) qui sera excut par la couche CLR (Common Language Runtime)
Cot Java, c'est le code Java qui tait converti en byte code excut par la machine virtuelle Java (JVM)
La principale mise en oeuvre est bien sr de Microsoft et pour Windows, mais il existe quelques versions libres (implmentations souvent partielles)
Technologies intgres
18
Logique applicative
Ralise par composants EJB Communication via Hibernate ou JDBC pour attaquer BDD distante Avec client lger ou client lourd Client lger : navigateur web
Prsentation
Intrt : simplifie la prsentation (suffit d'un navigateur) Inconvnient : limite de l'interaction via HTML Application standard cot client, gre la logique de prsentation Intrt : plus grande possibilit en terme de prsentation et d'interaction Inconvnient : ncessite un dveloppement ddi via des API de widgets
Client lourd
19
logique mtier
21
Technologies Web
Prsentation
Affichage document HTML + feuilles de styles S'excute dans un navigateur web : client lger Interaction avec l'utilisateur via des formulaires (listes, entres texte, boutons ...) et liens But : produire un contenu HTML
Applicatif
Selon les choix de l'utilisateur Selon les donnes afficher Ncessite d'xecuter du code qui va gnrer ces pages 22
Technologies Web
Le client tlcharge partir du serveur du code qui s'excute dans le navigateur du client Exemple : applet Java
Excution d'un programme Java (d'une forme particulire) au sein du navigateur Tlchargement peut tre lourd : chaque client doit tlcharger le code Problme de scurit car on excute localement du code venant d'un lment distant
Problmes
Du code est excut cot serveur pour gnrer de manire dynamique la page HTML qui sera envoye au client 23 On va s'intresser ce type d'excution dans ce cours
Langages de scripts
Partie statique : balises HTML standards avec contenu textuel Partie dynamique : du code crit dans un langage de script Ce code gnre du code HTML standard
La page entremelle les parties statiques et dynamiques Quand un navigateur demande le contenu d'une page
La partie dynamique est excute et remplace par le HTML gnr Le navigateur du client reoit donc uniquement du code HTML
Un programme complet s'excute et gnre du contenu HTML La page est entirement dynamique
Plus prcisment : les partie statiques existent mais elles sont intgres dans le code, pas crites directement en HTML standard
24
Exemples de technologies
Langages de script
PHP
Langage interprt offrant l'avantage d'intgrer nativement les primitives de requtes SQL sur des BDD ASP et ASP .Net Solutions Microsoft JSP (Java Server Page) Solution Sun pour Java
Excution de programmes
Historiquement, une des premires solutions Solution Sun pour Java : excution de code Java respectant 25 certaines caractristiques
Servlet
Plateforme d'excution
Dans tous les cas, il faut pouvoir excuter du code et communiquer via HTTP avec le navigateur cot client Deux composants pour gnration de pages dynamiques
Serveur HTTP standard Elment (conteneur) d'excution des programmes ou des scripts
Microsoft IIS
26
Servlet
Classe standard du point de vue de son contenu en terme d'attributs, mthodes ... Mais excution et interactions diffrentes d'un objet Java standard
Pas d'appel de constructeur, pas de main() A la cration de la servlet par le serveur d'excution
Appel par le serveur d'excution de la fonction init(ServletConfig) On peut y faire les actions qu'on ferait dans un constructeur Appel par le serveur d'excution de destroy() A redfinir si on veut effectuer certaines actions la suppression de la servlet
27
Servlet
A chaque requte correspond une mthode doXXX(...) hrite de la classe HttpServlet et qui sera appele selon la requte client
On rdfinit ces mthodes pour y placer le code excuter par la servlet En pratique, pas besoin de redfinir toutes les mthodes (GET et POST minimum) De manire plus gnrale (mais moins recommande), la mthode service(...) reoit toutes les requtes et peut tre redfinie directement (par dfaut elle redispatche aux doXXX(...) )
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException request : contient la description de la requte du client response : utiliser pour envoyer la rponse au client 28 Toutes les mthodes doXXX(...) ont la mme signature
HttpServletRequest request
Initialis par l'appel du client (le navigateur) Donnes / informations sur la requte envoye par le client On peut y rcuprer notamment
Valeurs entres pour un formulaire Une session pour grer un tat ddi chaque client Cookies du client envoys avec la requte Informations sur l'URL utilise pour l'appel de la servlet Login de l'utilisateur s'il s'est identifi Et de manire plus gnrale, tous les headers de l'appel
Identifiants du navigateur, type de requte (GET, PUT ...), type d'encodage support par le navigateur, ...
29
HttpServletResponse response
A initialiser et utiliser par la servlet pour gnrer le rsultat envoyer au navigateur client Dfinir le type MIME des donnes envoyes
Gnralemet du code HTML response.setContentType("text/html;charset=UTF-8"); Mais peut utiliser n'importe quel type MIME : image/gif, audio/mp3, application/pdf, ...
PrintWriter getWriter()
Flux texte, typiquement pour du HTML Flux binaire pour des images, vidos ...
ServletOutputStream getOutputStream
Cr un nouveau cookie (ou modifier un existant) Ajouter un header aux donnes envoyes
30
Une servlet n'est cre qu'en une seule instance Si plusieurs clients accdent l'URL d'une mme servlet
Appelle les mthodes sur cette instance unique Cet tat est permanent et conserv (tant que la servlet existe) Il est accd / modifi par tous les clients : tat global
On peut lui associer des donnes via des couples cl (chaine) / objet
La session a une dure de vie configurable Exemple typique d'utilisation d'une session
Panier d'un utilisateur sur un site de vente en ligne : conserve les produits choisis par l'utilisateur pendant son parcours sur le site
31
Gnre une page qui affiche hello word Gre et affiche un compteur qui est incrment chaque accs la servlet Le code qui suit a t cr sous Netbeans qui gnre un squelette de code
Ce squelette contient une mthode principale processRequest() qui contiendra le code principal de la servlet Les mthodes hrites doGet() et doPost() appellent directement cette mthode processRequest() avec les mmes paramtres
Une fois dploye sur le serveur, on accde une servlet via une URL HTTP
La notre est contenue dans le fichier HelloWorld.java URL sera de la forme : http://www.xxxxxx.fr/XXX/HelloWorld Note : peut choisir une URL d'accs la servlet diffrente 32
33
} }
Exemple d'excution
Aprs 4 chargements de la servlet compteur passe 5
34
Code prcdent
Le compteur est global : commun tous les clients Passer par les donnes qu'on peut associer une session Modification de processRequest()
try { // rcupre la session associe au client HttpSession session = request.getSession(true); // rcupre le compteur associ la session Integer compteur = (Integer)session.getAttribute("compteur"); // si valeur null : attribut compteur n'existe pas, a signifie // que c'est la premire excution par le client, il faut crer le compteur if (compteur==null) { compteur = new Integer(1); session.setAttribute("compteur", compteur); // configure pour qu'une session dure 10 secondes max session.setMaxInactiveInterval(10); } (...) out.println("<p>Nombre d'appels : "+compteur+"</p>"); (...) // incrmente le compteur 35 session.setAttribute("compteur", new Integer(compteur.intValue()+1));
Autre exemple
Cration d'un rectangle Dcalage du rectangle courant (non prsent en dtail pour gagner de la place) Calcul de la surface du rectangle courant
Implmentation
appeler la servlet avec ces paramtres Note : dans l'exemple, c'est une page JSP mais c'est du HTML standard, aucun code Java n'est inclus dans la page
Servlet
Une servlet gre le rectangle et excute les 3 oprations en fonction des paramtres venant du formulaire On rcupre ces paramtres via : request.getParameter(nomParam) 36
<p><input type="radio" name="action" value="creer" checked="checked" /> Crer Rectangle<br /> <input type="radio" name="action" value="decaler" />Dcaler Rectangle<br /> <input type="radio" name="action" value="surface" />Calcul Surface</p> <p><input type="submit" value="Excuter"> <input type="reset" value="Remise zro></p> </form> </body> </html>
37
Une action associe qui est l'appel de la servlet RectServlet 4 champs d'entre de noms x1, y1, x2, y2 Une liste de boutons radio dont selon le choix, on aura le paramtre action gal creer, decaler ou surface On rcupre ces 5 paramtres dans request Notamment le paramtre action qui prcisera quelle opration on veut appeler La servlet conservera le dernier rectangle cr (avec un premier rectangle dfini par dfaut) et les fonctions de dcalage et de surface seront appeles sur ce rectangle Pour simplifier, on met les fonctions mtiers (manipulation de rectangles) directement dans le code de la classe 38 de la Servlet
39
40
catch (Exception e) { // en cas de problme, affiche un message out.println("<p><b>Erreur !!</b><br />"); out.println(e.toString()+"</p>"); } // fin du document : lien pour retour en arrire out.println("<p><a href=\""+request.getContextPath()+"\"> Retour</a></p>"); out.println("</body>"); out.println("</html>"); 41 out.close(); }
42
43
Slection de retour pour revenir la page HTML puis choix de calcul surface
44
45
Les parties statiques Les parties en Java remplaces par le code HTML qu'elles ont gnres Le serveur d'excution de la JSP la traduit d'abord en une servlet complte quivalente et c'est cette servlet qui est 46 excute
En pratique
out : flux de sortie texte dans lequel on crit le code HTML gnr par les parties de code Java request : paramtres de l'appel de la JSP / Servlet response : pour renvoyer la rponse au client session : la session spcifique au client courant config : configuration de la JSP page : l'instance de la JSP / Servlet (quivalent du this) exception : l'exception qui a t leve en cas de problme application : donnes communes toutes les JSP du serveur pageContext : contexte de la page (gestion d'attributs ...) 47
Trois balises <% ... %>, <%! ... %> et <%= ... %> Peut insrer plusieurs de ces balises dans une mme page JSP JSP compile en Servlet donc unicit de la JSP galement Dclaration d'attributs et de mthodes Ils seront globaux tous les appels de la JSP pour tous les clients Scriplet : suite d'instructions Java qui sera excute chaque appel de la page JSP Si on y dclare des attributs, ils sont locaux chaque appel Evalue le expr et affiche le rsultat dans le code HTML Equivalent de <% out.print(expr) %>
Point important
48
A utiliser si les valeurs par dfaut de la page sont modifier <%@ page import = java.util.Vector %> Par dfaut du text/html <%@ page contentType = ''image/png'' %> Excuter une JSP en cas d'erreur rencontre
49
Gestion d'un compteur local et d'un compteur global d'appel Affichage de ces 2 compteurs (via mlange code statique et dynamique)
Implmentation
Trois insertions de code Java pour grer les compteurs
1. <% ...%> : dclaration du compteur local 2. <%! ... %> : dclaration du compteur global et d'une mthode d'incrmentation de ce compteur 3. <% ... %> : incrmentation des 2 compteurs Puis affiche via des <%= ... %> les valeurs des compteurs 50
Lgende couleur : - Code excut localement - Code dclar globalement - Evaluation de la valeur des attributs - Code HTML statique
51
Exemple d'excution
Aprs 4 chargements de la servlet compteur global passe 5 mais le local est systmatiquement 1
52
Aurait pu remplacer incGlobalNb(); par directement globalNb++; Les attributs et mthodes dclares en global sont tous accessibles directement
Ne peut par contre pas dclarer une mthode pour incrmenter le compteur local
void incNbLocal { nbLocal++; } Ne peut pas dclarer de mthode dans une balise <%! ... %>
Ne contient qu'une suite d'instructions excuter L'attribut nbLocal est local et n'est pas connu dans le code global
Ne peut pas dclarer cette mthode dans la balise <% ... %>
53
54
%>
<form action="rectangle.jsp" method="post"> <p> <table border="0"> <tr> <td>X1 ou X dcalage</td> <td><input <tr> <td>Y1 ou Y dcalage</td> <td><input <tr> <td align="right">X2</td> <td><input <tr> <td align="right">Y2</td> <td><input </table></p>
<p><input type="radio" name="action" value="creer" checked="checked" /> Crer Rectangle<br /> <input type="radio" name="action" value="decaler" />Dcaler Rectangle<br /> <input type="radio" name="action" value="surface" />Calcul Surface</p> 55
56
request : pour rcuprer les paramtres passs avec getParameter() out : flux de sortie pour gnrer du code HTML Utilisation du out comme avec une servlet Utilisation d'une balise <%= ... %> dans du code HTML
57
On va remplir les 4 champs avec valeurs 45, 12, 59, 47 58 et lancer l'excution de crer rectangle
59
60
Excution concurrente
Servlet / page JSP est unique Serveur HTTP peut avoir plusieurs requtes d'accs la servlet/JSP par plusieurs clients la fois
Excution multi-threade par le serveur HTTP Plusieurs threads peuvent donc excuter en mme temps du code de la mme servlet/JSP
Servlet
Implmentation de l'interface (vide) SingleThreadModel public class MaServlet extends HttpServlet implements SingleThreadModel Passe par les paramtres gnraux de la page : isThreadSafe <%@ page isThreadSafe="true" %>
JSP
Communication inter-lments
Chaque servlet / JSP possde un tat global ou un tat local pour chaque client
Peut aussi vouloir avoir un tat global toutes les pages JSP ou les servlets gres par le serveur HTTP
Permet de dfinir des attributs comme pour une session, mais communs toutes les pages JSP gres par le serveur HTTP Exemple : code Java pour grer un compteur commun toutes les pages JSP
<% Integer compteur = (Integer)application.getAttribute("compteur"); if (compteur==null) { // on cre le compteur qui n'existait pas compteur = new Integer(0); application.setAttribute("compteur", compteur); out.println("<p>Cration du compteur ...</p>"); } application.setAttribute("compteur", ++compteur); 62 out.println("<p>Compteur global : "+compteur+"</p>"); %>
Communication inter-lments
public class Compteur { protected static int compteur = 0; public synchronized static int nextValue() { return ++compteur; } }
On accde par exemple au compteur global dans une servlet ou une page JSP
63
D'appeler une autre servlet ou page JSP pour dlguer le traitement de la requte ou inclure un rsultat supplmentaire dans celui de la servlet/page JSP courante Servlet
Fait suivre le traitement de la requte ou inclus un traitement ralis par la servlet maServlet
Page JSP
<jsp:include page=''maPage.jsp''></jsp:include>
En cas d'erreur dans une page JSP, peut aussi excuter une page JSP particulire
Dans la page, insrer une redirection en cas d'erreur
<%@ page errorPage=''erreur.jsp'' %> En cas d'exception leve par une instruction Java, la page erreur.jsp est alors excute Prciser que l'on est une page d'erreur
Dans erreur.jsp
<%@ page isErrorPage=''true'' %> <p>Exception leve : <%= exception %> </p> L'attribut implicite exception est une exception Java classique, on peut appeler dessus des mthodes comme getMessage(), getCause(), printStackTrace(), ... 65
Dans une JSP, une part importante du code est ddie simplement afficher le contenu d'objets
Mme avec des <%= ... %> a peut tre relativement lourd raliser Reprenons notre manipulation de rectangles
Exemple
La servlet RectServlet gre le rectangle courant et excute les actions associs Une page HTML affiche un formulaire pour rentrer les diffrents champs Si l'utilisateur veut modifier une des 4 valeurs de coordonne (y1 par exemple) du rectangle courant, il doit rentrer les 4 valeurs On pourrait remplir par dfaut les 4 champs avec le contenu du rectangle courant 66
Transforme la page HTML associe en page JSP pour pouvoir rcuprer le rectangle associ la session
<%@page import = "rect.Rectangle" %> <% Rectangle rect =(Rectangle) session.getAttribute(''rectangle''); %> <h1>Manipulation de rectangle avec une servlet</h1> <form action="RectServlet" method="post"> <p> <table border="0"> <tr> <td>X1</td> <td><input name="x1" value="<%=rect.getX1() %>"></td> </tr> (...) On rcupre l'attribut rectangle associ la session On s'en sert pour mettre une valeur par dfaut dans les champs d'entre des 4 valeurs de coordonnes
68
Au premier chargement de la JSP, aucun appel n'a encore t fait sur la Servlet : pas d'attribut rectangle associ la session
L'attribut rect vaut donc null et <%= rect.getX1() %> lve une exception <%@page import = "rect.Rectangle" %> <% Rectangle rect = (Rectangle) session.getAttribute(''rectangle''); String x1 = '''', x2= '''', y1 = '''', y2 = ''''; if (rect != null) { x1 = new Integer(rect.getX1()).toString(); (...) } %> <h1>Manipulation de rectangle avec une servlet</h1> <form action="RectServlet" method="post"> <p> <table border="0"> <tr> <td>X1</td> <td><input name="x1" value="<%= x1 %>"></td> 69 (...)
Expression UEL (Unified Expression Language) Simplifie l'accs aux attributs (dans le sens des attributs associs une session)
La page JSP devient tout simplement <h1>Manipulation de rectangle avec une servlet</h1> <form action="RectServlet" method="post"> <p> <table border="0"> <tr> <td>X1</td> <td><input name="x1" value='' ${sessionScope.rectangle.x1}''></td>
(...)
Le champ d'entre X1 est initialis par le contenu de la proprit x1 de l'attribut rectangle associ la session Si l'attribut rectangle n'existe pas, ne gnre pas d'erreur, retourne simplement une chaine vide
70
Attributs de la session, de l'application, du header ou de la requte HTTP ... Addition, multiplication, modulo ...
Ensembles de balises offrant des fonctionnalits pour manipuler des fichiers XML, accs des BDDs, l'internationalisation ... Ensemble core permet notamment de manipuler simplement des ensembles de donnes, faire des tests et d'associer des balises HTML (ou autres) ces traitements ... Facilite grandement dans une page JSP l'affichage de donnes 71 retourns par la logique mtier
Attribut
Instance d'une classe Java respectant quelques contraintes structurelles : Java Beans
On peut ensuite accder aux proprits des attributs via une notation pointe partir d'un certain contexte
Exemple : sessionScope.rectangle.x1
Contexte : sessionScope Attribut : rectangle Proprit : x1 ((Rectangle)sessionScope.getAttribute(''rectangle'')).getX1() On voit bien l'obligation d'avoir un getter/setter associ chaque proprit pour pouvoir y accder
Si l'attribut ou une de ses proprits n'est pas dfinie (valeur null) 72 gnre une chane vide
pageScope : la page JSP requestScope : la requte HTTP sessionScope : la session associe avec le navigateur client applicationScope : contexte global toutes les pages JSP du serveur
73
Accde aux donnes d'un tableau (array, list ...) ou d'une map via une notation indexe
att[index]
Avec index qui est soit la cl pour une map, soit l'index pour un tableau Peut aussi tre le contenu d'une variable Pour un tableau, peut utiliser un index sous forme d'entier ou de chaine
Rectangle rect1 = new Rectangle(10,10,20,20); Rectangle rect2 = new Rectangle(30, 30, 50, 50); HashMap<String, Rectangle> mapRect = new HashMap<String, Rectangle>(); Rectangle[] arrayRect = new Rectangle[2]; int index = 1; mapRect.put("premier",rect1); mapRect.put("second", rect2); arrayRect[0] = rect1; arrayRect[1] = rect2; session.setAttribute("mapRect", mapRect); session.setAttribute("arrayRect", arrayRect); session.setAttribute("index", index);
74
<p> Map -> "premier" : ${sessionScope.mapRect["premier"].x1}<br /> Map -> 'second' : ${sessionScope.mapRect['second'].x1}<br /> Map -> "troisieme" : ${sessionScope.mapRect["troisieme"].x1}<br /> Array -> 0 : ${sessionScope.arrayRect[0].x1}<br /> Array -> '1' : ${sessionScope.arrayRect['1'].x1}<br /> Array -> 2 : ${sessionScope.arrayRect[2].x1}<br /> Array -> index : ${sessionScope.arrayRect[sessionScope.index].x1}<br /> </p>
Affichage rsultant
Map -> "premier" : 10 Map -> 'second' : 30 Map -> "troisieme" : Array -> 0 : 10 Array -> '1' : 30 Array -> 2 : Array -> index : 30
Si des lments dans la map n'existent pas ou si on dpasse75 l'index max du tableau, renvoie une chaine vide
UEL : oprateurs
Oprateurs logiques
&& (ou and), || (ou or), ! (ou not) == (ou eq), != (ou ne), > (ou gt) ... +, -, *, / (ou div), % (ou mod) Types de nombre disponibles : entier et rel empty : renvoie vrai si valeur vide
Egale null, chaine vide, un tableau vide ou une map vide ? : choix conditionnel 76 test ? choixVrai : choixFaux
Divers
Pour utiliser du JSTL core dans une page JSP, insrer la balise suivante dans la page
JSTL : core
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> Au dploiement, ne pas oublier le lien vers la librairie (.jar) externe implmentant cet ensemble de balises <c:out value=''valeur'' /> <c:if test=''condition''> ... </c:if> <c:choose> <c:when test=''condition1''> ... </c:when> <c:when test=''condition2''> ... </c:when> ... <c:otherwise> ... </c:otherwise> </c:choose>
Choix conditionnels
77
JSTL : core
JSTL : core
Exemple
<c:if test="${empty sessionScope.arrayRect[2].x1}"> Pas d'lment d'index 2 dans le tableau<br /><br /> </c:if> Surface des rectangles :<br /> <c:forEach items="${sessionScope.arrayRect}" var="rect"> -> <c:out value="${(rect.x2 - rect.x1) * (rect.y2 - rect.y1)}"/><br /> </c:forEach>
Affichage rsultant
Pas d'lment d'index 2 dans le tableau Surface des rectangles : -> 100 -> 400
79
Servlet vs JSP
Servlet
C'est du java standard qui est excut Les lignes out.println() servent gnrer le code HTML qui sera affich Problme : une bonne partie de ce code HTML est statique
Page JSP
Permet de mlanger du code HTML standard avec du Java standard Meilleure dcoupage des diffrentes parties qu'avec des servlets Moins lourd programmer qu'une servlet
Simplification des affichages des donnes, surtout si combin avec UEL et JSTL Mais moins structur du point de vue du code Java
80
Servlet et JSP
Servlet / JSP
Technologie cot serveur permettant donc la gnration dynamique de page HTML Intrt est de profiter de la puissance d'un langage Objet Le code embarqu dans les Servlet / JSP n'intgre pas de prfrence le code et la logique mtier
En pratique
On s'appuie sur d'autres lments (composants EJB par exemple) Logique de prsentation
Manire de prsenter et de gnrer les pages aux clients Appele par la logique applicative pour gnrer les pages
Logique mtier
81
82
Problmatique
Classe qui contient les informations sur une personne public class Personne { String nom; Int age; } Lors du stockage d'une personne, on lui associera un identifiant unique // mthodes d'accs aux attributs age et nom
83
Problmatique
Problmatique
85
Problmatique
On accde aux lments du ResultSet en naviguant selon les lignes et les colonnes Peu pratique mais difficile de faire autrement vu ce que retourne de manire native les requtes SQL
86
Problmatique
Qui complexifie forcment les choses mais ne peut pas y couper Cot BDD
Structure en table avec langage de requte ddi Rcupre toujours une sous-table via le rsultat de l'excution d'une requte de type SELECT Instances de classe (Personne ici) : objets Les objets sont associs entre eux et forment un graphe d'objet dans l'application
Cot Java
?
87
Problmatique
Solution
Comme pour notre exemple Cot BDD, la structure de stockage intgrera des concepts objets Passage plus facile du programme au stockage dans la base Mais toujours besoin de faire des requtes explicites 88
Framework de persistance
Principes
S'abstraire des problmatiques de stockage des donnes
Pouvoir manipuler directement des entits mtiers indpendamment de leur stockage physique La structure des classes utilises dans l'application Le stockage physique utilis par le support de persistance
Cration, suppression, manipulation, collections d'objets ... grs de manire classique, programmation standard Le framework fait le lien entre le graphe d'objet en mmoire dans l'application et le stockage physique
Typiquement : envoi de requte SQL au SGBD pour rcuprer des donnes, les modifier, les ajouter / supprimer
89
Framework de persistance
Plus besoin de se proccuper du stockage physique et des problmes de correspondance Comme on le voit dans notre exemple de l'atelier
Ecriture des requtes SQL via JDBC est assez lourd L'implmentation des accs aux donnes peut reprsenter un temps important lors du dveloppement d'une application
Hibernate
Standard de fait, trs utilis dans l'industrie Utilis galement par JPA (framework standard de persistance sous Java Java Persistence API)
90
Hibernate
Principes gnraux d'Hibernate
Dfinition des structures de donnes / entits manipules
Classe Java totalement standard avec dfinition d'attributs, d'accesseurs, de constructeurs pour gestion donnes de l'entit Ne s'appuie donc pas sur des frameworks ou librairies particuliers, contrairement par exemple aux entits d'EJB
Persistante : son contenu est li avec les donnes physiques sur la BDD et est sauvegard dans cette BDD Dfinition, en XML, d'un ensemble de fichiers de configuration
Mapping d'une entit vers un support physique Configuration gnrale de l'accs au support physique
91
Hibernate
Rcuprer sous forme d'instances de POJO des donnes stockes par le support physique
Modifier le contenu de ces POJO, leurs associations, en ajouter, en supprimer, ... Le framework fera le lien entre les modifications locales et le stockage physique
92
Exemple Hibernate
Avec les mmes structures de donnes que ce qui est stock dans la base Mais a n'est pas une obligation d'avoir exactement la mme chose (voir plus loin)
93
Exemple Hibernate
code | sport | intitule ------+----------1 | athletisme 2 | ski 3 | natation code | | code discipline | intitule | sport -----------+------------------+-----1 | 100 metres | 1 2 | 200 metres | 1 3 | saut en hauteur | 1 4 | saut en longueur | 1 5 | 100m 4 nages | 3 6 | 100m papillon | 3 7 | marathon | 1
Table discipline
94
On y trouve, notamment
On peut voir que l'accs en pratique se fera via JDBC Ex: data.Sport (classe Java) dont le mapping est prcis dans 95 Sport.hbm.xml
Fichier Sport.hbm.xml
<hibernate-mapping> <class name="data.Sport" table="SPORT" schema="ECARIOU"> <id name="codeSport" type="short"> <column name="CODE_SPORT" precision="4" scale="0" /> <generator class="assigned" /> </id> <property name="intitule" type="string"> <column name="INTITULE" length="20" /> </property> <set name="disciplines" inverse="true"> <key> <column name="CODE_SPORT" precision="4" scale="0" /> </key> <one-to-many class="data.Discipline" /> </set> </class> </hibernate-mapping>
Dans classe data.Sport, attributcodeSport correspond la colonne CODE_SPORT de la table SPORT Dfinition d'un ensemble nomm disciplines dans la classe data.Sport
96
Affichage de la liste des sports, avec pour chacun la liste de ses disciplines
// cration session Hibernate (et donc connexion au serveur Oracle) Session session = (new Configuration().configure().buildSessionFactory()).openSession(); // requte en HQL : rcupre la liste de tous les sports, // sous forme d'une liste Java Query query = session.createQuery("from data.Sport"); List sports = query.list(); // variables utilises pour le parcours de la liste des sports Set disciplines; Iterator itSport, itDisc; Sport sport; Discipline disc;
98
Affichage de la liste des sports, avec pour chacun la liste des disciplines (suite)
// parcourt les sports itSport = sports.iterator(); while (itSport.hasNext()) { sport = (Sport) itSport.next(); System.out.println(sport.getCodeSport() + " -> " + sport.getIntitule()); // rcupre l'ensemble des disciplines du sport disciplines = sport.getDisciplines(); itDisc = disciplines.iterator(); // parcourt les disciplines while (itDisc.hasNext()) { disc = (Discipline) itDisc.next(); System.out.println(" "+disc.getCodeDiscipline() + " -> "+disc.getIntitule()); } 99
1 -> athletisme 1 -> 100 metres 2 -> 200 metres 7 -> marathon 4 -> saut en longueur 3 -> saut en hauteur 2 -> ski 3 -> natation 6 -> 100m papillon 5 -> 100m 4 nages
Point intressant
A partir d'un objet de classe Sport, on accde directement sa liste de disciplines via getDisciplines() : ensemble d'objets
Les objets sont chargs partir de la base directement sans besoin de traitement particulier, c'est transparent Si on tait pass par du SQL via JDBC, on aurait du faire une requte explicite du type
100
A l'excution, peut demander tracer les requtes SQL effectues, ce qui donne ici
Hibernate: select sport0_.CODE_SPORT as CODE1_0_, sport0_.INTITULE as INTITULE0_ from ECARIOU.SPORT sport0_ 1 -> athletisme Hibernate: select discipline0_.CODE_SPORT as CODE2_1_, discipline0_.CODE_DISCIPLINE as CODE1_1_, discipline0_.CODE_DISCIPLINE as CODE1_1_0_, discipline0_.CODE_SPORT as CODE2_1_0_, discipline0_.INTITULE as INTITULE1_0_ from ECARIOU.DISCIPLINE discipline0_ where discipline0_.CODE_SPORT=? 1 -> 100 metres 2 -> 200 metres 7 -> marathon 4 -> saut en longueur 3 -> saut en hauteur (...)
Premier SELECT : pour rcuprer la liste des sports Deuxime SELECT : pour rcuprer la liste des disciplines du sport courant
101
102
Le persist() sur cet objet permet directement, sans traitement supplmentaire, de le rendre persistant (voir plus loin pour dtails)
Hibernate: select sport0_.CODE_SPORT as CODE1_0_, sport0_.INTITULE as INTITULE0_ from ECARIOU.SPORT sport0_ where sport0_.INTITULE='natation' Hibernate: insert into ECARIOU.DISCIPLINE (CODE_SPORT, INTITULE, CODE_DISCIPLINE) values (?, ?, ?)
La premire requte est un SELECT qui rcupre les donnes du sport natation La deuxime requte est un INSERT qui ajoute la discipline 103 qu'on vient de crer
Modlisation mtier de l'application de sports avec ajout d'une classe / entit sportif
104
Un sportif pratique plusieurs disciplines et une discipline est pratique par plusieurs sportifs
Association bidirectionnelle * <-> * pratique entre les 2 classes Le nombre de disciplines se dtermine partir de l'association pratique Ex. en OCL : context Sportif def: nbDisciplines : int = pratique -> size()
Un sportif a un nom et une adresse Association unidirectionnelle drive /sports entre Sportif et Sport
Les sports pratiqus par le sportif Se dtermine de l'association pratique en rcuprant les sports 105 de ces disciplines : pratique.sport -> asSet()
Une adresse est spcifique un sportif : peut inclure les donnes de l'adresse avec les donnes du sportif
pratique(code_sportif, code_discipline)
Cl primaire : combinaison de code_sportif et code_discipline Cls trangres : code_sportif de sportif et code_discipline 106 de discipline
Pas de ncessit/peu recommand d'avoir un mapping 1 vers 1 entre une table de la BDD et une classe cot mtier
On modlise d'un cot le mtier et de l'autre la BDD en s'attachant faire les meilleures modlisations selon le domaine
Cot mtier : structure logique et facilit de manipulation des donnes Cot BDD : optimiser la sauvegarde des donnes et performance d'accs
Les donnes de la classe Adresse et de la classe Sportif sont stockes via une seule table et non pas deux tables diffrentes La table d'association pratique n'a pas tre reprsente par une classe
On aura directement des mthodes dans les classes Sportif et Discipline pour rcuprer les lments correspondants Le fichier de mapping permettra de directement grer cette association
Avec disciplines qui est une association cardinalit multiple donc utilise un Set Chaque attribut doit possder un getter et un setter Peut en dfinir d'autres en plus 108
La classe persistante data.Sportif se base sur le contenu de la table sportif <id name="codeSportif" type="int"> <column name="code_sportif" /> <generator class="assigned" /> </id> Dfinition d'un attribut codeSportif correspondant la colonne code_sportif de la table La balise <id> prcise qu'on est en train de dfinir un attribut jouant le rle particulier d'identification de l'objet
Balise non obligatoire mais fortement recommande Par principe, elle sera en gnral lie la cl primaire de la table assigned : gr la main par celui qui cre les classes Peut utiliser d'autres valeurs pour une gnration automatique (voir plus loin)
109
Balise <property> dfinit une proprit au sens des Java Beans, concrtement, un attribut simple (autre qu'une collection, tableau ...) de la classe
<property name="nbDisciplines" type="integer" formula = "(select count(*) from PRATIQUE p where code_sportif = p.code_sportif)" />
Champ formula (ou balise <formula>) permet de dfinir une formule (expression SQL) au lieu d'un mapping vers une colonne d'une table
Ici on compte le nombre de disciplines associes au sportif courant via une requte sur la table pratique L'appel du setter associ (setNbDisciplines) ne servira rien ... 110
<component name="adresse" class="data.Adresse"> <property name="rue" type="string"> <column name="rue" length="50" /> </property> <property name="codePostal" type="string"> <column name="code_postal" length="5" /> </property> <property name="ville" type="string"> <column name="ville" length="15" /> </property> </component>
Balise <component> dfinit un lment compos (relation UML de composition) dans la classe courante
Ici on dfinit un attribut adresse de classe Adresse qui contient les attributs rue, codePostal et ville mappant les colonnes quivalentes dans la table sportif (la table de la classe engloblante) La classe Adresse est dfinie comme un POJO car sera persitante public class Adresse implements java.io.Serializable { private String rue; private String codePostal; private String ville;
111
<set name="disciplines" inverse="false" table="pratique"> <key> <column name="code_sportif" not-null="true" /> </key> <many-to-many entity-name="data.Discipline"> <column name="code_discipline" not-null="true" /> </many-to-many> </set>
Balise <set> dfinit un ensemble de donnes Correspond ici au mapping d'une association avec une cardinalit multiple sur une autre table (ici pratique) Balise <key> : cl trangre sur la table avec laquelle on fait la jointure
Sur la table pratique, la cl trangre est code_sportif Balise <many-to-many> dfinit une association en * <-> *
On fait la jointure sur la colonne code_discipline de pratique Retournera des instances de la classe Discipline L'attribut disciplines de la classe Sportif correspond donc l'ensemble des disciplines trouves dans pratique avec le mme 112 code_sportif que le sportif courant
Association bidirectionnelle
private Set sportifs; <set name="sportifs" inverse="true" table="pratique"> <key> <column name="code_discipline" not-null="true" /> </key> <many-to-many entity-name="data.Sportif"> <column name="code_sportif" not-null="true" /> </many-to-many> </set> Ensemble de sportifs correspondant la jointure via la table pratique et la cl code_discipline 113
Association bidirectionnelle
D'un des deux cots, on doit avoir un inverse = true dans la dfinition du set (et un false, par dfaut, de l'autre)
Dans les classes, pour assurer la bidirectionnalit, on doit faire un ajout dans les deux ensembles des deux lments
Classe Sportif
public void addDiscipline(Discipline disc) { this.disciplines.add(disc); disc.getSportifs().add(this) } public void addSportif(Sportif sportif) { this.sportifs.add(sportif); sportif.getDisciplines().add(this); }
Classe Discipline
114
Association et cardinalits
Un vers un Un vers plusieurs : sport vers discipline Plusieurs vers un : discipline vers sport Plusieurs vers plusieurs : entre discipline et sportif Ncessite une table d'association entre les 2 tables 115
<one-to-many>
<many-to-one>
<many-to-many>
select distinct(sport.code_sport), sport.intitule from discipline, pratique, sportif, sport where sportif.code_sportif = code_monSportif and discipline.code_discipline = pratique.code_discipline and pratique.code_sportif = sportif.code_sportif and sport.code_sport = discipline.code_sport
116
Requte getSports()
public Set<Sport> getSports() { Set<Sport> sports = new HashSet<Sport>(); Iterator it = this.getDisciplines().iterator(); while (it.hasNext()) sports.add(((Discipline)it.next()).getSport()); return sports; } Parcourt les disciplines du sportif et rcupre pour chacun le sport associ On place ces sports dans un Set (qui par principe ne contiendra pas de doublon) On oblige en effet charger en mmoire (de la BDD vers le programme Java) toutes les disciplines du sportif alors qu'on n'en a pas besoin 117 Problme potentiel de performance
Bonne implmentation
Requte getSports()
118
Se lit assez simplement : rcuprer la liste des sports des disciplines qui sont associes au sportif pass en paramtre Utilisation d'un paramtre nomm pour prciser le sportif
Excution de la requte
Appel de list() sur l'objet requte qui retourne la liste des rsultats On peut ensuite associer un itrateur cette liste Attention !
Il existe une mthode iterate() appelable directement sur l'objet requte Iterator it = query.iterate(); Cette mthode ne charge pas en mmoire les objets persistants retourns par la requte S'ils taient dj chargs, a marche, sinon on ne rcupre rien Donc privilgier l'usage de : Iterator it = query.list().iterate(); 119
HQL est un langage de requte aussi puissant que SQL et qui est en plus orient objet
Dfinir une variable sport correspondant une instance de la classe data.Sport : ... data.Sport sport ... Rcuprer l'objet sport associ une discipline : ... disc.sport ...
Au final, les requtes HQL sont gnralement (bien) plus simples que les requtes SQL quivalentes
select distinct sport0_.code_sport as code1_7_, sport0_.intitule as intitule7_ from sports.sport sport0_, sports.discipline discipline1_ where discipline1_.code_sport=sport0_.code_sport and (? in (select sportifs2_.code_sportif from pratique sportifs2_ where discipline1_.code_discipline=sportifs2_.code_discipline)) 120 Deux requtes SELECT imbriques sur 4 tables
query = session.createQuery("select sport from data.Sport sport where sport.codeSport = '2' "); Sport sport = (Sport)query.uniqueResult(); if (sport == null) System.out.println("Pas de sport 2"); else System.out.println("Le sport 2 est : "+sport.getIntitule());
Si une requte slectionne plus d'une valeur, on rcupre un ensemble de tableaux, un tableau par rsultat
query = session.createQuery("select sportif.nom, sportif.adresse.ville from data.Sportif sportif"); Iterator it = query.list().iterator(); System.out.println("Nom des personnes avec leur ville"); while(it.hasNext()) { Object[] res = (Object[])it.next(); System.out.println("nom : " + res[0] + ", ville : " + res[1]); 121 }
Toutes les fonctions de gestion du cycle de vie d'un objet se font par rapport une session Hibernate ouverte Toute modification d'tat se fait en mode transactionnel
Rendre persistant un objet, modifier le contenu d'un objet persistant, supprimer un objet persistant, ... Schma gnral appliquer de prfrence
En cas d'erreur (exception leve) lors de la transaction, excuter systmatiquement un rollback pour annuler ce qui a pu tre modifi
session = (new Configuration().configure().buildSessionFactory()).openSession();
(...) try { trans = session.beginTransaction(); // faire les modifications voulues (...) // pas d'erreur, on commit trans.commit(); } catch (Exception e) { // problme : on annule tout if (trans != null) trans.rollback(); }
122
Excuter des requtes HQL comme on l'a vu Utiliser des requtes natives SQL
Sportif sportif = session.load(Sportif.class, 2); Si ne trouve pas l'objet (identifiant inexistant), load() lve une exception et get() renvoie null Contrairement get(), load() ne charge pas forcment tout de suite l'objet en mmoire, l'exception potentielle sera donc leve 123 seulement quand on accdera aux donnes de l'objet
Instantier de manire normale un POJO et positionner la valeur de ses attributs Si l'on ne veut pas grer soi mme la cl primaire associ au POJO dans la BDD
Dans fichier de mapping, balise <id>, balise <generator>, champ class peut prendre diffrentes valeurs
assigned : la charge de celui qui instancie l'objet de fixer la cl primaire (valeur par dfaut si aucun gnrateur n'est prcis) native : laisse le SGBD dterminer la cl primaire (valeur entire seulement) selon ses fonctionnalits uuid : identifiant sous forme de chaine, en utilisant l'adresse IP de la machine ....
Ensuite, on rend l'objet persistant via l'appel de persist() ou save() sur la transaction courante
124
save() ralise immdiatement la gnration de la cl mais l'enregistrement physique se fera plus tard persist() fait les deux actions simultanment et immdiatement Transaction trans = trans.beginTransaction(); Sport sport = new Sport(''pche''); Discipline disc = new Discipline(''mouche'', sport); session.persist(disc); trans.commit(); Ce code gnrera une exception car le sport associ la discipline n'a pas t rendu persistant
Il faut donc le faire explicitement Ou prciser dans les fichiers de mapping que la persistance se fait automatiquement en cascade Dans une dfinition d'association (<many-to-one>, ...) ajouter le champ : cascade = ''persist''
125
Tout objet persistant (charg depuis la BDD, instanti puis rendu persistant) est attach la session
L'tat de l'objet est li avec le contenu de la BDD tant que la session existe
Mthodes evict() ou close() Il n'est plus associ la session mais existe encore en BDD
Le contenu de l'objet est supprim de la BDD (mais l'objet Java existe toujours lui, il n'a juste plus aucun lien avec la BDD) Dans fichier de mapping, utiliser au besoin des champs : cascade=''delete'' et cascade=''all-delete-orphan''
126
Modifier son contenu via l'appel des setters et autres accs aux collections
La dtection de la modification et la mise jour sur la BDD sont faites automatiquement par Hibernate
En pratique, la mthode flush(obj) est appele pour faire la mise jour physique
Mthode refresh(obj) Il n'y a pas de raison d'appeler explicitement cette mthode vu que les modifications sont transmises, sauf si on sait qu'un trigger a t excut 127
Collections
On a dfini des mappings correspondant des jointures retournant une collection java de type Set via une balise <set> On peut dfinir d'autres types de collections, correspondant aux types Java quivalents
Balise <join>
Permet de mapper des donnes venant de plusieurs tables dans une seule classe cot Java Mappings pour une hirarchie d'hritage Trois stratgies possibles
Hritage
Une table unique pour toutes les classes Une table par classe logique (mapping pour la classe mre + mappings pour les classes filles) 128 Une table par classe concrte (pas de mapping pour la classe mre)
Performance
Les performances sont principalement lies au chargement en mmoire des donnes Comme le graphe d'objets lis est potentiellement grand, on essaye de charger les objets uniquement la demande
Champ lazy=''true'' dans les mappings des collections Par dfaut, quand Hibernate charge un objet, il ne charge pas ses collections associes tant qu'on y accde pas
Exemple avec code prcdent, et sa trace, accdant aux sports et leurs disciplines
Gestion de la concurrence
Mmes fonctionnalits que dans les SGBD pour grer de manire prcise les accs concurrents : verrous sur donnes, ... 129 La gestion dtaille des transactions est importante
Peut aussi directement ajouter des annotations dans la classe Java pour prciser les mappings
@Entity @Table(name = "sport") @NamedQueries({@NamedQuery(name = "Sport.findAll", query = "SELECT s FROM Sport s"), @NamedQuery(name = "Sport.findByCodeSport", query = "SELECT s FROM Sport s WHERE s.codeSport = :codeSport"), @NamedQuery(name = "Sport.findByIntitule", query = "SELECT s FROM Sport s WHERE s.intitule = :intitule")}) public class Sport implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "code_sport") private Integer codeSport; @Column(name = "intitule") private String intitule; @OneToMany(mappedBy = "codeSport") private Collection<Discipline> disciplines; (...)
130
Un SQL-like orient objet La gestion des donnes est principalement du Java natif, pas soucier de comment sont gres et accdes les donnes
Au niveau du programme en tout cas, car il faut quand mme concevoir la base de donne et les mappings Cot Java, on manipule donc directement les entits mtiers telles qu'on les a conues 131 Mme si on doit avoir en tte qu'elles ont une persistance en BDD
Documentation Hibernate
Livre
Hibernate 3.0 Gestion optimale de la persistance dans les applications Java/J2EE, Anthony Patricio, Eyrolles
132
Combinaison de Hibernate, servlets, pages JSP avec UEL et JSTL pour afficher les sportifs avec leurs disciplines et sports pratiqus
Page HTML via un lien envoie une requte la servlet SportServlet Servlet SportServlet.java (d'URL /Sports)
Exemple final
Rcupre via une requte HQL l'ensemble des sports Ajoute cet ensemble la requte HTTP reue par la servlet Puis fait suivre (forward) la requte HTTP la page afficherSports.jsp Rcupre l'ensemble des sports dans la requte HTTP Via UEL et JSTL, met en page leur affichage
Page afficherSports.jsp
La servlet ne gnre aucun code HTML, c'est le 133 rle de la page JSP qui on a forward la requte
Exemple final
<a href="Sports?operation=listeSportif" target="operation"> Afficher la liste des sportifs</a> public List<Sportif> getListeSportifs() throws Exception { Session session = this.openHibernateSession(); Query query = session.createQuery("from data.Sportif"); return query.list(); } protected void processRequest( ... request, ... response) { String operation = request.getParameter("operation"); if (operation.equals("listeSportif")) { // rcupre la liste des sports et l'associe la requte HTTP request.setAttribute("sportifs", getListeSportifs()); // forwarde la requte la page JSP getServletConfig().getServletContext().getRequestDispatcher( "/afficheSportifs.jsp").forward(request,response); 134 } (...)
Code de SportServlet.java
Exemple final
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <h2>Liste des sportifs et de ce qu'ils font</h2> <c:forEach items="${requestScope.sportifs}" var="sp"> <h3>${sp.nom}</h3> <p><b>Adresse : </b>${sp.adresse.rue} - ${sp.adresse.codePostal} ${sp.adresse.ville}</p> <c:choose> <c:when test="${empty sp.disciplines}"> <p><i>Ne pratique aucune discpline sportive</i></p> </c:when> <c:otherwise> <p><b>Liste des disciplines pratiques : </b></p> <ul> <c:forEach items="${sp.disciplines}" var="disc"> <li>${disc.intitule}</li> </c:forEach> </ul> <p><b>Liste des sports : </b> </p> <ul> <c:forEach items="${sp.sports}" var="sport"> <li>${sport.intitule}</li> </c:forEach> </ul> </c:otherwise> </c:choose> </c:forEach>
135
Exemple final
136