Vous êtes sur la page 1sur 37

Collaboration de servlets

 Des servlets qui s'exécutent dans le même serveur peuvent


communiquer les unes avec les autres
Elles peuvent partager de l'information :
un état ( état des ventes, des achats, des clients, ...)
une ressource (connexion BD, un fichier statique, ...)
Elles peuvent partager le contrôle d'une même requête :
la requête reçue par une servlet peut être traitée en partie par une
autre servlet

Technologies de Programmation Web , HAMEL 2017 104


Collaboration de servlets :
Partage d'informations
 A toute application web est associé un contexte auquel les
servlets ont accès
 Un contexte d'application web est représenté par une instance
de la classe ServletContext (à partir de l’API Servlet 2.1)
 Les servlets accèdent au contexte courant par la méthode
getServletContext()
 ServletContext context = getServletContext();
 Les éléments du contexte se présentent comme des couples (
nom, objet )
 Les accesseurs aux éléments du contexte sont :
public void ServletContext.setAttribute(String name,Object o)
public Object ServletContext.getAttribute(String name)
public Enumeration ServletContext.getAttributeNames()
public void ServletContext.removeAttribute(String name)
Technologies de Programmation Web , HAMEL 2017 105
Collaboration de servlets :
Partage d'informations
 Chaque application web possède son propre contexte
 Pour partager des informations avec une autre application web
(située sur le même serveur), il faut accéder à un autre contexte

// accès au contexte courant


ServletContext contexteCourant = getServletContext();
// accès à un autre contexte
ServletContext contexteExterieur =
getServletContext("/autreAppli/index.jsp");
// récupération d’un attribut externe
String qte = contexteExterieur.getAttribute("quantite");

Technologies de Programmation Web , HAMEL 2017 106


Collaboration de servlets :
Partage d'informations
 2 servlets partagent une même information : un vecteur
contenant le nom de personnes.
 Cette information est enregistrée sous la forme d’un attribut
dans le contexte de l’application
 La servlet Inscription enregistre des participants à une réunion
 Un autre servlet Invites accède à la composition de la réunion et affiche
la liste des inscrits
 Démo cours

Technologies de Programmation Web , HAMEL 2017 107


Collaboration de servlets :
Partage d'informations
public class Inscription extends HttpServlet {
private String nom;
private Vector invites = new Vector();
public void doGet(HttpServletRequest req, HttpServletResponse
res) throws IOException, ServletException {
res.setContentType( "text/html" );
PrintWriter out = res.getWriter();
ServletContext contexte = getServletContext();
out.println("<FORM ACTION='/reunion/Inscription‘METHOD='get'>");
out.println("<INPUT NAME='nom' TYPE='text'/>");
out.println("<INPUT TYPE='submit‘ VALUE='nouvel inscrit'/>" );
out.println("</FORM>");
invites.add(req.getParameter("nom"));
contexte.setAttribute("invites",invites);}}

Technologies de Programmation Web , HAMEL 2017 108


Collaboration de servlets :
Partage d'informations
public class Invites extends HttpServlet {
public void doGet( HttpServletRequest req, HttpServletResponse
res ) throws IOException, ServletException {
res.setContentType( "text/plain" );
PrintWriter out = res.getWriter();
ServletContext contexte = getServletContext();
Vector invites = (Vector)contexte.getAttribute( "invites" );
Enumeration e = invites.elements();
out.println( "liste des inscrits : " );
while ( e.hasMoreElements() )
out.println( e.nextElement() );
}
}

Technologies de Programmation Web , HAMEL 2017 109


Collaboration de servlets :
Partage du contrôle d'une requête
2 possibilités :
Délégation de la requête à une autre servlet
Une servlet reçoit une requête et laisse une autre servlet( jsp ) la
responsabilité de la traiter (en partie ou totalement).
Dans ce cas le contrôle est passé à la seconde servlet
Inclusion de contenu
Une servlet inclut dans sa propre réponse un contenu généré
dynamiquement par une autre servlet
La réponse peut être ainsi construite à partir d'un ensemble de contenus
générés par divers composants web
Dans ce cas la première servlet conserve le contrôle

Technologies de Programmation Web , HAMEL 2017 110


Collaboration de servlets :
Partage du contrôle d'une requête
La délégation est obtenue par un distributeur de requête,
instance de la classe javax.servlet.RequestDispatcher.
La servlet obtient un distributeur sur la requête vers un
composant de l'application (servlet, jsp, fichier statique, ...) en
indiquant son URI par la méthode :
public RequestDispatcher
ServletRequest.getRequestDispatcher(String uri)
l'URI peut être :
 relatif, on reste dans le contexte de la servlet courante
 absolu, il est interprété relativement à la racine du contexte
Le chemin peut être complété par une chaîne d'interrogation :
/reunion/Inscription?nom=Ali

Technologies de Programmation Web , HAMEL 2017 111


Collaboration de servlets :
Partage du contrôle d'une requête
 RequestDispatcher
 Spécifie la méthode :
forward() passe la requête complète au composant cible.
req.setAttribute("numero","21515");
RequestDispatcher
distibuteur=req.getRequestDispatcher(ServletReponse);
distributeur.forward(req,res);
Le contrôle est passé à la servlet ServletReponse du même
contexte qui peut de ce fait accéder à l'attribut numero
String num = (String)req.getAttribute("numero");

Technologies de Programmation Web , HAMEL 2017 112


Collaboration de servlets :
Partage du contrôle d'une requête
 RequestDispatcher
 spécifie la méthode :
 include()
 inclut un contenu à la réponse courante
 la servlet appelante garde le contrôle de la réponse
// on passe une chaîne à la réponse
RequestDispatcher distributeur =
req.getRequestDispatcher(ServletReponse?numero=21515);
distributeur.include(req,res);
// on passe un attribut (donc un objet à part entière)
RequestDispatcher distributeur =
req.getRequestDispatcher(ServletReponse);
req.setAttribute("objet",new Object());
distributeur.include(req,res);
Technologies de Programmation Web , HAMEL 2017 113
Collaboration de servlets :
Partage du contrôle d'une requête
 RequestDispatcher
 exemple :
 Le projet include contient 2 servlets : Principale et Secondaire
 Une requête émise à Principale construit une réponse sous la
forme d’un texte formé à partir de Principale et d’un contenu
inclus fourni par Secondaire

Technologies de Programmation Web , HAMEL 2017 114


Collaboration de servlets :
Partage du contrôle d'une requête
public class Principale extends HttpServlet {
protected void processRequest(HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html;charset=UTF-8");
PrintWriter out = res.getWriter();
out.println("<html><head>");
out.println("<title>Servlet Principale</title>"</head>");
out.println("<body>");
out.println("<h3>Servlet Principale at");
out.println(" req.getContextPath() </h3>");
out.println(" le texte suivant est inclus par la servlet secondaire");
out.println("<hr />");
RequestDispatcher dist = req.getRequestDispatcher("Secondaire");
dist.include(req,res);
out.println( "<hr />");
out.println( " retour à la servlet principale");
out.println("</body></html>");
out.close();
}
Technologies de Programmation Web , HAMEL 2017 115
Collaboration de servlets :
Partage du contrôle d'une requête
public class Secondaire extends HttpServlet {
protected void doGet( HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<h3>Servlet Secondaire at" );
out.println(request.getContextPath () + "</h3>");
out.println(" Caractéristiques de la machine <br>");
out.println("Fonction Aquastop.<br>");
out.println("5 températures: 45 à 70°.<br>");
out.println("Départ différé de 1 à 19 h.<br>");
out.println("énergie/lavage/séchage : classe A/A/A<br>");
out.println("Niveau sonore : 47 dB.<br>");
}

Technologies de Programmation Web , HAMEL 2017 116


Cookies

 Un cookie est une information envoyée par un serveur web à un


navigateur et sauvegardée par celui-ci sur le disque de sa machine
 Le navigateur retourne cette information (inchangée) lorsqu'il
visite de nouveau le même site.
 Ayant lu cette information, le serveur peut identifier le client et
lui fournir un certain nombre de facilités :
 achat en ligne
 authentification
 personnalisation de portail
 diriger les recherches d'un moteur
 Pas de menace sécuritaire
 limité à 4K
 un navigateur accepte 20 cookies/site et 300 au total
Technologies de Programmation Web , HAMEL 2017 117
Cookies

 Cette technique est utilisée pour le suivi de session. Il mémorise


l'identifiant de session (sessionid) pour le navigateur
 Pour stocker un cookie sur un navigateur, la servlet doit ajouter
le cookie dans l'en-tête de sa réponse
 Pour récupérer l'information à partir d'un cookie, la servlet doit
extraire le cookie de l'en-tête de la requête
 Ceci est réalisé et rendu transparent par l'API Cookie et ses
méthodes d'accès : addCookie() et getCookies()
Les navigateurs n'acceptent pas toujours les cookies ( WAP, ...).
Il est possible de les inhiber

Technologies de Programmation Web , HAMEL 2017 118


Cookies

javax.servlet.http.Cookie
 constructeur :
 public Cookie(String name,String value)
 envoi d'un cookie à un client par une servlet :
 public void HttpServletResponse.addCookie(Cookie cookie)
 récupération des cookies. Il est impossible de récupérer un
cookie connaissant son nom. On ne peut que récupérer un
tableau de tous les cookies envoyés par le navigateur :
 public Cookie[] HttpServletRequest.getCookies()
 modifier la valeur d'un cookie :
 public void setValue(String newValue)

Technologies de Programmation Web , HAMEL 2017 119


Cookies

Création d'un cookie (res est l'objet réponse)


Cookie unCookie = new Cookie("nom","martin");
res.addCookie(unCookie);
 Récupération d'un cookie (req est l'objet réquête)
Cookie[] cookies = req.getCookies();
if (cookies != null)
for ( int i=0;i<cookies.length;i++ ){
if (cookies[i].getName().equals("nom")){
String valeur = cookies[i].getValue();
break;
}
}
}
Technologies de Programmation Web , HAMEL 2017 120
Cookies
 Un cookie est défini par son nom auquel est associée une valeur.
 Il est possible d'y ajouter certains attributs
 void setDomain(String pattern)
 précise le domaine pour lequel le cookie est valide
 par défaut, le cookie est retourné seulement au serveur qui l'a sauvé
void setMaxAge(int expiry)
 spécifie l'age maximum du cookie en secondes
 expiry<0 => le cookie expire avec le navigateur
 expiry=0 => le cookie est détruit immédiatement
void setPath(String uri)
 définit le chemin dans le domaine pour lequel le cookie est valide
 par défaut, le cookie est valide pour la page qui le définit et toutes les pages
du répertoire du dessous
 si uri="/", le cookie est valide pour toutes les pages du serveur
void setSecure(boolean flag)
 flag=true => le cookie doit être envoyé via un canal sécurisé (SSL)
void setComment(String comment)
 définit un commentaire qui décrit le rôle du cookie
Technologies de Programmation Web , HAMEL 2017 121
Cookies
 Exemple
 L'exemple présente une page qui permet de saisir un mot.
 Le mot saisi est conservé dans un cookie.
Ainsi chaque fois que la page est demandée (après rechargement), le dernier mot
saisi est affiché.
De même si une requête à cette page est réalisée à travers une autre instance du
navigateur
Après déconnexion, la valeur du cookie est réinitialisée

Technologies de Programmation Web , HAMEL 2017 122


Cookies
package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;
public class Question extends HttpServlet {
public void doGet (HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String raz=request.getParameter("raz");
if(raz!=null) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i=0;i<cookies.length;i++){
if(cookies[i].getName().equals("cookieMot")) {
Technologies de Programmation Web , HAMEL 2017 123
Cookies
cookies[i].setValue(" ");
response.addCookie(cookies[i]);}}}}
String mot=null;
out.println("<html><head><title>Question</title></head>"+
" <body bgcolor=yellow text=blue>"+
"<center>");
if(mot==null || mot.equals(" ")) {
out.println("<h2> Saisissez un mot !</h2>");
mot=" ";
}else{
out.println("<h2>Dernier mot saisi"+mot +"</h2>");
}

Technologies de Programmation Web , HAMEL 2017 124


Cookies
out.println("<form action='reponse' method='post' >"+
"<hr><table><tr>"+
"<td>Votre mot</td>"+
"<td><input name='Mot' value="+mot+" \"");
out.println("type='text' size='20'></tr></table><table>"+
"<tr>"+
"<td><input type='submit'value='Envoyer'</td>"+
"<td><input type='reset' value='Rétablir'></td>"+
"</tr></table>"+
"</form>"+
"</center>"+
"</body>"+
"</html>");
}
}

Technologies de Programmation Web , HAMEL 2017 125


Cookies
package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Reponse extends HttpServlet {
public void doPost(HttpServletRequest request,HttpServletResponse
response) throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String mot=request.getParameter("Mot");
Cookie cookieMot=new Cookie("cookieMot",mot);
cookieMot.setMaxAge(600);
response.addCookie(cookieMot);
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i=0;i<cookies.length;i++){
if(cookies[i].getName().equals("cookieMot"))
mot=cookies[i].getValue();}}
Technologies de Programmation Web , HAMEL 2017 126
Cookies
out.println(
"<html>"+
"<head>"+
"<title>Bienvenue</title>"+
"</head>"+
"<body bgcolor=green text=white>"+
"<center>"+
"<h2> Vous avez saisi :"+ mot+"</h2>"+
"<FORM action='question' method='get'>"+
"<INPUT type='submit' value='déconnexion'>"+
"<INPUT type='hidden' name='raz' value='1'>"+
"</FORM>"+
"</center>"+
"</body>"+
"</html>");
}
}

Technologies de Programmation Web , HAMEL 2017 127


Sessions
 Le protocole HTTP est un protocole sans état => le serveur ignore
qu'une séquence de requêtes provient d'un même client
 En mode HTTP, pour le serveur, 2 requêtes successives d'un même
client sont indépendantes
 Le serveur HTTP voit les requêtes, pas les clients. En effet une adresse
IP n'est pas suffisante pour identifier un utilisateur
 Exemple : Un serveur web de commerce électronique gère un panier.
Les articles achetés, ajoutés au panier, donnent lieu à différentes requêtes
La notion de session n'est pas liée au protocole HTTP.
Une session est définie comme une collection de requêtes HTTP entre
un client et un serveur web sur une période de temps
 La notion de session permet d'associer un ensemble de requêtes et de
les identifier comme appartenant à un même client.
 La technique de la session est utilisée pour maintenir un lien entre
plusieurs requêtes
Technologies de Programmation Web , HAMEL 2017 128
Sessions
 A chaque utilisateur est associé implicitement un objet utilisé par les servlets
pour sauvegarder un ensemble d’objets (un panier par exemple)
 Cet objet de type HttpSession permet donc de suivre l'activité d'un client sur
plusieurs pages
 les requêtes provenant d'un même utilisateur sont associées à un même objet
 Chaque ServletContext gère ses propres instances de HttpSession
 HttpSession HttpServletRequest.getSession() pour récupérer l’objet session courant
 void HttpSession.setAttribute(String name, Object value) ajoute un couple (name,
value) à cette session
 Object HttpSession.getAttribute( String name ) retourne l'objet associé à la clé
name ou null
 void HttpSession.removeAttribute( String name ) enlève le couple de clé name
 java.util.Enumeration HttpSession.getAttributeNames() retourne tous les noms
d'attributs associés à la session
 void HttpSession.setMaxIntervalTime( int seconds ) spécifie la durée de vie
maximum d'une session

Technologies de Programmation Web , HAMEL 2017 129


Sessions
 Fonctionnement d’une session
 A la première requête vers une application web :
 un objet HttpSession est créé
 ainsi qu’un identifiant unique pour cet objet
 L’identifiant est en général sauvegardé par un cookie appelé JSESSIONID => seul
l’identifiant de session est envoyé au client
 Grâce à cet identifiant, le serveur détermine l’objet session correspondant à la
requête courante
 A toute nouvelle requête émise par l'utilisateur, le cookie est transmis via le
serveur web et accédé par la méthode : public String HttpSession.getId()
Cycle de vie d'une session
 A sa création, une période de temps est affectée à la session
 Elle expire automatiquement à la fin de cette période (par défaut 30mns avec
Tomcat)
 Elle peut être invalidée explicitement par la servlet ( HttpSession.invalidate() ).
Permet de fermer une session
 A l'expiration (invalidation), les données de l'objet session(HttpSession) sont
retournées au moteur de servlets
 Les sessions ne sont donc pas invalidées à la fermeture du navigateur
Technologies de Programmation Web , HAMEL 2017 130
Sessions Exemple
 Dans l'exemple qui suit, on souhaite mémoriser le nombre de fois que le
mot "vu" est saisi à travers les requêtes HTTP.
 Pour cela, on utilise un objet HttpSession dans lequel peuvent être
stockées des ressources sous la forme (nom –String-, valeur – Object-).
 Le compteur de saisies sera mémorisé par la session.
 La servlet est rechargée :
 après arrêt et redémarrage du serveur web (le rechargement évite la
recompilation de la classe) lorsque sa classe est modifiée
 Notons que :
 les variables statiques sont partagées par les instances multiples d'une
même servlet
 les propriétés de session et les classes utilitaires sont partagées par
toutes les servlets d'un même moteur de servlets

Technologies de Programmation Web , HAMEL 2017 131


Sessions Exemple
public class SimpleSession extends HttpServlet {
private static final String compteur = "compteur";
private static final String mot = "vu";
public void gestionRequete(HttpServletRequest req,
HttpServletResponse res,boolean isPost)
throws ServletException, IOException{
res.setContentType("text/html");
PrintWriter pw = res.getWriter();
pw.println("<HTML><BODY>");
// saisie du paramètre ‘texte’,
// rechargement de la page
pw.println("<FORM method='POST'
action='http://localhost:8080/session/SimpleSession'>");
pw.println("<INPUT type='text' name='texte'>");
pw.println("<INPUT type='submit' >");
pw.println("</FORM>");
// retourne l'objet session courante
// ou création d'une session car true
HttpSession laSession = req.getSession(true);
// récupération de l'attribut compteur de l'objet session
Integer compteVu =(Integer)laSession.getAttribute(compteur);
Technologies de Programmation Web , HAMEL 2017 132
Sessions Exemple
if( isPost ){
// une requête HTTP POST a été reçue
String texte = req.getParameter("texte");
// si le paramètre session de la requête = "vu"
if( mot.equals(texte) ){
if( compteVu == null )compteVu = new Integer(1);
else
compteVu = new Integer( compteVu.intValue() + 1 );
// l'attribut de l'objet session est incrémenté
laSession.setAttribute(compteur,compteVu);
pw.println("<hr>");
}
}
pw.println("<P><P><H1>le mot 'vu' a été saisi : " +
((compteVu == null) ? 0 : compteVu.intValue()) );
pw.println("</BODY></HTML>");
pw.close();}
public void doGet (HttpServletRequest req, HttpServletResponse res) throws
ServletException, IOException{ gestionRequete(req,res,false);}
public void doPost (HttpServletRequest req, HttpServletResponse res) throws
ServletException, IOException{ gestionRequete(req,res,true);}}

Technologies de Programmation Web , HAMEL 2017 133


JSP et Java Beans
 Un des objectif des JSP / Servlets
 Ne pas mélanger du code HTML au code Java des Servlets
 D’un autre coté si c’est pour mettre du code Java dans le code
JSP qu’est ce qu’on y gagne ?
 Un point important dans la conception de pages JSP est de
minimiser le code Java embarqué dans les pages
 Déporter la logique métier dans des composants objets qui
seront accédés depuis les pages JSP
 Simplification des traitements inclus dans la JSP
 Possibilité de réutilisation des composants depuis d’autres
JSP ou d’autres composants
 Les spécifications JSP définissent une manière standard
d'intérargir avec des composants Java Beans
Technologies de Programmation Web , HAMEL 2017 134
Java Beans
Qu’est-ce qu’un composant Java Bean ?
 Un composant java (objet) dont la classe respecte certaines règles
d’écriture
 Le respect de ces règles d’écriture permet ensuite d’utiliser ces
composants de manière standard
 Composants Java Beans depuis JSP (on va le voir tout de suite)
 Composants graphiques pour la construction d’interface utilisateurs
 Un Java Bean
 Classe publique
 Possède un constructeur public sans arguments
 Regroupe un ensemble de propriétés
 accessibles par des méthode de la forme getXXX()où XXX est le nom de la
propriété
 éventuellement modifiables par une méthode setXXX() où XXX est le nom de la
propriété
 Implémente en option l’interface java.io.Serializable
Technologies de Programmation Web , HAMEL 2017 135
Utiliser un bean depuis JSP
Le tag <jsp:useBean>
 Permet de localiser une instance ou bien d’instancier un bean pour l’utiliser
dans la JSP
Syntaxe
<jsp:useBean
id="beanInstanceName"
class="package.class"
type="package.class"
scope="page|request|session|application"
/>
Significations
 id : Nom utilisé pour la variable qui servira de référence sur le bean
 class : La classe du bean
 type : Optionnel, le type de la référence beanInstanceName si ce n’est pas le type
défini par l’attribut class
 scope : Optionnel, détermine la portée durant laquelle le bean est défini et
utilisable
Technologies de Programmation Web , HAMEL 2017 136
Utiliser un bean depuis JSP
Le tag <jsp:useBean>
 Permet de localiser une instance ou bien d’instancier un bean pour l’utiliser
dans la JSP
Syntaxe
<jsp:useBean
id="beanInstanceName"
class="package.class"
type="package.class"
scope="page|request|session|application"
/>
Significations (suite)
 scope : Optionnel, détermine la portée durant laquelle le bean est défini et
utilisable
 le bean demandé est déjà instancié pour la portée précisée :
renvoi de sa référence
 le bean demandé n’est pas déjà présent pour la portée précisée :
 instanciation du bean
ajout de celui-ci à la portée spécifiée
Technologies de Programmation Web , HAMEL 2017 137
Utiliser un bean depuis JSP
 L’attribut scope
page
valeur par défaut
bean utilisable dans toute la page JSP ainsi que dans les fichiers statiques
inclus.
request
bean accessible durant la durée de vie de la requête. La méthode
getAttribute() de l'objet requestpermet d'obtenir une référence sur le bean.
 session
bean utilisable par toutes les JSP qui appartiennent à la même session que
la JSP qui a instanciée le bean. Le bean est utilisable tout au long de la
session par toutes les pages qui y participent. La JSP qui créé le bean doit
avoir l'attribut session = "true" dans sa directive page
 application
bean utilisable par toutes les JSP qui appartiennent à la même
application que la JSP qui a instanciée le bean. Le bean n'est instancié
que lors du rechargement de l'application
Technologies de Programmation Web , HAMEL 2017 138
Utiliser un bean depuis JSP
package test;
public class Personne {
private String nom;
private String prenom;
private int age = 0;
public Personne() {
this.nom = "X"; // nom par défaut
this.prenom = "x"; // prénom par défaut
}
public String getNom() {
return (this.nom);
}
public void setNom(String nom) {
this.nom = nom;
}
...
public int getAge () {
return (this.ge);
}
public void setAge(int age) {
this.age = age;
}
}
Technologies de Programmation Web , HAMEL 2017 139
Utiliser un bean depuis JSP

<jsp:useBean
id="utilisateur"
class="test.Personne"
Définition dans la session d’un java bean
scope="session" instance de la classe Personne du
/> package test et désigné par la référence
utilisateur
<html>
<body>
<ul>
<li>NOM : <%=utilisateur.getNom()%></li>
<li>PRENOM : <%=utilisateur.getPrenom()%></li>
<li>AGE : <%=utilisateur.getAge()%></li>
</ul>
</body>
</html>

Technologies de Programmation Web , HAMEL 2017 140

Vous aimerez peut-être aussi