Vous êtes sur la page 1sur 174

CHAPITRE 2

APPLICATIONS WEB :
SERVLETS, JSP

Frédéric MOAL Cours PnT


Université d’Orléans Licence 3 version 01/2019
Plan
 Introduction et rappels
 Applications Web
 http/HTML
 Scripts cgi
 Servlets
 JSP
 Tag lib
Ressources IHM
 Documentation Apache : http://tomcat.apache.org/ dans la
version des servlets/JSP de tomcat utilisée
 Le site officiel de Oracle http://java.oracle.com
 « Cours » en ligne:
Jean Michel DOUDOUX - "Développons en Java" (2599pages)
http://www.jmdoudoux.fr/ Faîtes vous votre propre
Tutos de Vogella http://www.vogella.com/ librairie de tutos !
- bookmarks,
Intranet Michel Buffa, MIAGE Nice - Diigo.com
http://www.developpez.com - Pocket
http://www.dzone.com/ - Zotero
https://www.javacodegeeks.com/ - …
 Blogs :
Xebia, Ippon tech., SQLI, Le touilleur express, Java Posse, Bistro!, ...
Les cast codeurs podcast, parleys.com [Devoxx / FR]
 Twitter
Rappels

 Java [2, 5, 6, 7,8 et 9]


 Html[5] :
http://mainline.i3s.unice.fr/HTML5slides/
 CSS[3] :
http://mainline.i3s.unice.fr/JavaScriptSlides/
 Eclipse / IntelliJ
 Gestion de version (Git)
 …

=> Cf ressources et web


Plan

 Introduction
 Applications Web

 http/HTML
 Scripts cgi
 Servlets
 JSP

 Tag lib
Applications « Web »
 Protocole http :
Repose sur TCP [Au cours Réseaux tu te
réfèreras]

Client http Envoi d’une commande


get "/…/info.html"
Serveur http

Contenu du fichier
/…/info.html
Protocole HTTP
Une Piqure de « rappel » tu auras
Le Protocole HTTP
 HyperText Transfer Protocol
 Protocole d’échanges d’information sur le web
 Basé sur TCP
 Version courante 1.1
 Maintenant 2.0
URL
 Unique Resource Location
 Identifie les ressources de manière unique sur le Web
 5 parties
 Protocole (http, ftp, mail, …)
 Host (google.com)
 Port (8080, 80)
 Path (Chemin vers la ressource sur le serveur)
 Paramètres

http://server:port/path/to/resource?p1=v1&p2=v2
http://server:port/path/to/resource?p1=v1&p2=v2
Protocole Nom du serveur et Chemin de la Paramètres
port ressource
Enchainements Client - Serveur
Requête HTTP
 Permet à un client d’envoyer des
messages à un serveur
 Format d’un message HTTP
 Request Message Header
 Request Line
 Request Headers [Optional]

 Request Message Body


Requête HTTP
 Requête envoyée par un client http vers
Ressource/
un serveur Document Version du
demandé! protocole
Image, HTML, utilisée : 1.0
Methode de ou 1.1 ou 2.0
JSON, XML…
la requete
GET, POST,
<Méthode> <URI> HTTP/<version>
PUT…
[<Champ d’en-tête> : <valeur>]
Ligne blanche
[Corps de la requête]
Informations
concernant le
client HTTP, Donnée envoyée
l’utilisateur au serveur, prise
(cookies, en compte pour
localisation) les requêtes de
type POST ou PUT
Réponse HTTP
 Réponse du serveur au client :

 Response Message Header


 Response Line
 Response Headers
 Response Message [Optional]
Réponse HTTP
 Réponse du serveur à une requête du
client Statut de la
réponse Information
caractérisé par des descriptive
Version du
codes prédéfinis sur le
protocole
par le protocole statut
utilisée : 1.0 ou
http : 200/404/500
1.1 ou 2.0

HTTP / <Version> <Statut> <Commentaire>


Content Type : <Type MIME du contenu>
[<Champ d’en tête>: <valeur>]
Ligne blanche
Informations <Contenu> Information sur
concernant le le type MIME du
serveur contenu:
XML/html/JSON
Exemple

Une démo ?
Autre exemple : Request
 Request Line
POST /bibliotheque/faces/views/categorie/Create.xhtml HTTP/1.1
 Request Headers
Host: localhost:8080
Connection: keep-alive
Content-Length: 176
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/
*;q=0.8
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
39.0.2171.65 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:8080/bibliotheque/faces/views/categorie/List.xhtml
Accept-Encoding: gzip, deflate
Accept-Language: fr,fr-FR;q=0.8,en;q=0.6
Cookie: JSESSIONID=d64a9484e61761662575b5d14af1
Autre exemple : Request
 Request Message Body
j_idt13:nom:Toto
j_idt13:description:Hello
Response Message Header
 Response Line
HTTP/1.1 200 OK

 Response Headers
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish
Server Open Source Edition 4.0 Java/Oracle
Corporation/1.8)
Server: GlassFish Server Open Source Edition 4.0
Content-Type: text/html;charset=UTF-8
Date: Sun, 23 Nov 2014 16:05:39 GMT
Content-Length: 2274
Response Message Body
 Response Body
<html xmlns="http://www.w3.org/1999/xhtml"><html
xmlns="http://www.w3.org/1999/xhtml">
<head><link
type="text/css" rel="stylesheet"
href="/bibliotheque/faces/javax.faces.resource/theme.css?
ln=primefaces-aristo" />
<link type="text/css" rel="stylesheet"
href="/bibliotheque/faces/javax.faces.resource/css/jsfcrud.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Create New Categorie</title></head><body>
<h1>Create New Categorie
</h1>
<p><div id="messagePanel"><table><tr style="color: green"><td>Categorie
was successfully created. </td>
</tr></table></div>
</html>
Retours d’information
 Une fiche mémo :
http://authoritylabs.com/blog/common-http-respo
nse-codes-and-what-they-mean/

 Doivent être interprétés correctement par le


client, et émis correctement par le serveur !!!
De nombreuses autres méthodes…

 HTTP définit un ensemble de méthodes qui


permet de caractériser les types de
requêtes
 GET : Récupérer des ressources à un serveur
 POST : Envoyer des données à un serveur
 PUT : Modifier des données
 DELETE : Suppression de données
 OPTIONS : Demander la liste des méthodes
supportées par un serveur
 Autres : HEAD, TRACE, CONNECT, PATCH
Un peu d’histoire : CGI
Dynamique tu seras (ou tu essaieras
au moins)
Première approche : CGI
 Normalisation « système » pour
introduire des pages non statiques
 Idée simple : lancer un programme à
chaque requête pour générer un contenu
dynamique
 Pourquoi pas des Shell ? Bash, perl, …
 Run d’un programme et récupération de
la sortie du programme, et on renvoie le
tout au navigateur !
Appli web : les scripts CGI
 Formulaire html : submit

 Les paramètres saisis dans le formulaire


sont transmis à un script (GET : dans
l’URL, POST : dans le corps)

 Le script récupère les paramètres,


effectue son traitement et génère
(imprime) la page html résultat
Pages dynamiques par script CGI

 Exemple simple avec un formulaire


<html>
<head>
<title>Mon formulaire</title>
</head>
<body>
<h1>Titre de page</h1>
<form method="get" action="cgi-bin/Enreg">
Nom : <input type="text" name="nom">
<input type="submit" value="OK">
</form>
</body>
</html>
Pages dynamiques par
script CGI
Servlet
Les leçons tu retiendras
Servlets
 Programme : pourquoi pas en Java ?
 Alternative à la programmation avec CGI
 Il s'agit de programmes exécutés sur un
serveur
 servent de couche intermédiaire entre
une requête provenant d'un navigateur
Web et un autre service HTTP, comme
des bases de données ou des
applications du serveur HTTP
Servlets
 Technologie Servlets : pourquoi
Java ?
 indépendant / OS et serveurs Web
 Accès aux API de Java
 Annotations JEE
 mieux que CGI car compilé, prise en
charge connexion des utilisateurs en
multithread…
 Scalable sans changer le code source !!!
Servlets
 Différences Servlets / scripts CGI
 Performances
 une seule machine virtuelle Java sur le
serveur
 servlet reste placée en mémoire une fois
appelée
 servlet modifiée peut être réactivée sans
redémarrage serveur ou application
 Modularité
 possibilité
d’avoir plusieurs servlets, chacune
pouvant accomplir une tâche spécifique
Servlets : architecture
Servlets
 Tâches de la servlet :
1. Lire toutes les données envoyées par l'utilisateur (d’un
formulaire, d'une applet Java ou d'un prog. client HTTP)
2. Chercher d'autres informations sur la requête, à l'intérieur de
la requête HTTP (cookies, nom de l'hôte, …, etc. )
3. Générer des résultats (calculs, communication avec la base de
données, …)
4. Formater le résultat dans un document (incorporation des
informations dans une page HTML)
5. Définir les paramètres de la réponse HTTP appropriés (type de
document, définir les cookies, mémoriser les paramètres…
6. Renvoyer le document au client au format texte (HTML), au
format binaire (images GIF), ou dans un format compressé
comme gzip
Servlet
 Bon OK mais en dev ça donne quoi ?
Servlets
 L ’API pour les servlets constituée de deux
packages :
 javax.servlet
 javax.servlet.http
 Librairie Servlet avec chaque serveur d’application Java

<<interface>> <<interface>> <<interface>>


GenericServlet
Servlet ServletRequest ServletResponse

<<interface>> <<interface>>
HttpServlet
HttpServletRequest HttpServletResponse

MaServlet
Architecture d’une Servlet
 La classe HttpServlet
 Rôle = traiter la requête HTTP
 Pour chaque méthode HTTP : GET, POST, PUT,
DELETE, etc. il y a une méthode
correspondante :
 doGet(…) – répond aux requêtes HTTP GET

 doPost(…) – répond aux requêtes HTTP GET

 doPut(…), doHead(…), doDelete(…), doTrace(…),


doOptions(…)
 Conseil : implémenter au moins les deux
premières méthodes ou redéfinir la méthode
service(…)
Servlet HTTP et servlet générique

G e n e r ic S e r v le t
C lie n t
S erv er
req u est

resp o n se
s e r v ic e ( )

H T T P S e r v le t
B ro w ser
H T T P S erver
req u est
doG et ( )
resp o n se
s e r v ic e ( )
d o P o s t( )
Architecture d’une Servlet (2)

 Ces méthodes ont deux paramètres : la requête et


la réponse
 L’objet HttpServletRequest
 Contient la requête du client
 En-tête de la requête HTTP
 ParamètresHTTP (données de formulaire ou paramètres
passés avec l’URL)
 Autres données (cookies, URL, chemin relatif, etc.)
 L’objet HttpServletResponse
 Encapsule les données renvoyées au client
 En-tête de réponse HTTP (content type, cookies, etc.)
 Corps de la réponse (en tant que OutputStream)
Architecture d’une Servlet (3)
 La méthode HTTP GET est utilisée quand :
 Le traitement de la requête ne modifie pas l’état du

serveur,
 Si jamais il s’agit de l’envoi d’un formulaire, taille des
données < 255 caractères,
 On veut pouvoir bookmarker l’URL
 La méthode HTTP POST est utilisée quand :
 Le traitement change l’état du serveur : exemple
classique = un insert dans une base de données.
 La quantité de données à envoyer est importante,
 On veut cacher dans l’URL les paramètres (ex : mot
de passe)
Servlets API
 Fonctions principales d’une Servlet :
 Traiter les paramètres HTTP reçus dans la
requête (GET ou POST)

HttpServletRequest.getParameter(String)
 Récupérer un paramètre de configuration de
l’application web (dans le descripteur web.xml)

ServletConfig.getInitParameter()
 Récupérer un élément de l’en-tête HTTP

HttpServletRequest.getHeader(String)
Servlets API (2)
 Spécifier dans le header de réponse le type
HttpServletResponse.setHeader(<name>, <value>) /
HttpServletResponse.setContentType(String)

 Récupérer un Writer pour écrire la réponse


HttpServletResponse.getWriter()

 …ou un flux binaire si la réponse est binaire


HttpServletResponse.getOutputStream()

 Rediriger la requête vers un autre URL


HttpServletResponse.sendRedirect()
Des exemples ?
De nombreux tu testeras
Exemple 0 simple de servlet
import java.io.IOException;
import java.io.PrintWriter; Import des classes
import javax.servlet.ServletException; de servlets
import javax.servlet.http.HttpServlet;
import Redéfinition
javax.servlet.http.HttpServletRequest;
Redéfinition
import javax.servlet.http.HttpServletResponse;
de
de doGet(…)
doGet(…)
Hérite de Request
Request et
et Response
Response ::
public class Premiere extends HttpServlet { HttpServlet contexte
contexte d’appel
d’appel et
et de
de
retour
retour
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException { Propagation
response.setContentType("text/html"); des exceptions
Réponse
PrintWriter out = response.getWriter();
out.println("<HTML>"); en html
out.println("<HEAD><TITLE>Première servlet</TITLE></HEAD>");
URL
URL d’accès
d’accès
out.println("<BODY><H1>Ma première servlet</H1></BODY>");
à la servlet
à la servlet
out.println("</HTML>");
} Le
Le code
code html
html
renvoyé
renvoyé
}
Exemple 1 : « dynamique »
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DateServlet extends HttpServlet {


public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

// A éviter, normalement pas de HTML dans une servlet


PrintWriter out = Res response.getWriter();
out.println("<HTML>");
out.println("The time is: " +
new java.util.Date());
out.println("</HTML>");
}
}
Exemple 2 : paramètres
 Utilisation classique :
enchainement d’un formulaire de saisie
html qui appelle une servlet en cas de
validation (<form>)

Page html [formulaire.html] -> Servlet


[TraiteFormulaire.java]
Servlets
 Servlet TraiteFormulaire.java
Servlet : exemple de formulaire
<!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=ISO-8859-1">
<title>Un formulaire de saisie</title>
</head>

<body>
<form method="get" action="TraiteFormulaire">
Titre : <select name="titre">
<option>Mr</option><option>Mme</option>
</select><br>
Prénom : <input name="prenom"><br>
Nom : <input name="nom"><br>
Mot de passe : <input name="motdepasse" type="password"><br>
<input type="submit"><input type="reset">
</form>
</body>

</html>
Servlet : traitement du formulaire
public class TraiteFormulaire extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse


response) throws ServletException, IOException {

response.setContentType("text/html");
PrintWriter out = response.getWriter();

out.println("<HTML>");
out.println("<HEAD><TITLE>Deuxième servlet</TITLE></HEAD>");
out.println("<BODY><H1>Bonjour ");
String titre = request.getParameter("titre");
if (titre.equals("Mr")) {
out.println("monsieur ");
} else if (titre.equals("Mme")) {
out.println("madame ");
} else throw new RuntimeException("Mauvais titre");
out.println(request.getParameter("nom")+",<br>");
String motdepasse = request.getParameter("motdepasse");
out.println("Votre mot de passe comprend "+motdepasse.length()+ "
caractères.");
out.println("</H1></BODY>");
out.println("</HTML>");
}
Servlet qui construit et sert une image

 On veut faire une Servlet qui construit une


image avec un texte dedans : un
compteur de vues.
 La Servlet maintient un compteur
 On l’initialise dans la méthode init() et on
l’incrémente dans la méthode doGet()
 La Servlet produit une image binaire
 Le Content-type doit être "image/jpeg"
Image Counter Servlet (1)

import javax.servlet.*;
import javax.servlet.http.*;
...

public class ImageCounterServlet extends HttpServlet {


private String mStartDate;
private int mVisitCounter;

public void init() {


mStartDate = (new Date()).toString();
mVisitCounter = 0;
}

public BufferedImage createImage(String msg) {


... // ici on crée une image, on dessine un texte
// dedans et on renvoie l’image sous forme de
// BufferedImage (buffer binaire)
}
Image Counter Servlet (2)

public void doGet(HttpServletRequest request,


HttpServletResponse response)
throws IOException, ServletException {
String msg;
// Rappel les servlets sont ré-entrantes !
synchronized(this) {
mVisitCounter++;
msg = "" + mVisitCounter + " visits since" +
mStartDate;
}
BufferedImage image = createImage(msg);
response.setContentType("image/jpeg");
OutputStream out = response.getOutputStream();
// Encode l’image en jpeg et l’écrit sur le flux
// binaire de la réponse
ImageIO.write(image, "jpg", out);
}
}
Extrait du code de création de l’image

// Create an image of our counter to be sent to the browser.


BufferedImage buffer = newBufferedImage(50, 20,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffer.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);
g.setFont(new Font("Monospaced", Font.PLAIN, 14));
g.setColor(Color.BLUE);
g.fillRect(0, 0, 50, 20);
g.setColor(Color.YELLOW);
g.drawString(msg, 0, 20);
return buffer;
Résultat
Renvoyer un zip depuis une
Servlet
Exemple de http://www.kodejava.org/examples/590.html
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
try {
String path = getServletContext().getRealPath("data");
File directory = new File(path);
String[] files = directory.list();
if (files != null && files.length > 0) {
byte[] zip = zipFiles(directory, files);
ServletOutputStream sos = response.getOutputStream();
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment;
filename=\"DATA.ZIP\"");
sos.write(zip); sos.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Servlets : contexte Request
 HttpServletRequest hérite de ServletRequest
 Cet objet encapsule la requête HTTP et fournit des
méthodes pour accéder aux informations
 du client
 de l'environnement du serveur
 Exemples de méthodes
String getMethod() : retourne le type de requête
String getServerName() : retourne le nom du serveur
String getParameter(String name) : retourne la valeur d'un
paramètre
String[ ] getParameterNames() : retourne le nom des les
paramètres
String getRemoteHost() : retourne l'IP du client
String getServerPort() : retourne le port sur lequel le serveur
écoute
… (voir l'API Servlets pour le reste)
Servlets : exemple de contexte
Récupérer l’URL relatif de la
servlet
 Permet d’obtenir des informations depuis le
header de la requête. Ex : chemin relatif
utilisé pour appeler la servlet :
public class ContextPathDemo extends HttpServlet {
protected void doGet(HttpServletRequest req,
HttpServletResponse res) throws ServletException,
IOException {
// HttpServletRequest.getContextPath() returns the
// portion of the request URI that indicates the
//context of the request.
String contextPath = req.getContextPath();
}
}
URI relatif à quoi cela sert-il ?
 Dans le cas où une même servlet est
mappé sur plusieurs URLs,
 Exemple, une Servlet qui streame des
fichiers mp3 dans /mp3/* a besoin de
récupérer le nom des fichiers…
/mp3/toto.mp3, /mp3/titi.mp3, on a
besoin de récupérer toto.mp3 pour
l’ouvrir…
 req.getRequestURI().substring(req.getCo
ntextPath().length()) renvoie la fin de
l’URI sans le contexte de déploiement
Servlet : contexte Response
 HttpServletResponse hérite de ServletResponse
 Cet objet est utilisé pour construire un message de
réponse HTTP renvoyé au client, il contient
 les méthodes nécessaires pour définir le type de contenu, en-
tête et code de retour
 un flot de sortie pour envoyer des données (par exemple
HTML) au client
 Exemples de méthodes
 void setStatus(int) : définit le code de retour de la réponse
 void setContentType(String) : définit le type de contenu MIME
 ServletOutputStream getOutputStream() : flot pour envoyer
des données binaires au client
 void sendRedirect(String) : redirige le navigateur vers l'URL
Conteneur de Servlets =
serveur
 Une application WEB peut contenir plusieurs
Servlets
 Pour tester et déployer une Servlet, il faut un
système d'exécution appelé conteneur de
Servlets
 Le conteneur réalise le lien entre la Servlet et le
serveur WEB
 Transforme code Java (bytecode) en HTML
 Associe à des URL's virtuels une Servlet
Conteneur de Servlet
 Plusieurs implémentations possibles :
 Apache Httpd
 Apache Tomcat
 Jetty
 Weblogic
 Websphere
 Wildfly
 …
 On démarre un serveur puis on déploie une ou plusieurs
applications
 Souvent par copie du fichier war dans un répertoire du serveur
 La plupart des serveurs proposent une interface web
d’administration qui permet de le faire
Conteneur de Servlets
 Une application WEB est contenue dans un
répertoire physique sur le serveur (exploded) ou
dans un WAR [<packaging>war</packaging>]
 Une application WEB possède une hiérarchie de
répertoires et de fichiers :
Et pour nous ?
 pom.xml !
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion>4.0.0</modelVersion>

<groupId>fr.miage.orleans.ihm</groupId>
<artifactId>monprojet</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
Fichier descripteur web.xml

 C’est un fichier XML, standard Java EE


 Ce fichier contient un nombre important
d’informations concernant l’application web Java
 L’URL de la page ou de la servlet de démarrage,
 Les associations classes de servlets -> nom de
servlets et nom de servlet -> URL
 Des paramètres d’initialisation (ex : email de
l’admin, server SMTP, activer des traces, etc)
 Servlet-filters : association de Servlets à ensemble
d’URLs
 Permet de déclarer des classes comme écouteurs de
certains aspects de l’application
Fichier de déploiement
 Ce fichier web.xml doit être placé dans
WebContent/WEB-INF
 Généré automatiquement (Eclipse…) ou
défini « à la main »
 N’est plus obligatoire depuis les Servlet
3.0 [le dire à maven-war-plugin ! Sinon
pas happy il sera]
web.xml : exemple
Web.xml : exemple
Chemins virtuels
Maping URL - Servlet
 La spécification des Servlets impose l’algo de
recherche : [https://java.net/downloads/servlet-
spec/Final/servlet-3_1-final.pdf]
 Part de l’URL complète et essaie de matcher le
plus spécifique
 Essaie récursivement en enlevant la fin (/)
 Si il y a une extension (eg .jsp), cherche un match
dessus
 Si rien ne match, cherche un servlet par défaut
 Attention, restrictions dans les matchs (eg /run/
* ok mais pas /run*)
Et comment qu’on run ?
Les differents « web listeners »
(écouteurs/callbacks)

 Par exemple on peut déclarer une classe qui


implémente ServletContextListener et dont
la méthode contextInitialized sera appelée
au déploiement de l’application
 Ex : remplir la base de données avec des
données de test, créer des comptes pour
l’admin, etc
 Ou encore compter le nombre de session
ouvertes pour afficher combien de personnes
sont « online » sur le site
 On va utiliser un SessionListener
Déclaration dans le
web.xml
<listener>
<description>
Classe pour remplir la base au déploiement
</description>
<listener-class>tools.InitApplication</listener-class>

</listener>
Classe de remplissage de la BD au
déploiement
public class InitApplication implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("##### BASE CREE ######");
compteBancaireFacade.creerComptesDeTest();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {

}
SessionListener : compter les personnes
online. Dans le web.xml

<listener>
<listener-class>
demo.SessionCounter
</listener-class>
</listener>
Classe écouteur
public class SessionCounter implements HttpSessionListener {
private List sessions = new ArrayList();

public SessionCounter() { }

public void sessionCreated(HttpSessionEvent event) {


HttpSession session = event.getSession();
sessions.add(session.getId());
session.setAttribute("counter", this);
}
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
sessions.remove(session.getId());
session.setAttribute("counter", this);
}

public int getActiveSessionsNumber() {


return sessions.size();
}
}
Affichage dans une page
JSP
<html>
<head>
<title>Session Counter</title>
</head>
<body>
Nombre de personnes online sur le site :

${activeSessionsNumber}
</body>
</html>

REMARQUE : ${activeSessionsNumber} va
chercher une propriété activeSessionsNumber
dans la page, la requête, la session, le contexte,
jusqu’à la trouver. Appelle
getActiveSessionsNumber()… Si page JSF,
Servlet : paramètres d’init
 Possibilité d’utiliser des paramètres
d’initialisation
 TRES utile pour la mise en production
 Les paramètres d’initialisation sont définis
dans le fichier web.xml de l’application WEB
Exemple de paramètres d’initialisation

<init-param>
<param-name>compressionThreshold</param-name>
<param-value>10</param-value>
</init-param>

<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
Récupération des initParams, ici dans un
écouteur, au déploiement

public void contextInitialized(ServletContextEvent event)


{
this.context = event.getServletContext();
String comp =
context.getInitParameter("compressionThreshold");
log("contextInitialized()");
log("compression= " + comp );
}
Ici dans une Servlet
public void init() {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
ServletContext context = getServletContext();
String logPath = context.getInitParameter("LOG.PATH");
writer.println("Log Path: " + logPath + "<br/>");
Enumeration enumeration = context.getInitParameterNames();
while (enumeration.hasMoreElements()) {
String paramName = (String) enumeration.nextElement();
String paramValue = context.getInitParameter(paramName);
writer.println("Context Init Param: [" +
paramName + " = " + paramValue +"]<br/>");
}
}
Servlet : cycle de vie
 Entre chaque requête du client les Servlets
persistent sous forme d’instances d’objet
 Au moment où le code d’une Servlet est
chargé, le serveur ne crée qu’une seule
instance de classe
 L’instance (unique) traite chaque requête
effectuée sur la Servlet
 Les avantages (rappels)
 L’empreinte mémoire reste petite
 Le surcoût en temps lié à la création d’un nouvel
objet pour la Servlet est éliminé
 La persistance est possible c’est-à-dire la
possibilité de conserver l’état de l’objet à
chaque requête (un exemple le compteur)
Cycle de vie d’une Servlet
• Le serveur gère ce New Destroyed
cycle,
Running
• Les méthodes init() destroy()
“callback” du cycle de
vie ne doivent jamais ...()
service()
être appelées par le
code qu’on écrit doGet()
doDelete()

doPost() doPut()

 On implémente souvent la méthode init


(invoquée lors de la première exécution de la
servlet) pour récupérer des ressources ou
paramètres d’initialisation.
Servlet : cycle de vie
 A chaque rechargement d’une Servlet par le
conteneur de Servlet, il y a création d’une
nouvelle instance et donc destruction de
l’ancienne
 Le rechargement d’une Servlet a lieu quand il y a :
 Modification d’au moins une classe de l’application
WEB
 Demande explicite de l’administrateur du serveur
WEB
 Redémarrage du conteneur de Servlets
 CF problèmes en TP !!!
Servlet : cycle de vie
 Un constat : il n’y a pas de
constructeur dans une Servlet
 L’initialisation des attributs se fait par
l’intermédiaire de la méthode init()
 Elle ne possède pas de paramètre
 Définie et implémentée dans la classe
abstraite GenericServlet
 La méthode init() peut être appelée à
différents moments
 Lorsque le conteneur de Servlets démarre
 Lors de la première requête à la Servlet
 Sur demande explicite de l’administrateur
du serveur WEB
Servlet : cycle de vie
 Une Servlet doit libérer toutes les ressources qu’elle
a acquises et qui ne pourront être passées au
ramasse-miettes
 Exemples de ressources
 Connexion à une base de données
 Ouverture d’un fichier sur le disque serveur
 La méthode destroy() donne une dernière chance
d’écrire les informations qui ne sont pas encore
sauvegardées
 La méthode destroy() est également utilisées pour
écrire les informations persistantes qui seront lues
lors du prochain appel à init()
Servlets 3.0
 Comme on est pas là pour faire du « XML
Sitting », le modèle 3.0 a apporté de
nombreuses annotations qui évitent de
remplir le fichier web.xml.
 possibilité de ne pas avoir de fichier
web.xml [Tomcat 7, 8…]
 Utilisation d’annotations directement
dans le code
 Pour des applications simples il est
facultatif
 Nécessaire encore pour certaines tâches
Et pour nous ?
 Pom !
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
Annotations Servlets 3.0

@WebServlet(asyncSupported = false,
name = "HelloAnnotationServlet",
urlPatterns = {"/helloanno"},
initParams = {@WebInitParam(name="param1",
value="value1"),
@WebInitParam(name="param2",
value="value2")} )
public class HelloAnnotationServlet extends HttpServle
{..}

Récupération des init params dans doGet() ou doXXX()


par :
getInitParameter("param1");
Annotations pour file upload
@WebServlet("/upload.html")
@MultipartConfig(location="c:\\tmp", fileSizeThreshold=1024*1024,
maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)
public class FileUploadServlet extends HttpServlet {  
@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();  
Collection<Part> parts = req.getParts();  
out.write("<h2> Total parts : "+parts.size()+"</h2>");

  for(Part part : parts) {


printPart(part, out);
part.write("samplefile");
}
 }
Code qui créer le fichier
private void printPart(Part part, PrintWriter pw) {
StringBuffer sb = new StringBuffer();
sb.append("<p>");
sb.append("Name : "+part.getName());
sb.append("<br>");
sb.append("Content Type : "+part.getContentType());
sb.append("<br>");
sb.append("Size : "+part.getSize());
sb.append("<br>");
for(String header : part.getHeaderNames()) {
sb.append(header + " : "+part.getHeader(header));
sb.append("<br>");
}
sb.append("</p>");
pw.write(sb.toString());   }
Code du formulaire d’envoi
<html>
<body>
<p>Commons File Upload Example</p>
<form action="uploadServletl"
enctype="multipart/form-data" method="POST">

<input type="file" name="file1"><br>


<input type="Submit" value="Upload File">
<br>
</form>
</body>
</html>
Compléments sur l’envoi de fichiers en
multipart (1)
 Attention, si le formulaire d’envoi possède
des champs classiques ou « hidden » en
plus du ou des fichiers, leurs valeurs ne
seront pas accessible dans la Servlet par
request.getParameter(nomDuParam)
 Valeur null renvoyée, faire getPart() à la
place !
 A la place :
private String getParamFromMultipartRequest(HttpServletRequest
request, String paramName) throws IOException, ServletException {
Part part= request.getPart(paramName);
Scanner scanner = new Scanner(part.getInputStream());
String myString = scanner.nextLine();
return myString;
}
Compléments sur l’envoi de fichiers en
multipart (2)

 Si on ne préciser pas le paramètre location


dans l’annotation :
@MultipartConfig(location="…" )
Les fichiers écrits par part.write() iront dans
le chemin où est exécuté le projet
 Si on veut que les fichiers aient un URL

valide (soit affichables dans une page)


 Location = un espace visible par le serveur
HTTP, soit le docroot, soit le répertoire web
(ou un sous-répertoire) de votre projet
Annotation ServletFilter
@WebFilter(urlPatterns={"/*"}, description="Request timer filter")
public class TimerFilter implements Filter {
private FilterConfig config = null;
@Override
public void init(FilterConfig config) throws ServletException {
this.config = config; config.getServletContext().log("TimerFilter
initialized");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
long before = System.currentTimeMillis(); chain.doFilter(req, resp);

long after = System.currentTimeMillis();


String path = ((HttpServletRequest)req).getRequestURI();
config.getServletContext().log(path + " : "+(after-before));
}
}
Cookies en Java
http://java.sun.com/products/servlet/2.2/javadoc/index.html

 Un cookie a un nom, une valeur, des attributs : comment, path et


domain, un âge maximum, et un numéro de version.
 Une Servlet envoie les cookies au navigateur à l’aide de la
méthode :
HttpServletResponse.addCookie(javax.servelet.http.Cookie)
 Cette méthode ajoute les cookies à la réponse,
 Max 20 cookies par site/utilisateur, 300 cookies au total, Ko par
cookie.
 Question : et HTML5 local et session storage ?
 Le navigateur envoie les cookies au serveur via les requêtes HTTP
(dans le header)
 Les Cookies sont récupérées à l’aide de la méthode
HttpServletRequest.getCookies( ). Plusieurs cookies peuvent avoir
le même nom mais un “path” différent.
Méthodes de manipulation
 Un cookie est une instance de la classe
javax.servlet.http.cookie.
 public Cookie(String name, String value): créée
un cookie avec la paire nom-valeur.
 Cookie c = new Cookie(“id”,”12345”);
 public string getName( ) : renvoie le nom
 public string getValue( ) : renvoie la valeur
 public void setValue(String val) : change la
valeur
 public void setMaxAge(int expiry) : permet de
donner la durée de vie maximum du cookie en
secondes.
Méthodes de manipulation (2)

 public void setPath(java.lang.String uri) : Spécifie le


chemin pour lequel le client doit renvoyer le cookie.
 Le cookie sera visible pour toutes les pages dans le
chemin ou dans le sous-chemin
 Le chemin d’un cookie doit inclure la servlet qui a
créé le cookie, par exemple, /catalog, ce qui rend le
cookie visible pour toutes les pages sous /catalog.
 public java.lang.String getPath() : Renvoie le chemin
d’un cookie
 public String getDomain( ) : renvoie le domaine
 if orea.getDomain.equals(“.miage.fr”)
 … // faire un traitement
 public void setDomain(String _domain): change le
domaine
Méthode doGet utilisant les
cookies
public void doGet(HttpServletResponse req,
HttpServletResponse res)
throws ServletException, IOExceiption{
res.setContentType(“text/html”);
PrintWriter out = res.getWriter( );
out.println (“<H1>Contents of your shopping
cart:</H1>”);
Cookie cookies[ ];
cookies = req.getCookies( );
if (cookies != null) {
for ( int i = 0; i < cookies.length; i++ ) {
if (cookies[i].getName( ).startWith(“Item”))
out.println( cookies[i].getName( ) + “: “ +
cookies[i].getValue( ));
Rappel : Session HTTP ?
 Une session permet de conserver l’état de ce que
fait l’utilisateur
 Le contenu d’une session est persistant entre
plusieurs requêtes HTTP
 Une session est individuelle et dépend du
navigateur, de l’URL (ou famille d’URLs) qu’on
consulte
 Ex : gestion de Login / password (état dans la

session : connecté ou pas)


 Formulaires multi-page (Wizards… next next ok)
 Paniers virtuels
 Préférences utilisateurs, etc.
Gestion de sessions dans les
Servlets
 Il existe une « Servlet session API »
 Permet de récupérer un objet HttpSession
à partir de la requête
(HTTPServletRequest)
 L’objet HTTPSession est une HashMap Java.
 Gestion des objets dans la session : ajout,
modification, retrait, recherche, etc.
 Gestion des méta-information à propos de
la session elle-même : date de création, id
de la session, etc.
Récupérer l’objet session
 Utiliser cette méthode :
HttpServletRequest.getSession()
 Exemple:
HttpSession session = request.getSession(true);
 Retourne la session en cours, en crée une
(true) si il n’en existe pas.
 Pour savoir si il s’agit d’une nouvelle session
utiliser la méthode isNew() de la session
 Il existe des écouteurs du cycle de vie de la
session (on verra plus tard).
En coulisse…
 Quand on appelle getSession(true) chaque
utilisateur se voit attribuer un Session ID
 Le Session ID est communiqué au client
 Option 1: si le navigateur supporte les cookies,
la Servlet créée un cookie avec le session ID,
dans Tomcat, ce cookie est appelé JSESSIONID
 Option 2: si le navigateur ne supporte pas
les cookies, la servlet va essayer de
récupérer le session ID depuis l’URL
Récupérer des données de la
session
 L’objet session fonctionne comme une HashMap
 Peut stocker n’importe quel type d’objet,
 Les objets ont une « clé  d’accès » comme dans les
Maps Java
 Exemple de récupération :
Integer accessCount =
(Integer) session.getAttribute("accessCount");

 Récupérer toutes les « clés » de tous les objets


dans la session :
Enumeration attributes =
request.getAttributeNames();
Mettre des données dans la
session
 Les objets que l’on met dans la sessions
sont des “attributs” :
HttpSession session = request.getSession();
session.setAttribute("nom", "Pierre Dupond");

 Et on peut les supprimer :


session.removeAttribute("name");
Autres informations de session

 Récupérer le session ID, par exemple : gj9xswvw9p


public String getId();
 Voir si la session vient juste d’être créée :
public boolean isNew();
 Récupérer la date de création :
public long getCreationTime();
 Dernière fois que la session a été activée (ex
dernière date de connexion)
public long getLastAccessedTime();
Session Timeout
 Récupérer le plus grand temps (secondes)
d’inactivité de la session (ex : on veut la fermer
si pendant 5mns on ne fait rien)
public int getMaxInactiveInterval();
 Si on spécifie cet intervalle, la session sera fermée
(invalidée) automatiquement lorsqu’un utilisateur
ne fait rien pendant un temps plus long:

public void setMaxInactiveInterval (int seconds);

 Si la valeur est négative : jamais d’interruption


Terminer une session
 Pour terminer (invalider) une session :
public void invalidate();
 Typiquement, on fait ça au logout, ou au
passage d’une commande sur un site de
e-commerce
 Les sessions peuvent se terminer
automatiquement lors de périodes
d’inactivité
Login / Logout – Exemple
 Une appli web protégée par login /
password
 On utilise la session pour stocker
l’utilisateur loggué
 On utilise la clé "username"
 Lorsqu’elle est présente, la valeur = le nom de
l’utilisateur loggué
 Lors de l’authentification on rajoute la clé si
les login/password sont valides
 Cliquer sur logout invalide la session
 La servlet principale vérifie que l’utilisateur
courant est loggué
Formulaire de login
LoginForm.html

<html>
<head><title>Login</title></head>
<body>
<form method="POST" action="LoginServlet">
Please login:<br>
Username:
<input type="text" name="username"><br>
Password:
<input type="password" name="password"><br>
<input type="submit" value="Login">
</form>
</body>
</html>
LoginServlet
LoginServlet.java
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws IOException, ServletException {

String username = req.getParameter("username");


String password = req.getParameter("password");

PrintWriter out = resp.getWriter();


if (isLoginValid(username, password)) {
HttpSession session = req.getSession();
session.setAttribute("USER", username);
response.sendRedirect("MainServlet");
} else {
response.sendRedirect("InvalidLogin.html");
}
MainServlet
MainServlet.java
public class MainServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse resp)
throws ServletException, IOException {

HttpSession session = request.getSession();


String userName = (String)
session.getAttribute("USER");
if (userName != null) {
response.setContentType("text/html");
ServletOutputStream out = resp.getOutputStream();
out.println("<html><body><h1>");
out.println("Hello, " + userName + "! ");
out.println("</h1></body></html>");
} else {
response.sendRedirect("LoginForm.html");
}
}
LogoutServlet
LogoutServlet.java
public class LogoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

HttpSession session = request.getSession();


session.invalidate();
response.setContentType("text/html");
ServletOutputStream out =
response.getOutputStream();
out.println("<html><head>");
out.println("<title>Logout</title></head>");
out.println("<body>");
out.println("<h1>Logout successfull.</h1>");
out.println("</body></html>");
}
Page InvalidLogin.html
InvalidLogin.html

<html>
<head>
<title>Error</title>
</head>
<body>
<h1>Invalid login!</h1>
Please <a href="LoginForm.html">try again</a>.
</body>
</html>
Problèmes avec le cache du navigateur

 La plupart des navigateurs utilisent un cache


pour les pages et les images
 L’utilisateur peut voir “l’ancien état d’une page”
 Peut paraitre pour un bug, surtout dans le cas d’une
page de login
 Pour éviter cela, il faut désactiver le cache
dans la réponse HTTP :
response.setHeader("Pragma", "No-cache");
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache");
Servlets
 Limitations importante des servlets

MAINTENANCE DES PAGES !


Par exemple pour un graphiste…

=> Introduction des JSP


Ressources web
 Tutorial Java EE 6, section Servlets :
http://
docs.oracle.com/javaee/6/tutorial/doc/bn
afd.html
 http://www.servletworld.com/ :
nombreux tutoriaux et exemples
 http://www.kodejava.org/browse/8.html :
idem, nombreux exemples de Servlets
LES JSP

La joie retrouvée
JSP

 Séparation contenu statique/dynamique


 Manipulation des composants JavaBeans
 Extension standard aux Servlets
 Portabilité

Equivalent JAVA de
ASP (Application Server Pages de
Microsoft)
et de PHP
Fonctionnement
JSP = Servlet !
JSP = Servlet !
Tags JSP

Trois types de tags


 <%@ … %>
 Tags de directives
 contrôlent la structure de la servlet générée

 <% … %>
 Tags de scripting
 insertion de code java dans la servlet

 <jsp:… >
 Tags d’actions
 facilitent l’utilisation de composants
Les directives

 Syntaxe :
<%@directive attribut="valeur" …>

 Permettent de spécifier des


informations globales sur la page
 3 types de directives
 page options de configuration de la page
 include inclusions de fichiers statiques
 taglib pour définir des tags d’actions
personnalisées
La directive Page

Principaux attributs de la directive page


 <%@page import="java.util.*,java.sql.Connection" %>
 <%@page contentType="text/html;charset=ISO-8859-1" %>
 <%@page session="true|false" %>
Indique si la page est incluse ou non dans une session. Par défaut true, ce qui
permet d’utiliser un objet de type HttpSession pour gérer des données de
session
 <%@page errorPage="relativeURL" %>
Précise la JSP appelée au cas où une exception est levée , URL relative par
rapport au répertoire qui contient la page JSP ou relative par rapport au
contexte de l’application Web si elle débute par /
 <%@page isErrorPage=" true|false" %>
Précise si la page JSP est une page de gestion d’erreur (dans ce cas l’objet
exception peut être utilisée dans la page), false par défaut.
 <%@page isThreadSafe=" true|false" %>
Précise si la servlet générée est multithreadée ou non.
 …
La directive include

 Syntaxe :
<%@include file="chemin relatif du fichier" %>
 chemin relatif par rapport au répertoire qui contient la page JSP ou
relatif par rapport au contexte de l’application Web si il débute par /
 Inclus le fichier dans le source JSP avant que celui-ci ne soit
interprété (traduit en servlet) par le moteur JSP
 Le fichier peut être un fragment de code JSP, HTML ou Java
 Tag utile pour insérer un élément commun à plusieurs
pages (en-tête, pied de page)

Insertion à la compilation et non pas à l’exécution


un changement du fichier inclus ne provoque pas une
régénération de la servlet
Tags de scripting

 Permettent d’insérer du code Java qui sera


inclus dans la servlet générée
 Trois formes de tags
 <%! …%> tag de déclaration
Code inclus dans le corps de la servlet (déclaration de
membres, variables ou méthodes)
 <%=expression%> tag d’expression

L’évaluation de l’expression est insérée dans le flot de


sortie dans la méthode service() de la servlet
<==> out.println(expression)
 <%...%> tag de scriptlet

Le code Java est inclus dans la méthode service() de


la servlet
Variables implicites

Les spécifications des JSP définissent plusieurs objets


implicite utilisables directement dans le code Java

 out : javax.servlet.jsp.JspWriter
Flux en sortie de la page HTML générée
 request : javax.servlet.http.HttpServletRequest
Contient les informations de la requête
 response :
javax.servlet.http.HttpServletResponse Contient
les informations de la réponse
 session : javax.servlet.http.HttpSession
Gère la session
 exception : java.lang.Throwable
L'objet exception pour une page d'erreur
Exemple de page JSP
<%@ page language="java" contentType="text/html;
charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!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=ISO-
8859-1">
<title>JSP simple : date</title>
</head>

<body>
<%java.text.DateFormat df = new
java.text.SimpleDateFormat("dd/MM/yyyy"); %>

<h1>Date: <%= df.format(new java.util.Date()) %>


</h1>
</body>
</html>
Exemple de page JSP

 Résultat
Tags de scripting
 Exemple de page JSP avec formulaire
Tags de scripting
 Exemple de page JSP avec formulaire
Commentaires

 <!-- ... -->


 Commentaires HTML
 Intégralement reconduits dans le fichier
HTML généré
 <%-- ... --%>
 Commentaires cachés
 Contenu ignoré par le moteur JSP
Gestion des erreurs

 Si une exception est levée dans une


page JSP et n'est pas capturée
 Si pas de page d'erreur associée à la JSP :
affichage de la pile d'exécution
Gestion des erreurs
 Si une exception est levée dans une page JSP et
n'est pas capturée
 Si une page d'erreur est associée : redirection vers cette
page
Bonnes pratiques
Vilain tu ne seras pas !
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
JSP et Java Beans

 Idée : 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
Java Bean

Un composant Java Bean c’est AU MOINS :


 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
Java Bean : exemple

public class Personne {


private String nom;
private String prenom;
private int age;
public Personne() { // instanciation par défaut
this.nom = "X";
this.prenom = "x";
this.age = 0;
}
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;
}
Utiliser un Bean dans les 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"
/>
Utiliser un Bean dans les 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 request
permet d'obtenir une référence sur le bean.
 session : bean utilisable par toutes les JSP de 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
Utiliser un Bean dans les JSP

Exemple :

Avec TOMCAT, les beans doivent être


nécessairement définis dans des packages
Accès aux propriétés

 Le tag <jsp:getProperty> permet


d’obtenir la valeur d’un attribut d’un bean
 Syntaxe
<jsp:getProperty name="beanInstanceName"
property="propertyName" />
Fixer des propriétés

 Le tag <jsp:setProperty> permet de


mettre à jour la valeur de un ou
plusieurs attributs d’un bean
 Syntaxe
<jsp:setProperty
name="beanInstanceName"
property="propertyName"
value="string|<%=expression%>"
/>
Fixer des propriétés

 Exemple :
<jsp:useBean id="utilisateur"
class="test.Personne" scope="session"/>
...
<jsp:setProperty name="utilisateur"
property="nom" value="Toto"/>
<jsp:setProperty name="utilisateur"
property="age" value="34"/>

Quand le type de la propriété du Bean n'est pas String


une conversion automatique est effectuée en
utilisant la méthode valueOf de la classe enveloppe :
<%utilisateur.setAge(Integer.valueOf("34"));%>
Tag de redirection
 Le tag <jsp:forward> permet de rediriger la
requête vers un fichier HTML, une autre page JSP
ou une Servlet
 Syntaxe
<jsp:forward page="relativeURL|<%=expression%>"/>

 Si URL commence par un / elle est absolue (contexte de


l'application) sinon elle est relative à la JSP
 Ce qui suit l'action forward est ignoré, et tout ce
qui a été généré dans cette page JSP est perdu
Tag de redirection

 Possibilité de passer un ou plusieurs


paramètres vers la ressource appelée
<jsp:forward page="relativeURL|<
%=expression%>">
<jsp:param name="parametre"
value="string|<%=expression%>">
...
</jsp:forward>
Tag d’inclusion

 Le tag <jsp:include> permet d'intégrer


dynamiquement un contenu généré par une
autre page JSP ou une autre servlet.
 Comme pour <jsp:forward> possibilité de passer
un ou plusieurs paramètres vers la ressource
incluse en utilisant le tag <jsp:param>
 Syntaxe
<jsp:include page="relativeURL" flush="true|
false"/>
(flush spécifie si le tampon doit être envoyé au
client et vidé)
Tags personnalisés

 Possibilité de définir ses propres tags basés sur


XML :
 tags personnalisés (custom tags)
 regroupés dans des bibliothèques de tags (taglibs)
 Objectifs
 Déporter dans des classes dédiées le code java contenu
dans les scriptlets de la JSP et appeler ce code en
utilisant des tags particuliers
 Améliorer la séparation des rôles :
 page JSP : présentation – concepteur de pages Web
 scriplets / code Java – développeur Java
 Tags personnalisés / Java Beans
 "philosophie" similaire
 Java Beans : objets métier pour stocker et échanger des
données
 Tag personnalisé : interagit directement avec
environnement JSP dans lequel il s'exécute
Tags personnalisés

Les Tags personnalisés son regroupés en


bibliothèques de Tag (Tag Lib). Définit par :

 Une classe Java (Gestionnaire de balise : Tag


Handler)
 code exécuté par le conteneur de JSP lorsque ce Tag
est invoqué dans une page JSP
 implémente interface javax.servlet.jsp.tagext.JSPTa
 Accède à un objet javax.servlet.jsp.JSPWriter pour
générer une réponse
 Une entrée dans le fichier de description de la
bibliothèque à laquelle il est associé (document
XML TLD Tag Library Descriptor)
 la syntaxe du tags – Nom, attributs ….
 La classe du Tag Handler associé
Tags personnalisés

Utilisation :
Pour pouvoir être utilisée dans une page JSP, une
bibliothèque de Tags doit être déclarée avec la
directive <%@ taglib>

<%@taglib uri="/WEB-INF/tlds/MaTagLib.tld" prefix="maTagLib" %>

 Exemple :

<%@taglib uri="/laTagLib" prefix="maTagLib" %>



<h1><maTagLib:HelloTag/></h1>
Tags personnalisés

Deux manières de déployer des bibliothèques de


Tags :

 Sans les packager


 Le fichier .tld de description doit se trouver
dans /WEB-INF où un de ses sous répertoire
(/WEB-INF/tlds)
 Les classes (bytecode) des tag handlers
doivent se trouver dans /WEB-INF/classes

 En les "packageant" dans un fichier jar


 Le fichier jar doit être placé dans
/WEB-INF/lib
Tags personnalisés

 Nombreuses bibliothèques de tags existantes


(Libres, Commerciales)
 JSTL : Java Standard Tag Library for
JavaServer Pages
 Bibliothèque standard développée par JSR
052
 Tags de structure (itération, conditions)
 Internationalisation
 Requêtes SQL
 …
 Nécessite conteneur Web implémentant
au moins API 2.3 des servlets et l'API JSP
1.2
JSP : des librairies
La roue tu ne ré-inveteras pas
JSTL

 Fonctionnalités de JSTL regroupées dans 5


bibliothèques de tags
Rôle Tag Lib Descriptor
 Fonctions de base c.tld
 Internationalisation fmt.tld
 Traitements SQL sql.tld
 Traitements XML x.tld
 Fonctions fn.tld

 En plus JSTL propose un langage d'expression


(EL) permettant de référencer facilement les
objets java accessibles dans le contexte de la JSP
JSTL

 Anciennement Jakarta Tag Lib, maintenant


Tomcat/Apache :
http://tomcat.apache.org/taglibs/
 Utilisation :
 Déclaration dans web.xml :
<taglib>
<taglib-uri>http://jakarta.apache.org/taglibs/{library}</taglib-uri>
<taglib-location>/WEB-INF/{library}.tld</taglib-location>
</taglib>
 Définition dans entête de chaque JSP :
<%@ taglib uri="http://jakarta.apache.org/taglibs/{library}" prefix="x" %>
 Utilisation dans la JSP :
<x:magic id="beanName" name="xyz">
... Some body text and/or nested tags ...
</x:magic>
JSTL
 Définition dépendance maven :
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>
JSTL : Core

 Exemple : appel avec paramètres :


core.jsp?sayHello=true&name=Fred
<%@taglib uri=" http://java.sun.com/jsp/jstl/core" prefix="c"%>
...
<html>
<body>
<h1>
<c:if test="${param.sayHello}">
<!-- Let's welcome the user ${param.name} -->
Hello ${param.name}!
</c:if>
</h1>
</body>
</html>
http://docs.oracle.com/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/index.html
JSTL : Core

 Exemple classique : itération de collection


<body>
<table>
<tbody>
<tr><th>ID</th><th>Name</th><th>Role</th></tr>
<c:forEach items="${requestScope.empList}" var="emp">
<tr><td><c:out value="${emp.id}"></c:out></td>
<td><c:out value="${emp.name}"></c:out></td>
<td><c:out value="${emp.role}"></c:out></td></tr>
</c:forEach>
</tbody>
</table>
Templating et JSP/JSTL
 On peut faire du templating dans des pages
JSPs pour définir des zones « standards »
(header, footer, menu à gauche, etc).
Templating et JSP/JSTL (1)

<%@page contentType="text/html" pageEncoding="UTF-8"%>


<%@taglib uri="http://java.sun.com/jsp/jstl/core"
prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
<c:import url="header.jsp"/>
<body>
<c:import url="MenuGauche.jsp"/>
<c:import url="main.jsp"/>
<c:import url="footer.jsp"/>
</body>
</html>
Exemple : header.jsp
<head>
<title>DOS NDAO BANK</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
<meta http-equiv="content-language" content="fr" />
… CSS
<link href="style.css" title="Défaut"
rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="roundies.js"/>
</script>
… autres scripts
</head>
Autre exemple : Struts Tag Lib

 Exemple : Les tags HTML Struts prennent en


charge l’initialisation des éléments du formulaire

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="ht


<html>
<head>
<title>Formulaire de saisie</title>
</head>
<body>
<H1>Histogramme des notes</H1>
<HR>
<html:form action="notesAnneeMatiere.do">
Année : <html:text property="annee" size="6"/>

http://struts.apache.org
EL (Expression Language)
 langage particulier constitué d'expressions qui
permet en particulier d'utiliser et de faire référence
à des objets java accessibles dans les différents
contextes (page, requête, session ou application)
d'une JSP
 Initialement introduit avec la JSTL
 Supporté de manière standard à partir de la version
1.4 J2EE (Servlets 2.4, JSP 2.0) =>web.xml en
2.3 !!
 une expression EL peut être utilisée directement
dans n'importe quelle page JSP (à la place d'une
expression <%=expressionJava%> )
EL (Expression Language)
... public class Utilisateur {
 Exemple : accès à un attribut
model.Utilisateur u = new private String nom;
private String prenom;
model.Utilisateur();
u.setNom("DUPONT"); public User() {
u.setPrenom("Jean"); }

request.setAttribute("utilisateur public String getNom() {


",u); return nom;
getServletContext().getRequestDis }
public void setNom(String
patcher("/ name) {
testEL.jsp").forward(request, this.nom = nom;
response); }
... public String getPrenom() {
return prenom;
... }
<jsp:useBean id="utilisateur" type="model.Utilisateur"
public void setPrenom(String
scope="session"/> prenom)
... EL recherche
{
l'attribut suivant l'ordre :
<H1
<H1align="center">Au
align="center">Au revoir<BR>
revoir<BR>
- portée dethis.prenom
la page = prenom;
<%=user.getPrenom()%> <%=user.getNom()%>
${user.prenom} ${user.nom} - portée de la requête </H1>
</H1>
...
... - portée de la session
- portée de l'application
EL (Expression Language)
 Accéder à une propriété d'un JavaBean
${user.prenom}
 Accéder à une propriété imbriquée
${user.adresse.ville} ${user.adresse}
 Accéder à une map
${map.a} ${map.u.prenom}
 Accéder à un tableau ou une liste
${array[3]} ${liste[5]}
 Les [ ] utilisables à la place du point
${user["prenom"]} ${map["a"]}
EL (Expression Language)
 Variables implicites EL
pageContext objet PageContext de la page JSP
pageScope Map pour accéder aux attributs définis dans la portée de la page (PageContext
requestScope Map pour accéder aux attributs définis dans la portée de la requête
(HttpServletRequest)
sessionScope Map pour accéder aux attributs définis dans la portée de la session
(HttpSession)
applicationScope Map pour accéder aux attributs définis dans la portée de l'application
(ServletContext)
param Map pour accéder aux paramètres de la requête http sous forme de String
paramValues Map pour accéder aux paramètres de la requête http sous la forme de tableau
de String
header Map pour accéder aux valeurs de l'en-tête de la requête
headerValues Map pour accéder aux valeurs de l'en-tête de la requête sous la forme de
tableau de String
initParam Map pour accéder aux paramètres d'initialisation (init-params du web.xml)
cookie Map pour accéder aux cookies
EL (Expression Language)
 Opérateurs EL
EL : exemples
EL Expression Result
${1 > (4/2)} false
${4.0 >= 3} true
${100.0 == 100} true
${(10*10) ne 100} false
${'a' < 'b'} true
${!empty param.Add} Falseif the request parameter named Add is null or an
empty string.
${pageContext.request.contextPath} The context path.
${sessionScope.cart.numberOfItems} The value of the numberOfItems property of the session-
scoped attribute named cart.
${param['mycom.productId']} The value of the request parameter named
mycom.productId.
${header["host"]} The host.
${departments[deptName]} The value of the entry named deptName in the
departments map.
#{customer.lName} Gets the value of the property lName from the customer
bean during an initial request. Sets the value of lName
during a postback.
#{customer.calcTotal} The return value of the method calcTotal of the
customer bean.
Exemple de gestion de login / password,
session, la page index.jsp

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>


<html>
<body>
<c:import url="header.jsp"/>
<c:if test="${connecte}">
<h2 align="center">Page d'accueil</h2>
<p>Bonjour, vous êtes actuellement sur un site de gestion
d'utilisateurs.
Sur ce site, vous pourrez :<br/>
<ul>
<li>Créer des utilisateurs test</li>
...
</ul>
</c:if>
<c:if test="${!connecte}">
Pour pouvoir effectuer toutes ces actions, il suffit de vous connecter!
</c:if>
</body>
</html>
Exemple de gestion de login / password :
avec session HTTP/JSTL/EL
Exemple de gestion de login / password :
avec session HTTP/JSTL/EL
Exemple de gestion de login / password,
la page header.jsp

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>



<c:if test="${!connecte}">
<form action="ServletConnexion" method="get" id="formconnexion">
Connexion : <input type="text" name="log"><br/>
<input type="text" name="pass"><br/>
<input type="hidden" name="action" value="checkConnexion">
<input type="submit" name="submit" value="Connexion">
</form>
</c:if>
<c:if test="${connecte}">
<a href="ServletConnexion?action=deconnexion">Déconnexion</a>
</c:if>
Exemple de gestion de login / password,
la Servlet
protected void processRequest(HttpServletRequest request,
HttpServletResponse response) … {
String action = request.getParameter("action");
HttpSession session = request.getSession(true);
if(action.equals("checkConnexion")){
if(request.getParameter("log").equals("toto") &&
request.getParameter("pass").equals("toto")) {
session.setAttribute("login", "toto");
session.setAttribute("mdp", "toto");
session.setAttribute("connecte", true);
} else {
session.setAttribute("connecte", false);
}
} else if(action.equals("deconnexion")) {
session.setAttribute("connecte", false);
}
// Redirection vers la page d’accueil
RequestDispatcher dp = request.getRequestDispatcher("index.jsp");
dp.forward(request, response);
}
Rappels sur ce chapitre
 Dans les JSP
 Tags de déclaration seulement
 AUCUN tag de script <% <%=
 Taglib SYSTEMATIQUE [contexte : JSTL,
Struts, Spring…]
 ${} EL partout (ou #)
 Aucun appel direct à une JSP [=> dans
WEB-INF]
 Pas de action = "*.jsp" dans les form

Vous aimerez peut-être aussi