Beruflich Dokumente
Kultur Dokumente
Partie trois
Une servlet est un programme qui
s'exécute côté serveur en tant
qu'extension du serveur.
La technique des CGI en Java, MAIS
Sans créer de processus + toute la puissance
de Java (accès aux divers domaines de
l'informatique: BD, multimédia, réseau, objets
distribués, composants, etc.)
+ indépendance de la plate-forme et du
serveur
Servlets
Scripts serveur écrit en Java
Servlets de Base : FileServlet, CGIServlet, …
HttpServlet
Exécution dans un espace isolé (Web Application)
Spécification : Sun (sous partie de J2EE)
Implémentation de référence : Apache Group
(Jakarta Tomcat)
Différence avec les CGI et les LD (NSAPI, ISAPI)
performance sur les passages des paramêtres (vs CGI)
sûreté de fonctionnement (NSAPI, ISAPI)
Pourexécuter des servlets, il faut un
moteur de servlets dans le serveur
Web.
Ces moteurs sont des plug-in pour des
serveurs Web existants
ou bien des serveurs Web aux mêmes
Plug-in : deux candidats : Jrun
(www.allaire.com), tomcat
(jakarta.apache.org)
Utilise deux paquetages :
javax.servlet : paquetage générique
javax.servlet.http : paquetage pour
serveurs Web
Ces paquetages ne sont pas dans
J2SE 1.3
Sont des paquetages supplémentaires.
Il sont aussi intégrés dans J2EE voir à
http://java.sun.com/j2ee/
L'APIservlet regroupe un ensemble
de classes dans deux packages :
javax.servlet : contient les classes pour
développer des serlvets génériques
indépendantes d'un protocole.
javax.servlet.http : contient les classes
pour développer des servlets qui
reposent sur le protocole http utilisé par
les serveurs web.
javax.servle Nom Role
t
Les RequestDispatche Définition d'un objet qui permet le renvoi
interfaces r d'une requête vers une autre ressource du
serveur (une autre servlet, une JSP ...)
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class Binder extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
HttpSession session = req.getSession(true);
SessionObject o = new SessionObject(getServletContext());
session.setAttribute("Binder.object", o);
out.println("<html>");
out.println("<head>");
out.println("<title>Session Binder</title>");
out.println("</head>");
out.println("<body>");
out.println("Object bound to session " + session.getId());
out.println("</body>");
out.println("</html>");
out.flush();
}
}
class SessionObject implements HttpSessionBindingListener {
ServletContext context;
public SessionObject(ServletContext context) {
this.context = context;
}
public void valueBound(HttpSessionBindingEvent event) {
context.log("" + (new java.util.Date()) + " Binding " + event.get
Name() + " to session "
+ event.getSession().getId());
}
public void valueUnbound(HttpSessionBindingEvent event) {
context.log("" + (new java.util.Date()) + " Unbinding " + event.g
etName() + " from session "
+ event.getSession().getId());
}
}
import java.util.Date; public void sessionDestroyed(HttpSession
import javax.servlet.http.HttpSession; Event se) {
import javax.servlet.http.HttpSessionEven HttpSession session = se.getSession();
t; String id = session.getId();
import javax.servlet.http.HttpSessionListe synchronized (this) {
ner; --sessionCount;
}
public class SessionListen implements Htt String message = new StringBuffer("Ses
pSessionListener { sion destroyed"
private int sessionCount; + "\nValue of destroyed session ID is"
public SessionListen() { ).append("" + id).append( "\n").append("Th
this.sessionCount = 0; ere are now ").append("" + sessionCount)
} .append(" live sessions in the applicat
public void sessionCreated(HttpSessionE ion.").toString();
vent se) { System.out.println(message);
HttpSession session = se.getSession(); }
session.setMaxInactiveInterval(60); }
synchronized (this) {
sesesionCount++;
}
String id = session.getId();
Date now = new Date();
String message = nw StringBuffer("New
Session created on ").append(
now.toString()).append("\nID: ").appe
nd(id).append("\n")
.append("There are now ").append(""
+ sessionCount).append(
" live sessions in the application.").
toString();
System.out.println(message);
}
Motivation
partager une information commune
entre servlets, ...
Plusieurs
S1 : utilisez les Properties de java. lang.
System
S2 : classe commune avec des
membres statiques
S3 : utilisez le contexte de l’application
Solution 1 : utilise les Properties de java. lang. System
String java. lang. System. getProperty( String key)
String java. lang. System. setProperty( String key, String
value)
Remarque : les Properties sont partagées par toutes les WebApps
du serveur J2EE
Solution 2 : classe commune avec des membres statiques
l ’initialisation des membres statiques XXX peut se faire au
moment du premier accès par une des servlets
Remarque pour une meilleure programmation
les membres statiques sont privés et sont accédés par des
méthodes statiques setXXX() et getXXX()
la classe n ’est accessible que par les servlets du même package
et chargée par le même ClassLoader (un par WebApp)
Solution 3 : utiliser les <env- entry> du contexte JNDI de
l’application
Paires typées (name, value, classname) appartenant au
contexte de l’application Web
<env- entry>
<env- entry- name> defaultCurrency< env- entry- name>
<env- entry- value> EUR< env- entry- value>
<env- entry- type> java. lang. String< env- entry- type>
< env- entry>
<env- entry>
<env- entry- name> default anguage< env- entry- name>
<env- entry- value> 33< env- entry- value>
<env- entry- type> java. lang. Integer< env- entry- type>
< env- entry>
Récupération des <env- entry> via JNDI
Context ctx = new InitialContext();
Object value = ctx. lookup(" java: comp env
defaultCurrency");
out. println(" Default currency value : " + value);
Context envCtx = ( Context) ctx. lookup(" java: comp env ");
NamingEnumeration enum = ctx. list(" java: comp env ");
while (enum. hasMoreElements()) {
out. print(" Binding : "+ ( enum. nextElement(). toString());
}
NamingEnumeration enumbinding = envCtx. listBindings("
java: comp env ");
while (enumbinding. hasMoreElements()) {
out. print(" Binding : "+( enumbinding. nextElement().
toString());
Deux types d'entrées du fichier web.xml contrôlent
la sécurité et l'authentification (avec toutefois un
troisème pour la définition du rôle) :
<security-contraint> : qui fournissent des
autorisations basées sur les rôles utilisateurs et, si
vous le souhaitez, sur le transport sécurisé de
données.
<login-config> : qui détermine le type
d'authentification utilisée pour l'application Web.
<security-role> : qui définit un rôle de sécurité
pour l'application web. (A placer avant la balise
<security-contraint>).
le modèle d'identification
BASIC, qui affiche dans le
navigateur une simple boîte
de dialogue :
nom d'utilisateur/mot de pass
e
le modèle d'URL est “/”, ce qui signifie que toute l'application Web est
sécurisée. Nous pourrions sécuriser qu'une seule partie de l'application
Web, par exemple un répertoire de l'application qui ne sera accessible
que par mot de passe.
Avant que cela fonctionne, il reste toutefois une étape à franchir : créer le
rôle utilisateur "personnel",
Pour que votre application Web soit parfaitement
sécurisée, il faudrait également protéger les informations
qui transitent sur le réseau. Il nous faut donc aborder un
élément supplémentaire de la contrainte de sécurité : la
garantie de transport.
Chaque bloc <security-contraint> peut finir par une entrée
<user-data-contraint>, qui indique lequel des trois niveaux
de sécurité de transport est retenu pour le protocole utilisé
lors du transfert de données de et vers la zone protégées
NONE : qui est équivalent à une sortie de section , sans transport
spécial. C'est le mode standard pour le trafic web, qui en général
véhicule du texte plein via le réseau.
INTEGRAL : précise que le protocole de transport utilisé doit
garantir que les données envoyées ne sont pas modifiées durant le
transit. Ceci implique l'utilisation de signatures digitales ou de tout
autre méthode de validation des données à l'arrivée, mais n'impose
pas que les données soient chiffrées et cachées durant le transport.
CONFIDENTIAL : ajoute le chiffrement à la méthode INTEGRAL. En
pratique, le seul mode de transport sécurisé largement utilisé dans
les navigateurs web est SSL. Exiger une garantie de transport autre
que NONE impose l'utilisation du SSL au navigateur client.
Lasection <login-config> détermine
exactement comment un utilisateur
s'authentifie à l'entrée de la zone
protégée. La balise <auth-method>
permet d'utiliser quatre types
d'authentification :
BASIC : utilise la boîte de dialogue standard
"nom/mot de passe" du navigateur web.
L'authentification BASIC envoie le nom et le mot
de passe utilisateur en texte plein sur le réseau, à
moins qu'une garantie de transport n'ait été
utilisée séparément pour démarrer SSL et chiffrer
le stream de données.
DIGEST : est une variante de BASIC qui cache le
texte de mot de passe mais n'est pas vraiment
beaucoup plus sécurisée ; elle est peu utilisée.
FORM : est équivalente à BASIC, mais permet
d'utiliser, au lieu de la boîte de dialogue standard,
son propre formulaire HTML ou servlet.
CLIENT-CERT : est une option intéressante. Elle
impose que l'utilisateur soit identifié via un
certificat de clé publique côté client. Ceci implique
l'utilisation d'un protocole comme SSL, qui permet
des échanges sécurisés et l'authentification
mutuelle en utilisant des certificats numériques.
Méthodes relatives à l’authentification :
public String getAuthType() : renvoie BASIC_AUTH,
DIGEST_AUTH, CLIENT_CERT_AUTH ou FORM_AUTH
public String getUserName()
public Principal getUserPrincipal() à utiliser avec
le package java.security
public boolean isUserInRole()
Exemple:
out.println("Est-un administrateur : " +
req.isUserInRole("admin"));.
Redirige la traitement de la requête
vers une autre servlet ou JSP
Utilisé pour le MVC
Exemple
public class ForwardServlet extends HttpServlet {
public void doGet (HttpServletRequest request,
HttpServletResponse response) {
//Set the attribute and forward to hello. jsp
request. setAttribute (" action", " hello");
ServletContext context= getServletConfig().
getServletContext().
context. getRequestDispatcher(" hello. jsp").
forward( request, response);
}
}