Connexion Web et Bases de Données : Les SERVLETS S. BEN YAHIA Faculté des Sciences de Tunis, Tunisie Sadok.benyahia@fst.rnu.tn
Présentation Servlet : Server-side applet Une servlet est un composant qui étend les fonctionnalités d'un serveur web de manière portable et efficace. Un serveur web héberge des classes Java servlets qui sont exécutées à l'intérieur du container web. Le serveur web associe une ou plusieurs URLs à chaque servlet. La servlet est invoquée lorsque des requêtes HTTP utilisateur sont soumises au serveur. Quand la servlet reçoit une requête du client, elle génère une réponse, éventuellement en utilisant la logique métier contenue dans des EJBs ou en interrogeant directement une base de données. Elle retourne alors une réponse HTML ou XML au demandeur.
Servlet : Avantages coté serveur Fournissent un moyen d'améliorer les serveurs web sur n'importe quelle plateforme, d'autant plus que les servlets sont indépendantes du serveur web S'exécutent dans un moteur de servlet (ou conteneur de servlet) utilisé pour établir le lien entre la servlet et le serveur web. On ne se soucie pas de détails techniques tels que la connexion au réseau, la mise en forme de la réponse à la norme HTTP, ...,
Servlet : Avantages coté serveur Beaucoup plus performantes que les scripts, car il s'agit de pseudo-code, chargé automatiquement lors du démarrage du serveur ou bien lors de la connexion du premier client. Elles sont donc actives (résidentes en mémoire) et prêtes à traiter les demandes des clients grâce à des threads, tandis qu'avec les langages de script traditionnels un nouveau processus est créé pour chaque requête HTTP. Une charge moins importante au niveau du processeur du serveur (d'autant plus qu'un système de cache peut permettre de stocker les calculs déjà accomplis), ainsi que de prendre une place moins importante en mémoire.
Servlet : Avantages coté serveur La réutilisabilité des servlets : permettre de créer des composants encapsulant des services similaires, afin de pouvoir les réutiliser dans des applications futures. Une servlet, peut utiliser toutes les API Java afin de communiquer avec des applications extérieures, se connecter à des bases de données, accéder aux entrée-sorties (fichiers par exemple), ...
Présentation Avantage Servlet: Inconvénient Servlet : inhérents à Java : JSDK ou JDK1.2 gratuit et portable par rapport aux Applets : plus facile à développer, meilleures performances, client léger , Inconvénient Servlet : interface graphique utilisateur limitée à HTML.
L’API Servlet (1/2) Une servlet doit implémenter l’interface javax.servlet.Servlet soit directement, soit en dérivant d’une classe implémentant cette interface comme : javax.servlet.GenericServlet javax.servlet.http.HttpServlet (particulièrement désignée pour des requêtes et réponses HTTP) cette interface possède les méthodes pour : initialiser la servlet : init() recevoir et répondre aux requêtes des clients : service() détruire la servlet et ses ressources : destroy()
javax.servlet.HttpServlet L’API Servlet (2/2) javax.servlet.Servlet Généralisation Spécification Servlet interface javax.servlet.GenericServlet GenericServlet classe abstraite javax.servlet.HttpServlet HttpServlet classe abstraite MapremiereServlet classe définie par l ’utilisateur
Modèle de programmation Les servlets suivent un modèle de programmation requête-service-réponse : Requête : objet javax.servlet.ServletRequest contient les informations nécessaires pour une communication du client vers le serveur Service : méthode service() invoquée Réponse : objet javax.servlet.ServletResponse contient les informations nécessaires pour une communication du serveur vers le client
Servlet : Mise en oeuvre Lorsqu'une servlet est appelée par un client, la méthode service() est exécutée. Celle-ci est le principal point d'entrée de toute servlet et accepte deux objets en paramètres: void service ( ServletRequest req , ServletResponse res ); l'objet ServletRequest encapsulant la requête du client, (contient l'ensemble des paramètres passés à la servlet (informations sur l'environnement du client, cookies du client, URL demandée, ...) l'objet ServletResponse permettant de renvoyer une réponse au client (envoyer des informations au navigateur). Il est ainsi possible de créer des en-têtes HTTP (headers), d'envoyer des cookies au navigateur du client, ...
Servlet : Développement Afin de développer un servlet fonctionnant avec le protocole HTTP, il suffit de créer une classe étendant HttpServlet (qui implémente elle-même l'interface Servlet). La classe HttpServlet (dérivant de GenericServlet) permet de fournir une implémentation de l'interface Servlet spécifique à HTTP. La classe HttpServlet surcharge la méthode service en lisant la méthode HTTP utilisée par le client, puis en redirigeant la requête vers une méthode appropriée. Si la méthode utilisée est GET, il suffit de redéfinir la méthode public void doGet( HttpServletRequest req, HttpServletResponse res); Si la méthode utilisée est POST, il suffit de redéfinir la méthode public void doPost ( HttpServletRequest req, HttpServletResponse res);
Servlet : exemple import javax.servlet.*; import javax.servlet.http.*; public class ServletDeBase extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException { // lecture de la requête // traitements // envoi de la réponse } }
Servlet : L’objet HttpServletRequest : la méthode DoXXX Description String getMethod() Récupère la méthode HTTP utilisée par le client String getHeader(String Key) Récupère la valeur de l'attribut Key de l'en-tête String getRemoteHost() Récupère le nom de domaine du client String getRemoteAddr() Récupère l‘adresse IP du client String getParameter(String Key) Récupère la valeur du paramètre Key (clé) d'un formulaire. Lorsque plusieurs valeurs sont présentes, la première est retournée String getParameterValues(String Key) Récupère les valeurs correspondant au paramètre Key (clé) d'un formulaire, c'est-à-dire dans le cas d'une sélection multiple (cases à cocher, listes à choix multiples) les valeurs de toutes les entités sélectionnées Enumeration getParameterNames() Retourne un objet Enumeration contenant la liste des noms des paramètres passés à la requête String getServerName() Récupère le nom du serveur String getServerPort() Récupère le numéro de port du serveur
Servlet : L’objet HttpServletResponse la réponse à fournir à l'utilisateur est représentée sous forme d'objet HttpServletResponse. Méthode Description String setStatus (int StatusCode) Définit le code de retour de la réponse void setHeader (String Nom, String Valeur) Définit une paire clé/valeur dans les entêtes void setContentType (String type) Définit le type MIME de la réponse HTTP, c'est-à-dire le type de données envoyées au navigateur void setContentLength (int len) Définit la taille de la réponse PrintWriter getWriter() Retourne un objet PrintWriter permettant d'envoyer du texte au navigateur client. Il se charge de convertir au format approprié les caractères Unicode utilisés par Java ServletOutputStream getOutputStream() Définit un flot de données à envoyer au client, par l'intermédiaire d'un objet ServletOutputStream, dérivé de la classe java.io.OutpuStream void sendredirect (String location) Permet de rediriger le client vers l'URL location
Exemple de servlet L’interface d’un objet ASP import javax. servlet.*; import javax. servlet. http.*; import java. io.*; public class HelloServlet extends HttpServlet { public void service( ServletRequest request, ServletResponse response ) throws ServletException, IOException { response. setContentType( "text/ html" ); PrintWriter out = response. getWriter(); imposé L’interface d’un objet ASP imposé par l'API servlet ce qui suit est en HTML récupère un flux pour générer le résultat out. println( "< html>< body>" ); out. println( "< h1> Hello depuis une servlet</ h1>" ); out. println( "</ body></ html>" ); } } génération du code HTML Compilation : HelloServlet. class installé dans l'arborescence de Tomcat Chargement via une URL de type http://.../ servlet/ HelloServlet
Exemple de servlet (code complet) 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(); } } L’interface d’un objet ASP
Exemple de servlet (code complet): Explication du code La classe HttpServlet a été étendue : public class PremiereServlet extends HttpServlet {} Lorsque la servlet est instanciée, il peut être intéressant d'effectuer des opérations qui seront utiles tout au long du cycle de vie de la servlet (se connecter à une base de données, ouvrir un fichier, ...). Pour ce faire, il s'agit de surcharger la méthode init() de la servlet. public void init() {} L’interface d’un objet ASP
Exemple de servlet (code complet): Explication du code A chaque requête, la méthode service() est invoquée. Celle-ci détermine le type de requête dont il s'agit, puis transmet la requête et la réponse à la méthode adéquate (doGet() ou doPost()), on ne s'intéresse qu'à la méthode GET la méthode doGet() a été surchargée : public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {} L’interface d’un objet ASP
Exemple de servlet (code complet): Explication du code Par contre l'objet HttpServletResponse permet de renvoyer une page à l'utilisateur: 1-définir le type de données qui vont être envoyées au client : la méthode setContentType() de l'objet HttpServletResponse 2- créer un objet PrintWriter grâce à la méthode getWriter() : envoyer du texte formatté au navigateur PrintWriter out = res.getWriter(); 3- utiliser la méthode println() de l'objet PrintWriter afin d'envoyer les données textuelles au navigateur, 4- fermer l'objet PrintWriter lorsqu'il n'est plus utile avec sa méthode close() L’interface d’un objet ASP
Déploiement de servlets
Déclaration d’une Servlet au sein d’une application Web (1/5) <web-app> <servlet> <servlet-name>……..</servlet-name> <servlet-class>……..</servlet-class> <init-param> < param-name> …….. </param-name> < param-value> …….. </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>…….</servlet-name> <url-pattern>…..…..</url-pattern> </servlet-mapping> </web-app> Web.xml La déclaration d’une Servlet dans une application Web se fait dans le descripteur de déploiement «web.xml».
Déclaration d’une Servlet au sein d’une application Web (2/5) <web-app> ……. </web-app>: encapsule l’ensemble des éléments servant à la configuration de l’application Web. <servlet> ……… </servlet>: encapsule l’ensemble des éléments servant à la configuration de chaque Servlet. <servlet-name> ………… </servlet-name>: contient une chaîne de caractère identifiant la Servlet au sein de l’application web.
Déclaration d’une Servlet au sein d’une application Web (3/5) <servlet-class> ………… </servlet-class>: contient le nom complet de la classe de Servlet (package compris). <init-param> …. </init-param> : Encapsule les paramètres d’initialisation de la Servlet. Chaque élément <init-param> ….. </init-param> correspond à un paramètre représenté par une paire nom/valeur avec les éléments : <param-name> ….. </param-name>, <param-value> ….. </param-value>.
Déclaration d’une Servlet au sein d’une application Web (4/5) <servlet-mapping> ………… </servlet-mapping>: contient des informations permettant de définir la relation entre les URL et les servlets. <url-pattern>…….</url-pattern> définit comment une Servlet est invoquée.
Déclaration d’une Servlet au sein d’une application Web (5/5) <web-app> <servlet> <servlet-name>Hello</servlet-name> <servlet-class>Hello</servlet-class> </servlet> <servlet-mapping> <url-pattern>/servlet/Hello</url-pattern> </servlet-mapping> </web-app> web.xml Déclaration de la Servlet « Hello » dans le descripteur de déploiement «web.xml»
Invocation d’une Servlet à partir d’un navigateur Web (1/7) Invoquer une Servlet c’est utiliser tout d’abord un conteneur Web (e.g., : Apache TOMCAT 5.0) pour sa mise en œuvre. Déployer la Servlet au sein d’une application Web. Crée un nouveau dossier nommée MaWebApp dans le dossier webapps de TOMCAT. Le dossier MaWebApp doit contenir un sous dossier nommé Web-INF, qui lui-même contient le descripteur de déploiement web.xml un sous-dossier nommé classes, qui contient le fichier compilé Hello.class de la Servlet. Deux possibilités d’invocation d’une Servlet : invocation de la méthode doGet(…), invocation de la méthode doPost(..).
Invocation d’une Servlet à partir d’un navigateur Web (2/7) 1ère Invocation de la méthode doGet(…) : Saisie de l’URL de la Servlet dans la barre d’adresse du navigateur. http://<hôte>:<port>/<webApp>/servlet/<servlet> http://localhost:8080/MaWebApp/servlet/Hello Hello http://localhost:8080/MaWebApp/servlet/Hello
Invocation d’une Servlet à partir d’un navigateur Web (3/7) 2ième Invocation de la méthode doGet(…): Clique sur un lien hypertexte qui pointe sur l’URL de la Servlet. <HTML> <HEAD> <TITLE> Test de la servlet Heloo par clic sur lien </TITLE> </HEAD> <BODY> <P> <A href="/MaWebApp/servlet/Hello"> Cliquer pour tester la Servlet Hello </A> </P> </BODY> </HTML> Index.html Cliquer pour tester la Servlet Hello Hello
Invocation d’une Servlet à partir d’un navigateur Web (4/7) Invocation de la méthode doPost(…) : La méthode doPost() d’une Servlet est invoquée principalement lors de l’envoi des données saisies dans un formulaire HTML (par un clic sur un bouton de type submit). Exemple de méthode doPost() qui retourne une chaîne de caractères concaténée avec les valeurs des paramètres transmis par le client.
Invocation d’une Servlet à partir d’un navigateur Web (5/7) Invocation de la méthode doPost(…) : <HTML> <HEAD> <TITLE> Test de la servlet Hello </TITLE> </HEAD> <BODY> <FORM action = "/test/servlet/Hello" method ="post"> <P> Prenom : <INPUT type ="text" name="prenom"> <BR> Nom : <INPUT type ="text" name="nom"> <INPUT type ="submit" value="Valider"> </P> </FORM> </BODY> </HTML> Index.html
Invocation d’une Servlet à partir d’un navigateur Web (6/7) Invocation de la méthode doPost(…) : Hello.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Hello extends HttpServlet{ public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String prenom = req.getParameter ("prenom"); String nom = req.getParameter("nom"); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML><BODY>"); out.println("<H1>Bonjour" +prenom+" "+ nom+"."+ "</H1>" ); out.println("</HTML><BODY> "); }
Cycle de vie d’une servlet
Structure de base d’une servlet import javax.servlet.*; public class first implements Servlet { public void init(ServletConf config) throws ServletException {…} public void service(ServletRequest req, ServletResponse rep) throws ServletException, IOException {…} public void destroy() {…} }
Le cycle de vie d’une servlet
Le cycle de vie d’une servlet Une servlet a le cycle de vie suivant : 1. la servlet est créée puis initialisée (init()) cette méthode n’est appelée par le serveur qu’une seule fois lors du chargement 2. traitements des requêtes (service()) cette méthode est appelée automatiquement par le serveur à chaque requête du client 3. la servlet est détruite (destroy()) cette méthode n’est appelée par le serveur qu’une seule fois à la fin, elle permet de libérer des ressources
Les servlets de type : HttpServlet Pour faciliter le traitement particulier des serveurs Web, la classe Servlet est affinée en javax.servlet.http.HttpServlet 2 méthodes remplacent avantageusement la méthode service() de la classe mère : doGet() : pour traiter des requêtes Http de type GET doPost() : pour traiter des requêtes Http de type POST la servlet doit obligatoirement contenir l’une ou l’autre de ces 2 méthodes service() de HttpServlet appelle automatiquement la bonne méthode en fonction du type de la requête
Cycle de vie d’une Servlet HTTP Instanciation et chargement Instanciation et chargement Initialisation invocation de la méthode init() Initialisation invocation de la méthode init() Le conteneur Web exécute l’instance de la Servlet dans un contexte multitâche. Chaque thread invoque la méthode service() qui s’occupe d’exécuter la méthode doGet() ou doPost(). L’instance de la Servlet reste en mémoire jusqu’à l’arrêt du serveur. La méthode destory() est ainsi invoquée indiquant que la Servlet n’est plus en service et l’instance de la Servlet est supprimée par le garbage collector. Le conteneur Web initialise la Servlet en utilisant éventuellement le fichier web.xml. L’initialisation se fait une seul fois. Le conteneur Web crée une instance de la classe de Servlet et la charge en mémoire. La classe Java de la Servlet est déployée au sein de conteneur Web Classe de Servlet Classe de Servlet Requêtes clients En service invocation de la méthode service() En service invocation de la méthode service() Destruction invocation de la méthode destory() puis finalize() Destruction invocation de la méthode destory() puis finalize() Arrêt du serveur
Ecrire une servlet Http (1) La servlet doit dériver de la classe javax.servlet.http.HttpServlet Il faut redéfinir les méthodes : init(), destroy() et getServletInfo() doPost() ou doGet() (ou doPut() ou doDelete() doHead() ou doOptions() ou doTrace() ) suivant le type de requêtes Http du client que la servlet doit traiter : POST, GET, PUT ou DELETE
Ecrire une servlet Http (2) Utiliser les objets HttpServletRequest et HttpServletResponse passés en paramètres des méthodes doGet() ou doPost() pour implémenter le service HttpServletRequest contient les renseignements sur le formulaire HTML initial (utile pour doPost()) HttpServletResponse contient le flux de sortie pour la génération de la page HTML résultat ce flux de sortie est obtenu par les méthodes : getWriter() : recommandé pour retourner du texte getOutputStream() : recommandé pour des données binaires
Squelette d’une servlet Http (GET) import javax.servlet.*; import javax.servlet.http.*; public class SimpleServlet extends HttpServlet { public void init (HttpServletConfig c) throws ServletException {…} public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {…} public void destroy() {…} public String getServletInfo() {…} }
Exemple simple (GET) public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // 1. spécifier le contenu de la réponse res.setContentType("text/html"); // 2. récupérer le conteneur de la réponse PrintWriter out = res.getWriter(); // 3. remplir le conteneur par la réponse out.println("<HEAD><TITLE>SimpleServlet"); out.println("</TITLE></HEAD><BODY>"); out.println("<h1>Une servlet simple</h1>"); out.println("<P>C’est la sortie de la servlet</P>"); out.println("</BODY>"); // finalement, envoyer le contenu au client out.close();
Quelques trucs: mettre les servlets en paquet Pour éviter les conflits de noms placer les fichiers .class dans un répertoire (exemple MesServlets) qui a le même nom que celui du package. Insérer l’instruction d’appartenance au paquet au début du fichier .java de la servlet package MesServlets; Inclure le nom du paquet dans l ’URL http://localhost/servlet/MesServlets.HelloWWW2
Quelques trucs Néanmoins : <DOCTYPE...> et <HEAD...> toujours pareils Faire une classe utilitaire ! public class ServletUtilities { public static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">"; public static String headWithTitle(String title) { return(DOCTYPE + "\n" + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n"); } ... }
HelloWWW avec ServletUtilities import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWWW3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println(ServletUtilities.headWithTitle("Hello") + "<BODY>\n" + "<H1>Hello WWW</H1>\n" + "</BODY></HTML>"); }
Les données des formulaires Récupérées par la méthode getParameter()de la classe HttpServletRequest Le nom du paramètre est passé comme argument Les données envoyées pas la méthode GET sont traitées de la même manière que celles envoyées par POST La valeur retournée est de type String, il correspond à la première occurrence du paramètre (un paramètre peut avoir plusieurs valeurs) Si le paramètre n ’a pas une valeur la chaîne vide est retournée Si le champ ne fait pas partie du formulaire, alors null est retourné par cette méthode.
Les données des formulaires Si le paramètre a plusieurs valeurs il faut utiliser la méthode getParameterValues() au lieu de getParameter() Cette méthode retourne un tableau de type String
Les données des formulaires Pour la vérification du code, il est utile de récupérer la liste des noms des paramètres avec la méthode getParameterNames() qui retourne une valeur de type Enumeration Chaque nom peut être transformé en String et utilisé par la suite dans getParameter().
Récupération des données d'un formulaire (Recap…) public String getParameter(String Key) : permet de retourner le valeur d'un champ dont on a passé le nom (sensibles à la casse) en argument ( Si le champ n'existe pas, la valeur null est retournée). public String[] getParameterValues(String Key) : à utiliser Lorsqu'un champ d'un formulaire peut avoir plusieurs valeurs (liste à choix multiples, cases à cocher,.. Retourne un tableau contenant l'ensemble des valeurs affectées à la clé spécifiée en paramètre. Enumeration getParameterNames() :Pour connaître l'ensemble des noms des champs du formulaire passé à la servlet. Retourne un objet Enumeration, contenant la liste des champs du formulaire. Il est possible de transformer chaque entrée en chaîne, puis de la traiter avec la méthode getParameter() afin de récupérer sa valeur.
Récupération des données d'un formulaire : Exemple L’interface d’un objet ASP Le Formulaire <FORM Method="POST" Action="http://serveur/servlet/UserInfo"> Nom : <INPUT type=text size=20 name=Nom><BR> Prénom : <INPUT type=text size=20 name=Prenom> <BR>Age : <INPUT type=text size=2 name=Age><BR> <INPUT type=submit value=Envoyer> </FORM>
Récupération des données d'un formulaire : Exemple La Servelet de Traitement import java.io.*;import javax.servlet.*;import javax.servlet.http.*; public class UserInfo extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<HTML>\n<BODY>\n" + "<H1>Recapitulatif des informations</H1>\n" + "<UL>\n" + " <LI>Nom: " + request.getParameter("Nom") + "\n" + " <LI>Prenom: " + request.getParameter("Prenom") + "\n" + " <LI>Age: " + request.getParameter("Age") + "\n" + "</UL>\n" + "</BODY></HTML>"); }} L’interface d’un objet ASP
Lister l'ensemble des paramètres d'un formulaire (1/2) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Parametres extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>\n" + "<h1>Tableau des paramètres</h1>\n" + "<table border=\"1\“ >\n" + "<tr>\n" + "<th>Nom</th><th>Valeur(s)</th>"); Enumeration NomsParam = request.getParameterNames(); while(NomsParam.hasMoreElements()) { String NomParam = (String)NomsParam.nextElement(); out.println("<tr><td>" + NomParam + "</td></tr>\n"); L’interface d’un objet ASP
Lister l'ensemble des paramètres d'un formulaire (2/2) String[] ValeursParam = request.getParameterValues(NomParam); if (paramValues.length == 1) { String ValeurParam = ValeursParam[0]; if (ValeurParam.length() == 0) out.println("<td><b>Aucune valeur</i></td>"); else out.println(ValeurParam); } else { out.println("<td><ul>"); for(int i=0; i < ValeursParam.length; i++) {out.println("<li>" + ValeursParam[i] + "</li>");} out.println("</ul></td></tr>"); } } out.println("</table>\n</body></html>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }} L’interface d’un objet ASP
Traitement des entêtes de requêtes Exemple d’une requête HTTP 1.1 GET /search?keywords=servlets+jsp HTTP/1.1 Accept: image/gif, image/jpg, */* Accept-Encoding: gzip Connection: Keep-Alive Cookie: userID=id456578 Host: www.somebookstore.com Referer: http://www.somebookstore.com/findbooks.html User-Agent: Mozilla/4.7 [en] (Win98; U)
Lecture des entêtes de requêtes Général getHeader() (getHeaders() (version 2.2)) getHeader("Accept-Encoding" ) getHeader("Referer" ) getHeaderNames() Spécialisé getCookies() getRemoteAddr() et getRemoteHost() getContentLength() getContentType() information liée getMethod(), getRequestURI(), getProtocol()
Afficher toutes les entêtes out.println("<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<B>Request Method: </B>" + request.getMethod() + "<BR>\n" + "<B>Request URI: </B>" + request.getRequestURI() + "<BR>\n" + "<B>Request Protocol: </B>" + request.getProtocol() + "<BR><BR>\n" + "<B>Adresse IP Client: </B>" + request.getRemoteAddr() + "<BR>\n" + "<B>Nom Client: </B>" + request.getRemoteHost() + "<BR>\n" +
Afficher toutes les entêtes (suite) "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TH>Header Name<TH>Header Value"); Enumeration headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = (String)headerNames.nextElement(); out.println("<TR><TD>" + headerName); out.println(" <TD>" + request.getHeader(headerName)); } out.println("</TABLE>\n</BODY></HTML>");
Résultat affiche par Internet Explorer
Suivi de Sessions
Problématique Protocole HTTP = protocole déconnecté Différent de Telnet et ftp Traite les requêtes et les réponses comme transactions simples isolées Certaines applications WEB (E-Commerce) ont besoin de maintenir une mémoire entre deux requêtes: Exemple : le chariot (panier) de supermarché mis en place pour effectuer des achats sur le WEB Pour ce faire : concept de « suivi de sessions »
Servlet Session? Très simple avec l’API des servlets : Objet HttpSession Principe : Un objet session peut être associé à chaque requête Il sert comme « conteneur » pour des informations persistantes Durée de vie limitée = celle de la session
Traitement des objets HttpSession Tout d’abord il faut tester s’il y’a un objet session dans la requête: Si la méthode getSession() retourne null, alors il n’y a pas de session et il faut créer une nouvelle. Avec l’instruction suivante on retourne la session courante s’il y en a une, sinon on crée une nouvelle HttpSession session = request.getSession(true); On peut toujours tester par la méthode isNew() si une session est nouvelle
Traitement des objets HttpSession L’information contenue dans un objet HttpSession est de la forme (attribut : String, valeur : Object)(attribut,valeur)(attribut, valeur)… La méthode getAttribute(String) permet d’extraire la valeur correspondante à un attribut donné dans l’objet session. Elle retourne un Objet de type Object il est nécessaire de faire le casting pour manipuler la valeur retournée. Exemple : Panier p=(Panier)session.getAttribute("Schopping"); Cette méthode retourne null si l’attribut n’existe pas.
Traitement des objets HttpSession La méthode setAttribute(String,Object) Permet d’insérer une paire (attribut, valeur) dans un objet de type HttpSession Si l’attribut existe déjà dans l’objet session sa valeur sera mise à jour. Exemple : Panier p = new Panier(); session.settAttribute("Schopping", p);
Traitement des objets HttpSession La méthode removeAttribute(String) Permet de supprimer un pair (attribut, valeur) dans un objet de type HttpSession Exemple : session.removeValue("Schopping");
Traitement des objets HttpSession Les méthodes : String[] getValueNames() Enumeration getAttributeNames() permettent de retourner les noms de tous les attributs dans un objet session. La méthode : String getId() retourne l’identificateur unique généré pour chaque session void invalidate() permet d’annuler une session et détacher tous les objets associés
Configuration des servlets
Configuration de Servlet : Interface ServletConfig Les informations de configuration d’une Servlet au sein d’une application Web (nom de la Servlet, les paramètres sous formes de nom/valeur) sont représentées par un objet de type javax.servlet.ServletConfig. L’objet javax.servlet.ServletConfig est crée par le conteneur web pour chaque élément <servlet> déclaré dans le descripteur de déploiement web.xml de l’application web. Les informations de configurations représentées par l’objet javax.servlet.ServletConfig peuvent ensuite être récupérées par la Servlet de préférence lors de sa phase d’initialisation au sein de la redéfinition de la méthode init(…).
Méthodes de l’interface ServletConfig (1/2) Méthodes de l’interface javax.servlet.ServletConfig dédiées à la récupération des paramètres d’une Servlet: public String getServletName() : Récupérer le nom de la Servlet déclaré au sein du descripteur de déploiement ou le nom de la classe de la Servlet. public String getInitParameter(String nom) : Récupérer une chaîne de caractères contenant la valeur d’un paramètre nommé nom ou la valeur null si le paramètre n’existe pas.
Méthodes de l’interface ServletConfig (2/2) public java.util.Enumeration getInitParameterNames(): Récupérer sous la forme d’un objet de type java.util.Enumeration l’ensemble des noms des paramètres déclarés pour la Servlet. public ServletContext getServletContext(): Récupérer une référence sur le contexte d’exécution de la Servlet qui permet d’interagir avec le conteneur web de l’application Web.
Initialisation d’une Servlet : redéfinition de la méthode init() (1/3) Syntaxe de la méthode init() : public void init(ServletConfig config ) throws ServletExeption; public void init() throws ServletExeption; <web-app> <servlet> <servlet-name>InitServlet</servlet-name> <servlet-class>InitServlet</servlet-class> <init-param> < param-name> param1 </param-name> < param-value> value1 </param-value> </init-param> < param-name> param2 </param-name> < param-value> value2 </param-value> </servlet> <servlet-mapping> <url-pattern>/servlet/InitServlet</url-pattern> </servlet-mapping> </web-app> web.xml
Initialisation d’une Servlet : redéfinition de la méthode init() (2/3) Exemple de manipulation : import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class InitServlet extends HttpServlet{ Vector vector=new Vector(); public void init() throws ServletException{ ServletConfig config =getServletConfig(); Enumeration lstParams = config.getInitParameterNames( ); vector.add(" Nom de la Servlet : " + config.getServletName()); while (lstParams.hasMoreElements() ) { String nomParam = (String) lstParams.nextElement(); vector.add("{nom=" + nomParam+ " , valeur=" +config.getInitParameter(nomParam)+ "} "); } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); out.write(vector.toString()); InitServlet.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class InitServlet extends HttpServlet{ Vector vector=new Vector(); public void init(ServletConfig config) throws ServletException{ super.init(config); Enumeration lstParams = config.getInitParameterNames( ); vector.add(" Nom de la Servlet : " + config.getServletName()); while (lstParams.hasMoreElements() ) { String nomParam = (String) lstParams.nextElement(); vector.add("{nom" + nomParam+ " , valeur=" +config.getInitParameter(nomParam)+ "} "); } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); out.write(vector.toString()); InitServlet.java
Initialisation d’une Servlet : redéfinition de la méthode init() (3/3) Exemple de manipulation (suite): [Nom de la Servlet :InitServlet, {nom=param2 , valeur=value2} , {nom=param1 , valeur=value1} ] http://localhost:8080/MaWebApp/servlet/InitServlet InitServlet
Paramètres de l’application Web (1/9) De la même manière que pour chaque Servlet d’une application Web, il est possible de déclarer des paramètres globaux (informations de configuration) pour toute l’application Web. Ces paramètres peuvent être utiles pour déclarer des informations susceptibles d’être utilisées par plusieurs Servlets de l’application Web: Nom et e-mail de l’administrateur, qui peuvent être utilisés pour générer une page d’erreur à un client. Nom d’hôte ou adresse IP de machines distantes, qui peuvent être utiles pour l’accès à des ressources distantes Nom de la base de données, nom du pilote JDBC à utiliser, nom d’utilisateur et mot de passe pour établir la connexion, Etc,
Paramètres de l’application Web (2/9) Les informations de configuration d’une application Web sont représentées par un objet de type javax.servlet.ServletContext. Chaque Servlet d’une même application Web a donc accès à ces informations. L’objet javax.servlet.ServletContext propose des méthodes permettant de travailler principalement avec deux catégories de données : Accéder à des paramètres globaux de l’application Web déclarés dans son descripteur de déploiement web.xml. Créer, lire et supprimer des attributs de façon logicielle, permettant le partage de ressources entre les Servlets d’une même application Web.
Paramètres de l’application Web (3/9) Configuration des paramètres globaux dans le descripteur de déploiement : web.xml <web-app> <context-param> <param-name>……</param-name> <param-value>……..</param-value> </context-param> <servlet> <servlet-name>InitServlet</servlet-name> <servlet-class>InitServlet</servlet-class> …………… </servlet> <servlet-mapping> <url-pattern>/servlet/InitServlet</url-pattern> </servlet-mapping> </web-app> web.xml 2. Servlets Java
Paramètres de l’application Web (4/9) Méthodes de l’interface javax.servlet.ServletContext dédiées à la récupération des paramètres globaux d’initialisation: public String getInitParameter(String nom) : Récupérer une chaîne de caractères contenant la valeur d’un paramètre nommé nom ou la valeur null si le paramètre n’existe pas. public java.util.Enumeration getInitParameterNames(): Récupérer sous la forme d’un objet de type java.util.Enumeration l’ensemble des noms des paramètres déclarés pour la Servlet.
Paramètres de l’application Web (5/9) Exemple de manipulation : <web-app> <context-param> <param-name>nomAdmin</param-name> <param-value> Administrateur</param-value> </context-param> <param-name>emailAdmin</param-name> <param-value>tt@fst.rnu.tn. </param-value> ………………… <servlet> <servlet-name>ErreurServlet</servlet-name> <servlet-class>ErreurServlet</servlet-class> </servlet> <servlet-mapping> <url-pattern>/servlet/ErreurServlet</url-pattern> </servlet-mapping> </web-app> web.xml
Paramètres de l’application Web (6/9) Exemple de manipulation : import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ErreurServlet extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ServletContext application=getServletContext(); String nom= application.getInitParameter ("nomAdmin"); String email= application.getInitParameter (" emailAdmin"); res.setContentType(" text/html"); PrintWriter out = res.getWriter(); out.println("<HTML><BODY>"); out.println("<H1>Erreur de l’application</H1>" ); out.println("<BR><H4>Veuillez contacter <B>" + nom + "</B>" ); out.println("<A href =\"mailto:"+ email + "\" >"+email+"</A>" ); out.println("<H4></BODY></HTML> "); } ErreurServlet.java
Paramètres de l’application Web (8/9) Méthodes de l’interface javax.servlet.ServletContext dédiées à la gestion logicielle des attributs du contexte d’application: public String setAttribute(String nom, Object objet) : Créer un attribut dans le contexte de l’application Web. Si le nom de l’attribut existe déjà, la valeur existante est remplacée par la nouvelle. public Object getAttribute(String nom) : Récupérer la valeur d’un attribut dont le nom est passé en paramètre, ou la valeur null si l’attribut n’existe pas. public java.util.Enumeration getAttributeNames(): Récupérer sous la forme d’un objet de type java.util.Enumeration le nom de tous les attributs stockées dans l’application Web. public void removeAttribute(String nom): Supprimer un attribut du contexte de l’application Web, dont le nom est passé en paramètre.
Paramètres de l’application Web (9/9) Exemple de manipulation : …….. Employé emp1 = new Employé (" Walid ", "MAHDI "); Employé emp2 = new Employé ("toto ", "titi "); Employé emp3 = new Employé (" tata ", "tatou "); ……… javax.servlet.ServletContext contextApp = getServletContext(); contextApp.setAttribute(" Employé1 ", emp1); contextApp.setAttribute(" Employé2 ", emp2); contextApp.setAttribute(" Employé3 ", emp3); …… … javax.servlet.ServletContext contextApp = getServletContext(); Java.util.Enumeration nomAttributs = contextApp.getAttributeNames( ); while ( nomAttributs.hasMoreElements() ) { String nom = (String) nomAttributs.nextElement(); Employé e = (Employé) contextApp.getAttribute(nom); ………. contextApp.removeAttribute(nom); ……
Interfaces ServletRequest et HttpServletRequest (1/7) Méthodes de Récupération d’informations sur l’URL de la requête public String getScheme( ) : Retourne le nom du protocole utilisé par le client pour émettre sa requête. Par exemple : http, ftp, etc. public String getContextPath( ) : Retourne sous la forme d’une chaîne de caractères commençant par un /, la portion de l’URL de la requête correspondant au nom du contexte de l’application Web . Par exemple : /MaWebApp. public String getMethod(): Retourne le nom de la méthode HTTP(GET, POST, etc) utilisée par le client pour émettre sa requête.
Interfaces ServletRequest et HttpServletRequest (2/7) Méthodes de récupération d’informations sur l’URL de la requête (suite) public String getRequestURL( ) : Retourne l’URL que le client a utilisée pour émettre sa requête. L’URL retournée contient le nom du protocole, le nom du serveur, le numéro de port et le chemin d’invocation de la ressource web, mais pas les paramètres de la chaîne de requête. Par exemple : http://localhost:8080/test/servlet/Hello. public String getServletPath( ) : Retourne la partie de l’URL qui invoque la Servlet/JSP, composée du chemin et du nom ou de l’alias de la Servlet/JSP. Par exemple : /servlet/Hello.
Interfaces ServletRequest et HttpServletRequest (3/7) Méthodes de récupération d’informations sur le client public String getRemoteAddr( ) : Retourne l’adresse IP du client qui a émis la requête. Par exemple : 127.0.0.1 public String getRemoteHost( ) : Retourne le nom complet du client qui a émis la requête. Par exemple : 127.0.0.1 public String getRemoteUser( ) : Retourne le nom de l’utilisateur qui a envoyé la requête si celui s’est authentifié au préalable, sinon retourne la valeur null. 2. Servlets Java
Interfaces ServletRequest et HttpServletRequest (4/7) Méthodes de récupération d’informations sur le serveur public String getServerName( ) : Retourne le nom d’hôte du serveur qui a reçu la requête. Par exemple : loclahost public String getServerPort( ) : Retourne le numéro de port d’écoute du serveur qui a reçu la requête. Par exemple : 8080
Interfaces ServletRequest et HttpServletRequest (5/7) Méthodes de récupération d’informations dans l’en-tête HTTP public String getHeader(String nom ) : Retourne la valeur de l’entête nommé, passé en paramètre ou la valeur null si l’entête n’existe pas. Le nom de l’entête est sensible à la casse. Par exemple : getHeader("Accept-Language") retourne fr. public java.util.Enumeration getHeaders(String nom ) : Retourne sous la forme d’un objet de type java.util.Enumeration l’ensemble des valeurs de l’en-tête de la requête spécifié en paramètre. public java.util.Enumeration getHeaderNames() : Retourne sous la forme d’un objet de type java.util.Enumeration l’ensemble des noms des en-têtes contenus dans la requête.
Interfaces ServletRequest et HttpServletRequest (6/7) Exemple de manipulation : import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class AfficheHeaders extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); res.setContentType("Text/plain"); Enumeration enum = req.getHeaderNames( ); while (enum.hasMoreElements() ) { String headerNom = (String) enum.nextElement(); out.println(headerNom+" = "+ req.getHeader(headerNom)); } AfficheHeaders.java
Interfaces ServletRequest et HttpServletRequest (7/7) Exemple de manipulation (suite): AfficheHeaders http://localhost:8080/MaWebApp/servlet/AfficheHeaders accept = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shoc accept-language = fr accept-encoding = gzip, deflate user-agent = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; ESB{27A4ABBB-B657 host = localhost:8080 connection = Keep-Alive
Interfaces ServletResponse et HttpServletResponse (1/7) Méthodes de déclaration du type du contenu et de la taille de la réponse public void setContentType(String type ) : Spécifier le type MIMIE de contenu du corps de la réponse HTTP. Par exemple text/html pour du HTML, text/plain pour du texte brut, application/pdf pour un document Adobe pdf … public void setContentLength(int taille) : Spécifier la taille du contenu de la réponse HTTP. Autrement dit définir l’en-tête HTTP Content-Length.
Interfaces ServletResponse et HttpServletResponse (2/7) Méthodes de renseignement des informations dans l’en-tête HTTP public void setHeader(String nom, String Valeur) : Initialiser un en-tête dans la réponse HTTP, avec le nom et la valeur spécifiés en paramètres. Si l’en-tête existe déjà, la nouvelle valeur remplace l’ancienne public void addHeader(String nom, String Valeur) : Ajouter un en-tête dans la réponse HTTP, avec le nom et la valeur spécifiés en paramètres. Cette méthode permet à un en-tête d’avoir plusieurs valeurs. public boolean containsHeader(String nom) : Retourne un booléen indiquant si un entête existe ou non.
Interfaces ServletResponse et HttpServletResponse (3/7) Méthodes d’envoi d’erreurs et d’états HTTP public void sendError(int sc) throws java.io.IOException public void sendError(int sc,String message) throws java.io.IOException Envoyer un code d’erreur HTTP au client. Par exemple SC-NOT-FOUND(404) ou SC_BAD_REQUEST (400) ou SC-SERVICE-UNAVAILABLE(503). public void sendStatus(int sc) : Appliquer un code d’état à la réponse HTTP quand il n’y a pas d’erreur, comme par exemple SC-OK(200) ou SC-CONTINUE(100).
Interfaces ServletResponse et HttpServletResponse (4/7) Méthodes de redirection d’URL public void sendRedirect(String url) throws java.io.IOException Envoyer au navigateur du client un ordre de redirection sur une autre ressources Web, qui peut être de la même application Web ou nom. L’URL de la ressources Web passée en paramètre peut être relative ou absolue. Exemple d’URL relative : res.sendRedirect("/MaWebApp/indentification.html" ) Exemple d’URL absolue : res.sendRedirect("http://www.tunisie.com" );
Interfaces ServletResponse et HttpServletResponse (5/7) Méthodes pull client Le pull client est similaire à la redirection, avec une différence principale : le navigateur affiche le contenu de la première page et attend un certain temps avant de retrouver et afficher le contenu de la page suivante. Utilités : Le contenu de la première page peut expliquer au client que la page demandée a été déplacée avant que la page suivante ne soit automatiquement chargée. Les pages peuvent être retrouvées en séquence, rendant ainsi possible une animation de mouvements.
Interfaces ServletResponse et HttpServletResponse (6/7) Méthodes pull client (suite) L’information de pull client est envoyée au client via l’en-tête HTTP Refresh. La valeur de cet en-tête indique le nombre de secondes pendant lesquelles la page doit être affichée avant d’aller chercher la prochaine et elle peut aussi inclure l’URL indiquant où aller la chercher. res.SetHeader("Refresh", "3" ); Indique au client de recharger la même Servlet après avoir affiché son contenu courant pendant trois secondes res.SetHeader("Refresh", "3;URL=http://www.tunsie.com"); Indique au client d’afficher la page d’accueil Tunisie après trois secondes.
Interfaces ServletResponse et HttpServletResponse (7/7) Exemple de manipulation : Mise à jour de l’heure courante import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class ClientPull extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("Text/plain"); PrintWriter out = res.getWriter(); res.setHeader ("Refresh", "60"); out.println(new Date().toString()); } ClientPull.java
Synchronisation des traitements : L’Interface SingleThreadModel (1/6) Par défaut une Servlet fonctionne dans un environnement multitâche. C’est-à-dire qu’à chaque requête reçue pour une Servlet, le conteneur Web crée un thread qui va exécuter la méthode de service d’une instance de la Servlet. Si la méthode de service travaille avec des variables d’instance de la Servlet; chaque thread peut modifier la valeur de ces variables indépendamment de la logique de traitement des autres threads. Obligation de garantir dans un certain cas un fonctionnement isolé de chaque thread.
Synchronisation des traitements : L’Interface SingleThreadModel (2/6) Exemple d’application posant un problème : Deux client désirent s’enregistrer sur votre site par l’intermédiaire d’un formulaire HTML. Ils envoient leurs données en même temps à destination d’une Servlet dont le rôle est de créer un enregistrement dans la tables clients d’une base de données. La Servlet doit donc procéder en deux étapes : Récupérer la plus grande valeur de clé primaire actuellement présente dans la Table. Créer un nouvel enregistrement dans la table avec les données du client, en donnant à la clé primaire la valeur maximale récupérée précédemment, plus un.
Synchronisation des traitements : L’Interface SingleThreadModel (3/6) Que se passe-t-il si deux instances de la Servlet effectuent la première étape du traitement en même temps ? Une seule des deux instances pourra exécuter la deuxième étape. L’autre instance obtient une erreur de la base de données, car elle tente de créer un doublon de clé primaire. Un seul des deux clients est donc enregistré sur votre site.
Synchronisation des traitements : L’Interface SingleThreadModel (4/6) Solution du problème : Avec l’implémentation de l’interface javax.servlet.SingleThreadModel, un conteneur Web prend en charge le fait qu’une instance de Servlet ne peut être exécutée par un seul thread à la fois. L’utilisation de l’interface javax.servlet.SingleThreadModel implique que le conteneur Web invoque la méthode de service dans un bloc synchronisé. Bien souvent, seules quelques instructions sont réellement critiques. Au lieu de synchroniser toute la méthode service, il est possible d’améliorer les performances en synchronisant uniquement les quelques instructions sensibles en utilisant tout simplement un ou plusieurs blocs synchronisés. import javax.servlet.*; ……………. public class MaServlet extends HttpServlet implements SingleThreadModel {…………}
Synchronisation des traitements : L’Interface SingleThreadModel (6/6) Exemple de syntaxe d’un bloc synchronisé dans une Servlet ……… Object obj = new Object(); public void doXXXX(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Synchronized(obj) { …………. }
Collaboration entre Servlets : L’Interface RequestDispatcher (1/2) Agrégation de résultats fournis par des Servlets : meilleure modularité, meilleure réutilisation. Servlet servlet1 servlet2 servlet3 servlet5 servlet4 2. Servlets Java
Collaboration entre Servlets : L’Interface RequestDispatcher (2/2) Obtention d’un RequestDispatcher : dans la méthode de traitement de requête de Servlet Redirection d’une requête dans méthode de traitement de requête, demande à une autre Servlet de répondre au client …………….. RequestDispatcher rd; rd = getServeletContext().getRequestDispatcher("/servlet/MaServlet"); if(rd==null) res.sendError(404); …………. rd.forward(req, res);
Un petit atelier
Réaliser la servelet qui interagit avec un flux d’objets pour inscrire ou désinscrire une liste d’émails
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ListManagerServlet extends HttpServlet { private Vector addresses; private String filename; public void init(ServletConfig config) throws ServletException super.init(config); filename = config.getInitParameter("addressfile"); if(filename == null) throw new UnavailableException(this, "la propriété \"addressfile\" "+ “doit etre égale a un nom de fichier");
try { ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename)); addresses = (Vector)in.readObject(); in.close(); } catch(FileNotFoundException e) { addresses = new Vector(); } catch(Exception e) throw new UnavailableException(this, "Erreur de lecture fichier d’addresses : "+e);
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print("<HTML><HEAD><TITLE>List Manager</TITLE></HEAD>"); out.print("<BODY><H3>Membres:</H3><UL>"); for(int i=0; i<addresses.size(); i++) out.print("<LI>" + addresses.elementAt(i)); out.print("</UL><HR><FORM METHOD=POST>"); out.print("Entrer votre addresse email: <INPUT TYPE=TEXT NAME=email><BR>"); out.print("<INPUT TYPE=SUBMIT NAME=action VALUE=subscribe>"); out.print("<INPUT TYPE=SUBMIT NAME=action VALUE=unsubscribe>"); out.print("</FORM></BODY></HTML>"); out.close(); }
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String email = req.getParameter("email"); String msg; if(email == null) { res.sendError(res.SC_BAD_REQUEST, « aucune addresse email specifiée."); return; } if(req.getParameter("action").equals("subscribe")) { if(subscribe(email)) msg = "Addresse " + email + “ inscrite."; else { res.sendError(res.SC_BAD_REQUEST, "Addresse " + email + " déja inscrite."); return; }
else { if(unsubscribe(email)) msg = "Addresse " + email + " supprimée else { if(unsubscribe(email)) msg = "Addresse " + email + " supprimée."; res.sendError(res.SC_BAD_REQUEST, "Addresse " + email + " non inscrite."); return; }
res. setContentType("text/html"); PrintWriter out = res res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print("<HTML><HEAD><TITLE>List Manager</TITLE></HEAD><BODY>"); out.print(msg); out.print("<HR><A HREF=\""); out.print(req.getRequestURI()); out.print("\">Afficher la liste</A></BODY></HTML>"); out.close(); }
private synchronized boolean subscribe(String email) throws IOException { if(addresses.contains(email)) return false; addresses.addElement(email); save(); return true; } private synchronized boolean unsubscribe(String email) throws IOException if(!addresses.removeElement(email)) return false;
private void save() throws IOException { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename)); out.writeObject(addresses); out.close(); }
Indeed, in addition to being a technique for classifying and defining concepts from the data, the fuzzy concept lattice may be exploited to discover dependencies among objects and the properties. The process may be undertaken in two different ways, depending on the peculiarities of the database and the needs of the users: (i) scan the whole lattice, or part of it, in order to generate a set of rules that can be later in a knowledge-based system, (ii) browse to check if a given rule holds, without necessarily generating the whole set of rules, but rather looking for a node with some specific description. The motivation behind this second usage is that it often happens that one wants to confirm a hypothesis or invalidate a claim based on the analysis of the input data Merci