Les Java Server Pages Dans ce chapitre, nous allons : Présenter l’architecture des JSP Comprendre la syntaxe JSP Développer un exemple de JSP
Présentation des JSP Présentation des JSP Génération de pages dynamiques orientée sur une logique de présentation Ce sont des scripts interprétés côté serveur contenant du code Java Insèrent de la logique de traitement dans des pages de présentation (HTML, WML, XML) Concurrent aux technologies : ASP PHP Les JSP sont basées sur une logique de présentation. Une page JSP est une page écrite dans le langage cible (HTML, mais aussi WML, XML ou d'autres dérivés du XML) et qui intègre quelques appels à du code Java. Ce code Java est exécuté sur le serveur et le résultat des appels vient compléter la construction de la page.
Exemple de fichier JSP Présentation des JSP Une page JSP est écrite dans le langage cible de publication (HTML, …) Elle contient des appels à du code Java <HTML> <HEAD> <TITLE> Exemple de page JSP </TITLE> </HEAD> <BODY> Un nombre aléatoire est : <%= Math.random() %> </BODY> </HTML> Dans cet exemple, il faut remarquer l'intégration du code Java au sein de la mise en page (en HTML).
Fonctionnement Présentation des JSP Les pages JSP sont exécutées par un moteur de JSP couplé au serveur Web Elles accèdent à du code Java qui se charge de la logique et de l'accès aux données Fonctionnement : La requête d’un client est envoyée vers le serveur Web (HTTP) qui fonctionne en étroite collaboration avec le moteur de JSP. La page JSP est compilée et le code qui s’y trouve est interprété au fil de la page. La page JSP peut par exemple manipuler des beans. C’est le cas dans l’exemple présenté ci-dessus. Les objets manipulés se trouvent sur le serveur et peuvent donc dialoguer avec d’autres objets de la même manière qu’un programme java classique (ici dialogue avec une base de données). Après exécution, la réponse du serveur est renvoyée au client via le serveur Web. Parmi les moteurs de JSP les plus performants, on peut noter celui du serveur d ’application Orion (http://www.orionserver.com) le serveur Resin (http://www.caucho.com) Tomcat est le moteur de JSP déclaré comme implémentation de référence par Sun : http://jakarta.apache.org/tomcat/index.html
Compilation des JSP Modèle d'exécution : Présentation des JSP Modèle d'exécution : Chaque page JSP est convertie en servlet Lorsque la page JSP a déjà été compilée et exécutée une fois, la servlet reste en mémoire, elle est directement exécutée L'un des avantages de cette technologie est de pouvoir redéployer "à chaud" des pages JSP sur un serveur Web. Lors d'un appel à une page, le moteur de JSP vérifie la date de dernière modification de cette page, si celle-ci est plus récente que sa version compilée (la servlet qui correspond), la page JSP est alors recompilée avant d'être exécutée.
Format des Tags JSP Les tags JSP L'écriture de pages JSP se base sur l'utilisation de balises (tags) prédéfinies Il existe deux formats pour les tags JSP JSP (Short-hand) Directives Déclaration Expression Scriptlet XML Actions L'écriture de pages JSP repose sur l'utilisation de tags précis définis dans le standard. Le concept JSP repose également sur une API ouverte permettant de définir des tags spécifiques créés au besoin par le développeur : les tag libraries.
Expressions Les tags JSP Permettent d’intégrer des valeurs directement dans le code HTML Utilisées pour afficher une chaîne de caractères, typiquement une valeur de retour Exemple : <P>Prix de l’article : <%= monArticle.getPrice() %></P> <%= value %> Toute variable utilisée dans une expression est automatiquement transformée en chaîne de caractères et intégrée dans le flux HTML produit. L'équivalent de l'exemple écrit dans une servlet serait : public void service( HttpServletRequest request, HttpServletResponse) { … out.println ("<P>Prix de l'article :" + monArticle.getPrice() + "</P>"); } Le code pourrait se trouver aussi dans la méthode doGet() ou doPost() à la place de service(). Equivalent à l’utilisation du out.println() dans la méthode service() d’une servlet
Scriptlets Permettent d’insérer du code Java Les tags JSP Permettent d’insérer du code Java Elles ont accès aux variables et aux composants déclarés dans la page Exemple : <P> <% if (true) { %> Ce texte est affiché <% } else { %> Celui-ci n'est jamais pris en compte <% } %> </P> <% code java %> L'équivalent de l'exemple écrit dans une servlet serait : public void service( HttpServletRequest request, HttpServletResponse) { … out.println ("<P>"); if (true) { out.println ("Ce texte est affiché"); } else { out.println ("Celui-ci n'est jamais pris en compte"); } out.println ("</P>"); Equivalent à du code simple dans la méthode service() d’une servlet
Déclarations Les tags JSP Utilisées pour déclarer des variables ou des méthodes dans une page Fortement déconseillé ! Exemple : <%! String var1 =“x”; int count = 0; private void increment() { count++; } %> <%! declaration %> La déclaration de membres au sein d'une page JSP n'est pas du tout recommandée. Ce n'est pas le but d'une page de scripts de déclarer des méthodes, elle ne doit contenir que des appels. Les déclarations éventuelles se trouvent dans une servlet, un Bean ou une classe Java. D'autre part, la déclaration d'attributs pose le même problème qu'avec les servlets : ces attributs sont partagés entre tous les threads clients, il peut y avoir des problèmes d'accès concurrents à ces données. Le code localisé dans la page JSP ne doit avoir d'intérêt que pour la présentation. L'équivalent de l'exemple écrit dans une servlet serait : public class maServlet extends HTTPServlet { String var1 = "x"; int count = 0; private void increment { count++; } … Equivalent à une déclaration d'attribut ou d'une méthode dans la classe de la servlet
Directives JSP Permettent de configurer la JSP Les tags JSP Permettent de configurer la JSP Sont souvent placées au début du fichier Exemples : Inclusion statique de fichiers : <%@ include file=“headers/copyright.html” %> Import de classes : <%@ page import=“java.util.*” %> <%@ directive { attribute = “value” } %> L'inclusion est très pratique dans un esprit de modularité et réutilisabilité. En effet, il est ainsi possible de définir sous forme de "composants" indépendants, des pages statiques HTML, des fonctions JavaScript, ou même d'autres pages JSP et d'inclure ces composants dans une page JSP. Attention ! La directive include permet de faire de l'inclusion statique de fichiers dans un fichier composite principal. Le fichier JSP principal est compilé en une servlet avec l'intégration des éléments inclus. Ces éléments eux ne sont pas compilés en servlets. Si ces éléments sont modifiés, le serveur ne le détecte pas forcément et ne recompile donc pas la page JSP principale en servlet. L'équivalent de l'exemple d'import écrit dans une servlet serait : import java.util.* public class maServlet extends HTTPServlet { … } Équivalent à l'écriture des imports de packages et de classes au début du code de la servlet
Directive pour les exceptions Les tags JSP Possibilité d’intercepter toutes les exceptions non catchées Redirection de tous les cas d'erreur vers une page unique Utilisation de la directive page : <%@ page isErrorPage="false" errorPage="errorHandler.jsp" %> Au début de la page errorHandler.jsp, il faut ajouter : <%@ page isErrorPage="true"%> L’ensemble des exceptions peuvent être récupérées par une même page. Le paramètre isErrorPage permet de préciser si la page est celle utilisée pour la gestion des erreurs. Dans le cas où la page est celle qui gère les exceptions, il existe une variable prédéfinie «exception» qui permet d’avoir davantage d’informations sur l’exception qui a été levée.
Liste des directives <%@ page language="java" %> <%@ page extends="package.class" %> <%@ page import= "{ package.class | package.* }, ..." %> <%@ page session="true|false" %> <%@ page buffer="none|8kb|sizekb" %> <%@ page autoFlush="true|false" %> <%@ page isThreadSafe="true|false" %> <%@ page info="text" %> <%@ page errorPage="relativeURL" %> <%@ page isErrorPage="true|false" %> <%@ page contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" %> Les tags JSP language="java" : indique le langage utilisé dans les scriptlets. En JSP, le seul langage utilisé est Java. extends="package.class" : indique le nom complet de la classe mère Java dont hérite la classe qui sera compilée à partir de cette page JSP. import= "{ package.class | package.* }, ..." : indique la liste de packages à importer, séparés par des virgules. session="true|false" : indique si oui ou non le client doit avoir une session HTTP pour utiliser la page JSP. Crée une session si nécessaire. buffer="none|8kb|sizekb" : précise la taille du buffer (en Kb) utilisée par l’objet out pour mettre en tampon le flux de sortie envoyé par la page JSP. autoFlush="true|false" : indique si oui ou non le flux de sortie bufferisé doit être automatiquement déversé lorsque le tampon est plein. isThreadSafe="true|false" : indique si oui ou non la gestion des threads est implémentée dans la page JSP, i.e. si le moteur de JSP peut envoyer plusieurs requêtes à la même page JSP simultanément. info="text" : une chaîne de caractéres qui est incorporée dans la page JSP. errorPage="relativeURL" : path vers une page JSP d’erreur vers laquelle sont envoyées les exceptions. isErrorPage="true|false" : indique si oui ou non la page JSP est une page d’erreur. Si la valeur est « true », on peut utiliser l’objet « exception ». contentType="mimeType [ ;charset=characterSet ]" | "text/html;charset=ISO-8859-1" : le type MIME et le character encoding utilisé par la page JSP pour la réponse envoyée au client.
Actions Elles effectuent une tâche prédéfinie Les tags JSP Elles effectuent une tâche prédéfinie Aucun codage en Java n’est nécessaire Elles se caractérisent par une balise standard XML spécifique : useBean setProperty/getProperty include forward Les actions sont des simplifications d'écriture pour la manipulation de composants JavaBean ou pour les interactions avec d'autres pages JSP ou avec des servlets.
Utilisation de Beans useBean : Instancie un Bean sur le serveur Les tags JSP useBean : Instancie un Bean sur le serveur getProperty : Récupère la propriété d’un Bean setProperty : Met à jour la propriété d’un Bean (utilisé pour les formulaires) <jsp:useBean id=“notreBean” scope=“application” class=“com.example.OurBean” /> <jsp:getProperty name="notreBean" property="unAttr"/> useBean permet de récupérer un Bean enregistré dans le scope. S'il n'existe pas, il est alors créé avec le constructeur par défaut du Bean. Dans une action setProperty le champ value peut être renseigné soit par une variable, soit par une expression JSP. Pour les formulaires, l’action <jsp:setProperty name="user" property="*"/> va appeler par introspection les accesseurs correspondant à tous les paramètres du formulaire <jsp:setProperty name="notreBean" property="unAttr" value="uneValeur"/> <jsp:setProperty name="notreBean" property="unAttr" param="unParam"/> <jsp:setProperty name="notreBean" property="*"/>
Actions - Scope Les tags JSP L’action useBean permet de récupérer ou de créer un bean suivant une portée 4 portées différentes : page : objet accessible seulement dans la page où il a été créé request : objet accessible seulement pour les pages qui sont liées à une même requête session : objet accessible par un seul client sur toutes les pages JSP pendant la même session application : objet accessible par tous les clients pendant toute la durée de l’application useBean permet de récupérer un Bean enregistré dans la portée. S'il n'existe pas, il est alors créé. Le cas du scope « request » : il est utilisé dans le cas où plusieurs pages sont appelées pour une même requête, dans le cadre d’include ou de forward de pages par exemple.
Utilisation d'autres ressources Les tags JSP include : Permet d’insérer dynamiquement le contenu d'une autre ressource (servlet, JSP, HTML) forward : délègue le traitement de la requête à une autre ressource le sendRedirect reste possible, mais ce n'est pas une action <jsp:include page="shoppingcart.jsp" /> L’action include permet d’inclure du code en faisant appel à une seconde JSP. Mais contrairement à la directive include, il s'agit ici d'une inclusion dynamique. Les fichiers JSP inclus ne sont que référencés par le fichier JSP principal. Ils sont eux-même compilés en servlets. En fait, la page principale inclus le résultat de l'exécution du composant inclus. Ce qui implique que lors d'une modification de l'un de ces fichiers, la recompilation est effectuée et les modifications sont bien intégrées à la page JSP principale. L’action forward, permet à la page JSP de réaliser des pré-traitements et de déléguer d'autres traitements et la production de la réponse à un deuxième composant. Une page JSP peut également implémenter une redirection comme pour les servlets. En effet, cette redirection se fait par simple appel à la méthode sendRedirect() sur l'objet response. <jsp:forward page="shoppingcart.jsp" />
Variables implicites 9 variables implicites peuvent être utilisées dans les pages JSP : Variables implicites Variable (scope - classe) Méthodes courantes Commentaires request ( request - Sous-classe de javax.servlet. ServletRequest ) getParameter getParameterNamesgetParameterValues Répresente la requête HTTP response (Page – Sous-classe de javax.servlet. ServletResponse) Représente la réponse HTTP Peu utilisé dans les JSP On accède directement à chacun de ces objets. Exemple : <% String maValeur = (String)request.getParameter("monParametre"); %> La référence de la réponse HTTP (response) est peu utilisée dans les JSP puisque le flux est directement géré par le serveur.
Variables implicites pageContext (Page - javax.servlet.jsp.PageContext) findAttribute getAttribute getAttributesScope getAttributeNamesInScope session (Session - javax.servlet.http. HttpSession) getId getAttribute putAttribute getAttributeNames Représente la session utilisateur application (application - javax.servlet. ServletContext) getMimeType getRealPath Représente la Web application
Variables implicites out (Page - javax.servlet.jsp.JspWriter) clear, clearBuffer, flush, getBufferSize, getRemaining Représente la réponse http sous la forme d’un flux de caractères config (Session - javax. servlet. ServletConfig) getInitParameter, getInitParameterNames page (page - java.lang. Object) getMimeType, getRealPath Peu utilisé exception (page - java.lang. Throwable) getMessage, getLocalizedMessage, printStackTrace Variables implicites
Ecrire des JSPs (1) JSPs de présentation : Démarche JSPs de présentation : Générer dans un premier temps le code HTML de la partie présentation Enregistrer le fichier avec l’extension .jsp Programmer le code Java sur le serveur qui gère la partie fonctionnelle Insérer les appels JSP pour la communication avec ce code Java Certaines JSPs servent uniquement à réaliser des traitements, l'écriture de la réponse est alors déléguée La ligne de conduite à suivre pour le développement de pages JSP met bien en évidence la possibilité de paralléliser le travail et d'affecter à chaque développeur la partie qui le concerne : la présentation pour le Web designer et la logique métier pour le concepteur-programmeur. Une page JSP peut parfaitement servir à effectuer des traitements comme une servlet, pour exploiter la validation d'un formulaire par exemple. En effet, elle a accès aux mêmes éléments qu'une servlet (requête, session, réponse, …).
Ecrire des JSPs (2) JSP Affichage de formulaire Démarche JSP Affichage de formulaire JSP Traitement du formulaire JSP Affichage de résultat JSP Affichage de page d'erreur POST forward En fonction du résultat La définition d'un service Web se compose de plusieurs éléments : une unité de saisie, c'est un formulaire HTML généré par une page JSP, une unité de traitement de ce formulaire, c'est une page JSP qui récupère les paramètres de la requête POST, instancie les objets métiers nécessaires et réalise les traitements nécessaires, elle redirige (forward) la présentation du résultat vers une page JSP adaptée (affichage de résultat ou affichage d'erreur), une unité de réponse, c'est une page HTML générée dynamiquement en fonction du résultat du traitement ; deux pages de réponses sont programmées : une pour les cas standards et une pour les cas d'erreurs.
Un exemple complet JavaBean JSP Ex 7-8 package com.example ; public class OurBean { private String value; public void setValue (String s ) { value = s ; } public String getValue ( ) { return value ; Démarche JavaBean <HTML> <BODY> <H2> cette page teste notre bean </H2> <jsp:useBean id= “notreBean” class= “com.example.OurBean” scope= “session” /> <% notreBean.setValue(“présent”); %> <P> notre bean est <%= notreBean.getValue(); %> </P> </BODY> </HTML> JSP Ex 7-8