Serveur d’applications JEE F.Renault
Introduction Java à la maison, java au boulot, java sur le chemin Le «Java Framework» (Java 2 Platform) est composé de trois éditions, destinées à des usages différents : J2ME : Java 2 Micro Edition est prévu pour le développement d'applications embarquées, notamment sur des assistants personnels et terminaux mobiles ; J2SE : Java 2 Standard Edition est destiné au développement d'applications pour ordinateurs personnels ; J2EE : Java 2 Enterprise Edition, destiné à un usage professionnel avec la mise en oeuvre de serveurs. Chaque édition propose un environnement complet pour le développement et l'exécution d'applications basées sur Java et comprend notamment une machine virtuelle Java (Java virtual machine) ainsi qu'un ensemble de classes.
Définition de J2EE J2EE (Java 2 Enterprise Edition) est une norme proposée par la société Sun, portée par un consortium de sociétés internationales, visant à définir un standard de développement d'applications d'entreprises multi-niveaux, basées sur des composants. Cela concerne l’architecture des logiciels On parle généralement de «plate-forme J2EE» pour désigner l'ensemble constitué des services (API) offerts et de l'infrastructure d'exécution. J2EE comprend notamment : Les spécifications du serveur d'application, c'est-à-dire de l'environnement d'exécution : J2EE définit finement les rôles et les interfaces pour les applications ainsi que l'environnement dans lequel elles seront exécutées. Ces recommandations permettent ainsi à des entreprises tierces de développer des serveurs d'applications conformes aux spécifications ainsi définies, sans avoir à redévelopper les principaux services. Exemple de serveur d’application : Sun Java server Glassfich WebLogic Application Server Un serveur d’application bien connu : TOMCAT Ce n’est finalement qu’un serveur JEE partiel comme on pourra le voir plus tard, il n’implémente qu’une partie des spécifications J2EE . Des services, au travers d'API, c'est-à-dire des extensions Java indépendantes permettant d'offrir en standard un certain nombre de fonctionnalités. Sun fournit une implémentation minimale de ces API appelée J2EE SDK (J2EE Software Development Kit). Ainsi des bibliothèques de classes supplémentaires sont disponibles pour créer des logiciels aux fonctionnalités adaptées aux serveurs d’applications.
Les Api de J2EE Les API de J2EE peuvent se répartir en trois grandes catégories : Les composants. On distingue habituellement deux familles de composants : Les composants web : Servlet et JSP (Java Server Pages). Il s'agit de la partie chargée de l'interface avec l'utilisateur (on parle de logique de présentation). Les composants métier : EJB (Enterprise Java Beans). Il s'agit de composants spécifiques chargés des traitements des données propres à un secteur d'activité (on parle de logique métier ou de logique applicative) et de l'interfaçage avec les bases de données. Ces deux types de composant sont mis en place par le biais de conteneurs. On parle de conteneur de servlets ou de conteneur EJB
Les Api de J2EE Les services, pouvant être classés par catégories : Les services d'infrastructures : il en existe un grand nombre, définis ci-dessous : JDBC (Java DataBase Connectivity) est une API d'accès aux bases de données relationnelles. JNDI (Java Naming and Directory Interface) est une API d'accès aux services de nommage et aux annuaires d'entreprises tels que DNS, NIS, LDAP, etc. JTA/JTS (Java Transaction API/Java Transaction Services) est un API définissant des interfaces standard avec un gestionnaire de transactions. JCA (J2EE Connector Architecture) est une API de connexion au système d'information de l'entreprise, notamment aux systèmes dits «Legacy» tels que les ERP. JMX (Java Management Extension) fournit des extensions permettant de développer des applications web de supervision d'applications. Les services de communication : JAAS (Java Authentication and Authorization Service) est une API de gestion de l'authentification et des droits d'accès. JavaMail est une API permettant l'envoi de courrier électronique. JMS (Java Message Service) fournit des fonctionnalités de communication asynchrone (appelées MOM pour Middleware Object Message) entre applications. RMI-IIOP est une API permettant la communication synchrone entre objets. Tous ces services sont donnés par des librairies de classes à partir desquelles on pourra créer facilement des objets utiles aux applications. Le cas typique JavaMail L'architecture J2EE permet ainsi de séparer la couche présentation, correspondant à l'interface homme-machine (IHM), la couche métier contenant l'essentiel des traitements de données en se basant dans la mesure du possible sur des API existantes, et enfin la couche de données correspondant aux informations de l'entreprise stockées dans des fichiers, dans des bases de données relationnelles ou XML, dans des annuaires d'entreprise ou encore dans des systèmes d'informations complexes.
Schema Serveur JEE complet Tomcat
Comparaison de serveurs…. Apache Serveur web simple : Pas de page dynamiques Fournisseur de fichiers Apache + CGI Comme un plug-in, permet à apache de rendre ses pages web dynamiques. Apache + php Plus connu aujourd’hui, et plus simple à mettre en œuvre que cgi, php et son interpréteur mais il suis le même schéma. C’est sa bibliothèque d’objets qui le rend souple et la possibilité depuis php5 d’avoir une programmation objet plus normalisée permet des développements de bonnes envergures. Cependant…quelques limites… Apache + java …. TOMCAT Tomcat est un serveur d’application plus évolué car cette fois, il ne se contente pas de rediriger les requêtes utilisateurs vers un programme simple ou comme php vers un interpréteur. Au lancement de tomcat, qui est écrit en java d’ailleurs, un conteneur de servlets est mis en place. C’est lui qui va gérer les redirections et créer un contexte pour les applications java. Il met aussi en place l’interprèteur JSP…
Conteneur de servlet Logiciel démarré au lancement du serveur et actif à plein temps : Fait le pont entre le monde web(requêtes utilisateur http) et le monde java Possède son propre contexte Paramétrable par des fichiers xml (dans ses répertoires) ou un logiciel adapté : Serveur.xml Context.xml Web.xml Crée un contexte pour chaque application web Paramétrable par des fichiers xml dans le répertoire de chaque application : Le serveur cumul les informations globales et locales, les fichiers ont d’ailleurs les mêmes noms. Nous travailleront essentiellement sur ces fichiers locaux. On peut voir un contexte comme une bulle dans laquelle vit l’application, le serveur en définit les limites. Un espace mémoire réservé Un système de fichier dont une structure minimale est imposée et dont la racine définit le contexte. On parle aussi de chemin de contexte. Des ressources générales misent à disposition : Accès à une base de données (Datasources) Accès à des objets partagés entre les applications Des ressources spécifiques à une application. Gestionnaire des servlets et pages jsp, il peut filtrer des requêtes destinées à l’un ou l’une en particulier ou pour toute l ’application(Pour des statistiques par exemple) Gestionnaire des espaces mémoires, il peut écouter les modifications associées à des objets fabriqués par pour l’application, les objets de contexte (modification d’une session utilisateur par exemple) Gestionnaire des requêtes entrantes, il peut définir des droits d’accès pour certaines ressources en fonction de l’utilisateur, en fonction de l’adresse ip du client ect…
Schéma : pour se faire une idée Représentant la requête http de l’utilisateur et la réponse à lui revoyer, encore vierge. Contexte serveur Contexte d’application Request Response Crée les objets java Request et Response . Lit les fichiers de config généraux et du contexte d’application, crée Les objets implicites Si des filtres ou écouteurs généraux sont définit, ils sont appelés et ont accès aux objets créés ci-dessus. Ensuite idem pour les filtres et écouteurs de l’application. Enfin passe le relai à le serlet. Rend la réponse de le serlet et/ou exécute les actions qu’elle demande. Web.xml Server.xml Context.xml Web.xml Context.xml Objets implicites Listener Filter Ressources. Listener Filter Ressources. Servlet
Servlet : Principe de base On demande une ressource http à un serveur web Le serveur passe la requête à un programme relai (le conteneur web, actif dès le démarrage du serveur) qui va instancier une classe java capable de gérer la requête et générer une réponse (c’est la boucle de l’appel). Le conteneur donne aussi au passage, un ensemble d’informations sur lui-même Une fois instanciée, cette classe reste en attente de sollicitations. La réponse est ‘rendue’ au conteneur puis au client( fin de la boucle). Serveur WEB Conteneur de Servlet Client Request Servlet1 Response
Servlet : en pratique Une classe java pur qui herite de GenericServlet ou HttpServlet On ne l’intancie pas (pas de new MaServlet), c’est le conteneur de servlet qui se charge de tout le cycle de vie de l’objet. Création Initialisation Appel de ses méthodes Mise à disposition d’objet implicites Destruction On pense environnement comme en développement windows avec c++ et les fonctions de callback, en java avec les listeners et la machine virtuelle, cette fois, c’est au conteneur qu’il faut penser.
Accède à des objets d’informations sur le conteneur Servlet : Anatomie HttpServlet GenericServlet Conteneur -Crée les objets Req et Resp -Appel init() à l’instanciation de le servlet -Appel à service() avec les objets req et resp Si une requête est destinée à la servlet : Service défini si la requête est de type post ou get et appel doGet() ou doPost en fonction. -Appel à destroy() lorsque le conteneur s’arrête par exemple SERVLET Accède à des objets d’informations sur le conteneur init() destroy() service(req, res) doGet(req, res) doPost(req, res)
Du code ! import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class PremiereServlet extends HttpServlet { public void init() { } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE> Titre </TITLE></HEAD>"); out.println("<BODY>"); out.println("Ma première servlet"); out.println("</BODY>"); out.println("</HTML>"); out.close(); }
Servlet package servlets; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class NewServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); protected void doPost(HttpServletRequest request, HttpServletResponse response) public String getServletInfo() { return "Short description";
JSP Dans sa forme une page jsp est un fichier texte qui comporte du code HTML que l’on peut enrichir de code java à travers des balises (tags) spécifiques. La page jsp s’apparente à une page php mais cache beaucoup plus de ressources. La page est prise en charge par le conteneur de servlet, en effet, au premier appel de celle-ci, le conteneur va construire une servlet à partir du fichier jsp à l’aide d’un interpréteur. Mécanisme : Le fichier page.jsp est parser par l’interpreteur qui construit un nouveau fichier texte page_servlet.java. Le fichier page_servlet.java est compilé, rendant une servlet transparente au développeur accessible par le chemin de la page jsp.
JSP : Phase de traduction
Du code ! <%-- Ceci est un commentaire JSP --%> <%@page contentType="text/html"%> <%@page import="java.util.*"%> <html> <head><title>Page JSP</title></head> <body> <%-- Déclaration d'une variable globale à la classe --%> <%! int nombreVisites = 0; %> <%-- Définition de code Java --%> <% //Il est possible d'écrire du code Java ici Date date = new Date(); // On peut incrémenter une variable globale pour compter le nombre // d'affichage, par exemple. nombreVisites++; %> <h1>Exemple de page JSP</h1> <%-- Impression de variables --%> <p>Au moment de l'exécution de ce script, nous sommes le <%= date %>.</p> <p>Cette page a été affichée <%= nombreVisites %> fois!</p> </body> </html>
Schémas Conteneur de Servlet Serveur WEB Client Ressources Server.xml Conteneur de Servlet Ressources Web.xml Context.xml Contexte App1 Contexte App2 Contexte App3 Client Web.xml Web.xml Web.xml Context.xml Context.xml Context.xml Servlet1 Servlet3 Servlet2 Interprète JSP
Sénario 1 : Appel d’une servlet 1) Requête du client au serveur http://serveur/App1/Servlet2 2) Le serveur oriente la requête vers le conteneur 3) Le conteneur créer ici des objets java qui seront utilisables par la servlet (objets implicites) 4) Le conteneur recherche la Servlet2 dans le contexte App1. C’est le fichier web.xml de App1 qui va lui donner les informations necessaires 5) Le conteneur passe les objets implicites à la servlet 6) La servlet utilise les objets implicites (ou pas), créer une réponse 7) La réponse est remise au serveur web (par le conteneur en fait) qui se charge de la renvoyer au client. Le conteneur englobe toutes les servlets et gère le cycle de vie, leur création, initialisation, destruction. Nous verrons qu’il peut aussi mettre à disposition de celles-ci des ressources supplémentaires, intercepter des requêtes destinées à une application ou une servlet précise…
Schémas Conteneur de Servlet Serveur WEB Client Ressources Server.xml Conteneur de Servlet Ressources Web.xml Context.xml Contexte App1 Contexte App2 Contexte App3 Client Web.xml Web.xml Web.xml Context.xml Context.xml Context.xml Servlet1 Servlet3 Servlet_MaPage Servlet2 Interprète JSP MaPage.jsp
Sénario 2 : Appel d’une page JSP 1) Requête du client au serveur http://serveur/App3/MaPage.jsp 2) Le serveur oriente la requête vers le conteneur 3) Le conteneur créer ici des objets java qui seront utilisables par la serlet (objets implicites)…mais quel servlet ??? Les pages jsp sont en réalité transformées en servlet et le traitement est exécuté par cette dernière lorqu’elle est disponible. À la première demande d’une page jsp, la serlet qui lui correspond n’existe pas ! Le conteneur sait qu’il faut alors la créer et passe la demande à l’interpreteur JSP pour maPage.jsp 4) Pas de servlet pour cette requête jsp, l’interprèteur le crée et le met à disposition pour le contexte d’App3 Attention, ceci est transparent pour le programmeur. Il ne verra pas se créer la serlet, celle-ci se cache dans l’arborescence de tomcat (cf TD) 5) Le conteneur passe les objets implicites à la serlet 6) Le servlet utilise les objets implicites (ou pas), créer une réponse 7) La réponse est remise au serveur web (par le conteneur en fait) qui se charge de la renvoyer au client. Remarque : attention aux abus de language… passez l’objet c’est lui donner une référence. En réalité les choses se partagent et ne se transfert pas. La machine java est derrière tout ces méchanismes. La Page JSP est transformée une seule fois en servlet au premier appel, l’execution est donc plus lente à ce moment, mais les requêtes suivantes seront rapides car le conteneur utilisera directement la serlet produite.
Application web : structure
Application web : structure Une structure minimale d’une application web est imposée par les spécifications J2EE. Assembly Root : Répertoire racine de l’application. META-INF : Répertoire méta informations sur l’application On y trouvera des fichiers de configuration utilisés par l’application directement ou des ressources spécifiques (persistence.xml, struts-config.xml etc...) WEB-INF : Répertoire informations web contient 3 sous répertoires : lib : Répertoires des jars utilisés par l’application. Il complète les bibliothèques misent à disposition par le serveur. classes : Répertoire des class compilées du projet tags : Répertoire des librairies de tags personnalisés (ou pas) pour l’application. Fichier web.xml : Descripteur de déploiement de l’application. Fichier très important pour le développeur il recense toutes servlets, pages jsp et d’autres ressources auxquelles fait appel l’application (source de donnée, filtres, écouteurs etc..)
Vue de développeur Arborescence NetBean Arborescence Eclipse
Descripteur de déploiement : web-xml Un aiguilleur Un aiguilleur pour les requêtes Le serveur doit pouvoir retrouver les servlets qu’il doit atteindre à partir de la requête du client. Pour cela le fichier web.xml décrit un mapping de correspondance en deux étapes: 1) La servlet est nommée <servlet> <description>Servlet exemple</description> <display-name>Hello</display-name> <servlet-name>Hello</servlet-name> <servlet-class>com.test.servlets.Hello</servlet-class> </servlet> 2)La servlet est associée à une url <servlet-mapping> <url-pattern>com.test.servlets.Hello</url-pattern> </servlet-mapping >
Descripteur de déploiement : web-xml Un paramètreur Ajouter des paramètres pour l’application On peut définir des constantes textuelles accessibles dans tout le contexte de l’application <context-param> <param-name> MON_PARAM </param-name> <param-value>valeurDe MON_PARAM </param-value> </context-param> Il seront accessibles aux servlets par le biais de l’objet implicite servletConfig getServletContext().getInitParameter("MON_PARAM"); Ajouter des paramètres pour une servlet Sur le même schéma que précédemment, on définit cette fois des paramètres d’initialisation entre les balises de le serlet concernée: <servlet> <servlet-name>maServlet</servlet-name> <display-name>Ma Servlet</display-name> <description>Ma Servlet</description> <servlet-class>com.servlet.MaServlet</servlet-class> <init-param> <param-name>MON_PARAM</param-name> <param-value>Bonjour</param-value> </init-param> </servlet> Accessible par : getInitParameter("MON_PARAM");
Descripteur de déploiement : web-xml Un surveillant Il peut aussi mettre en place un Listener pour le contexte. Cette classe particulière réagit quand le contexte de l’application est initialisé ou détruit. Pour la créer, il suffit d’écrire une classe qui implémente l’interface ServletContextListener public class MyHttpServletContextListener implements ServletContextListener { /** Cette méthode appelée lors du démarrage de l'application*/ public void contextInitialized(ServletContextEvent sce) {System.out.println("L'application vient de démarrer"); } /** Cette méthode appelée lors de l'arret de l'application*/ public void contextDestroyed(ServletContextEvent sce) { System.out.println("L'application vient de s'arreter"); } } Ensuite pour la mettre en œuvre, on place sa définition dans le fichier web.xml : <listener> <listener-class>com.test.MonListenerDeContexte</listener-class> </listener> Ces fichiers java sont écrit dans l’EDI, répertoire de fichiers sources qui se charge généralement de la compilation et place automatiquement les fichiers .class générés dans le répertoire adéquat. Nous verrons plus loin comment déployer l’application sur le serveur.
Descripteur de déploiement : web-xml Un gardien Des filtres peuvent aussi être placés en fonction de la ressource à atteindre. Cela agît comme un aiguillage en boucle, on passe par le filtre avant d’atteindre la ou les urls designées dans un mapping. Pour créer un filtre on implémente cette fois l’interface Filter public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) Implements Filter throws IOException, ServletException { //Actions du filtre…… chain.doFilter(request, wrapper); } La mise en place se fait en agrémentant le fichier web.xml <FILTER> <FILTER-NAME>monFiltre</FILTER-NAME> <FILTER-CLASS>my.package.doFilter</FILTER-CLASS> </FILTER> <filter-mapping> <filter-name>monFiltre</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> Le mapping permet de définir quelles requêtes seront dirigées vers le filtre. REMARQUE : Depuis la version 3.0 des servlets, il est possible de zapper le fichier web.xml en utilisant des annotations directement dans le code qui seront comprises par le serveur ou à la compilation.
Descripteur de contexte : Context.xml Des ressources supplémentaires et gérées par le serveur peuvent être misent à disposition d’une application. Le fichier context.xml décrit ces ressources, ici une DataSource : <?xml version="1.0" encoding="UTF-8"?> <Context> <!-- Specify a JDBC datasource --> <Resource name="jdbc/mydatabase" auth="Container" type="javax.sql.DataSource" username="YOUR_USERNAME" password="YOUR_PASSWORD" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://mysql.metawerx.net:3306/YOUR_DATABASE_NAME? /> <!-- Specify the security realm and location of the users file <Realm className="org.apache.catalina.realm.MemoryRealm" pathname="/tomcat/webapps/ROOT/WEB-INF/users.xml" /> --> </Context>
Descripteur de contexte : Context.xml La DataSource précédemment décrite sera accessible ensuite aux servlets de l’application : // Get DataSource Context ctx = new InitialContext(); DataSource ds =DataSource)ctx.lookup("java:comp/env/jdbc/mydatabase"); // Get Connection and Statement Connection c = ds.getConnection(); Statement s = c.createStatement(); Le serveur gère un espace de noms qui permet de stocker des objets hiérarchisés en arborescence (Comme des répertoires) La racine pour chaque application sera java:comp/env Le descripteur de contexte y place au chargement de l’application une source de donnée, Objet DataSource qu’il sait instancier automatiquement. Il le place pour nous en « jdbc/mydatabase » relativement à la racine Lorsque l’on veut utiliser cette ressource, il faut récupérer le contexte puis la datasource.
Descripteur de contexte : Context.xml L’intérêt de la DataSource : -Déclarée dans Contexte.xml, elle est à disposition de toute l’application et c’est le serveur qui va gérer l’unicité ou un pool de connexions avec la base. -Il existe un autre fichier Context.xml qui lui est associé au serveur lui-même et non pas à l’application et travailant de paire avec un fichier Server.xml. - Une DataSource déclarée dans ces fichiers pourra donc être mise à disposition de toutes les applications situées sur le serveur. Un seul chemin vers la base de données complètement géré par le serveur.
Servlet en pratique Accès à la requête utilisateur Accès au contexte de l’application Accès à la réponse Création de beans Redirection
Les objets implicites Response : Paramètre de la méthode service C’est un lien avec la réponse envoyée au client qui est accessible par un buffer texte. On y trouve un ensemble de propriétés qui vont définir le format et les caractéristiques de renvoyées. Sa principale utilité est un accès direct au buffer pour y écrire : On écrit une réponse c’est-à-dire du code HTLM par exemple. Il est possible de définir un autre format qui indiquera au client que l’on envoie un fichier texte simple, pdf ou tout autre en définissant la propriété ContentType . Les méthodes de l’objet parlent d’elles même : Par exemple setHeader : redéfinit l’entête de réponse La date du fichier, un code d’erreur etc… Ajout d’un cookie (Class cookie puis response.setCookie) Request : Paramètre de la méthode service Accès aux propriétés de la requête émise par l’utilisateur Récupération des paramètres de la requête Accès aux attributs de requêtes, se sont des objets java stockés dans une Map en mémoire et disponibles tant qu’une réponse définitive n’est pas renvoyée. Accès à la l’objet session qui lui stocke de la même manière que précédemment des objets java qui eux seront gardés en mémoire pour toute la session utilisateur. C’est l’objet idéal pour créer un panier pour un site d’achats en ligne par exemple ou encore stocker les caractéristiques d’un client pour une interface personnalisée. Accès aux cookies de l’utilisateurs.
Les objets implicites (servlet et jsp) session: Instance de la classe javax.servlet.http.HttpSession, cet objet est par défaut disponible à toutes les pages qui participe à une session(jsp : sauf si l'attribut session de la directive page est positionné à faux.) Il permet d'accéder aux objets dont la portée est session via la méthode getAttribute. out: Instance de la classe javax.servlet.jsp.JspWriter , cet objet représente le canal de sortie utilisé pour communiquer la réponse au client (navigateur).Buffer texte application: Instance de la classe javax.servlet.ServletContext, cet objet contient le contexte de la servlet. context: Instance de la classe javax.servlet.jsp.PageContext, cet objet permet d'accéder à différentes informations sur l'environnement du serveur. config: Instance de la classe javax.servlet.ServletConfig, cet objet permet d'accéder à la configuration de la servlet. Pour les pages jsp nous verrons des objets ajoutés. page: instance de la classe java.lang.Object, cet objet désignant la page JSP elle même, c'est l'équivalent à this de Java. Prévu initialement pour permettre l'accès des objets Java lorsqu'un autre langage de script était utilisé. exception: instance de la classe java.lang.Throwable, cet objet représentant un exception non interceptée par le code Java, très utile dans les pages d'erreur.
Les Attributs, objets de communication. Le serveur met à disposition du programmeur des espaces mémoires afin de stocker des objets de toutes sortes nommés attributs. Un attribut est caractérisé par un nom unique auquel est associé l’objet stocké comme dans une map. Exemple : Personne p_roger = new Personne(« roger »); Request.setAttribute(« roger »,p_roger); Pour récupérer l’objet on passe par la clef et on caste en spécifiant le type. Personne untel = (Personne)request.getAttribute(« roger ») La méthode renvoi soit null, soit une instance de la classe java Object qu’il faut donc caster. Qui peut stocker des attributs : request, session, application : ce qui définit la portée de l’attribut, appelé aussi le scope. Suivant l’objet qui stocke l’attribut et donc suivant son cycle de vie dans le serveur, l’attribut sera disponible plus ou moins longtemps. Sur une requête, une session, ou sur l’application entière.
Scope : request Un objet disponible au fil de la requête : Request.setAttribute
Scope : Session Objet disponible sur la session utilisateur: Request.getSession().setAttribute
Scope : Application Objet disponible pour dans toute l’application, pour tout les utilisateurs. getServletContext().setAttribute(« nom »,objet); Application.setAttribute(« nom »,objet);
RequestDispatcher Aiguiller et transmettre la requête utilisateur. Cet objet très important permet à une servlet de passer le relais à une autre ou vers une jsp. Transmettant les objets request et response. Il accède au différentes ressources en se basant sur le chemin depuis la racine ou relativement à la servlet qui l’invoque. Methode : forward Inclure le résultat d’une servlet ou d’une jsp Methode : include
On s’y retrouve ? Session utilisateur request Attributes SERVLET parametres attributes Attributes SERVLET response ServletDispatcher InitParameters Web.xml ServletName Web.xml Servletcontext Servletconfig Parametres Web.xml Attributes
Les objets du développeur Les servlets forment l’interface avec le serveur. Elles sont sollicités par des requêtes externes (utilisateur, liens, formulaires) ou internes (autres servlet requestDispatcher). Lorsqu’on développe une application, on a bien sur besoin d’objets spécifiques : Objets réalisants des traitements Objets représentants des entités (personne ou autres) Objets de connections à une base de données Objet de communication entre objets de l’application, etc. Ces types d’objets se créent dans le répertoire source de l’application et sont à disposition des servlets Suivant leurs fonctions, certains auront de multiples instances et il est judicieux pour d’autres d’être uniques dans une session ou une application.
Design d’application : définitions des rôles de nos objets. Servlets : Objets capables de manipuler les requêtes et les réponses, d’utiliser les ressources de l’application (objets du développeur) comme celles du serveur. Request, response Objets des packages sources Objets des packages java standards Objets des packages d’entreprise JDK Objets des librairies du serveur Objets des librairies du répertoire WEB-INF/lib Mais il est pénible de coder une réponse HTML dans une servlet. JSP : On sait qu’elles sont en réalité des servlets, mais gérées par le conteneur, elles peuvent donc réaliser tout ce que les servlets peuvent faire mais ce n’est pas leur but principal. Leur fonctionnalité première et de simplifier le codage des réponses HTML et donc d’être orientées WEB. Elles seront donc la base des interfaces avec le client.
Objets Programmeur Jsp formulaire appelle Jsp Réponse utilise
Objets Programmeur Jsp formulaire appelle Servlet traitement utilise redirige Jsp Réponse
Vérifie les paramètres Objets Programmeur Vérifie les paramètres Servlet aiguillage Jsp formulaire 1 appelle utilise 3.2 réponse 3.1 redirige 2.1 Erreur de paramètres Objets Programmeur Traitement Servlet traitement 4 réponse Jsp Erreur Jsp Réponse traitement
Pause
JSP en pratique Une JSP est un fichier texte Il contient du code html (appelé template) et des balises spécifiques permettant de coder en java les scriptlets. Transformée par le serveur en servlet Tout ce qu’une servlet peut faire, une jsp peut le faire Il est utile d’aller voir le fichier java correspondant à la servlet générée afin de bien comprendre et situer ce que les balises de tags jsp produisent. Répertoire work pour tomcat
Transition : JSP => Servlet <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Hello JSP World!</h1> </body> </html>
Transition : JSP => Servlet package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory(); private static java.util.List _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.AnnotationProcessor _jsp_annotationprocessor; public Object getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName()); public void _jspDestroy() {
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { response.setContentType("text/html;charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\n"); out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n"); out.write(" \"http://www.w3.org/TR/html4/loose.dtd\">\n"); out.write("<html>\n"); out.write(" <head>\n"); out.write(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"); out.write(" <title>JSP Page</title>\n"); out.write(" </head>\n"); out.write(" <body>\n"); out.write(" <h1>Hello JSP World!</h1>\n"); out.write(" </body>\n"); out.write("</html>\n"); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context);
Cycle de vie Identique aux servlet jspInit() _jspService() jspDestroy() Ces méthodes sont utilisées comme celles des servlets et sont redéfinissables On pourrait imaginer modifier init() tout court mais le server l’utilise pour la génération de servlet de manière plus complexe, il est donc mis a disposition ces fonctions pour éviter des « collisions »
Eléments de script Quatres types d’éléments de script : Les directives : indiquent à la pages les informations globales (par exemple les instruction d’importations) Les déclarations : destinées à la déclaration de méthodes et de variables à l’échelle d’une page Les scriplets : code Java intégré dans la page Les expressions : sous forme de chaîne, en vue de leur insertion dans la sortie de la page
JSP : les directives de page Page : informations relatives à la page Include : fichiers à inclure littéralement Taglib : URI d’une bibliothèque de balises utilisée dans la page <%@ page [language="java"] [extends="package.class"][import="{package.class|package.*}, ..."] [session="true|false"] [buffer="none|8kb|sizekb"] [autoflush="true|false"] [contentType="mimeType [charset=characterSet]" | "text/html;charset=ISO-8859-17"] [iserrorPage="true|false"] %>
JSP : les directives de page Définir les "import" nécessaires au code Java de la JSP <%@ page import="java.io.*"%> Définir le type MIME du contenu retourné par la JSP <%@ page contentType="text/html"%> Fournir l'URL de la JSP à charger en cas d'erreur <%@ page errorPage="err.jsp"%> Définir si la JSP est une page invoquée en cas d'erreur <%@ page isErrorPage="true" %> Déclarer si la JSP peut être exécutée par plusieurs clients à la fois <%@ page isThreadSafe="false" %>
JSP : les directives de page
JSP : les directives d’inclusion <%@ include ……%> – Permettent d’inclure le contenu d’un autre fichier dans la page JSP courante – Inclusion effectuée avant la compilation de la jsp
JSP : les directives d’inclusion
JSP : les balises personnalisées <%@ taglib ……%> – Permettent d’indiquer une bibliothèque de balises adresse et préfixe, pouvant être utilisées dans la page <%@ taglib prefix="pref" uri="taglib.tld" %>
JSP : les déclarations <%! ……%> – Permettent de déclarer des méthodes et des variables d’instance connus dans toute la page JSP
Les scriplets
Les scriplets
Les expressions
Les commentaires
JSP : éléments de script-objets implicites
JSP : les éléments d’action
JSP : les éléments d’action
JSP : include/param
JSP : include/param
JSP : forward
JSP : useBean
JSP : useBean-Java Bean
JSP : useBean-Java Bean
JSP : useBean-Java Bean
JSP : useBean
JSP : get/setproperty
JSP : get/setproperty
JSP : get/setproperty
Combinaison Servlet et JSP