Académique Documents
Professionnel Documents
Culture Documents
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)
Pour exé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'API servlet 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.servlet Nom Role
Enumeration liste
=req.getParameterNames();
String [] valeurs = req.getParameterValues();
String val1 = req.getParameter(''param1'');
<HTML>
<HEAD><TITLE> ANNUAIRE </TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF"<CENTER>
<CENTER><H1>ANNUAIRE DU DESS TIIR </H1></CENTER>
<HR><CENTER>
<H2>Recherche de coordonnées </H2></CENTER>
<P> Tapez le début du nom de la personne recherchée:
<P><FORM METHOD=POST ACTION=annuaire >
<INPUT TYPE=TEXT NAME="nom" SIZE=20 MAXLENGTH=30
VALUE="">
<P><INPUT TYPE=SUBMIT NAME="go" VALUE="RECHERCHER">
<INPUT TYPE=RESET NAME="reset" VALUE="ANNULER">
</FORM>
</BODY></HTML>
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Annuaire extends HttpServlet{
public void doPost( HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
res.setContType("text/html");
PrintWriter out=res.getWriter();
out.println("<HEAD><TITLE>Réponse annuaire </TITLE></HEAD><BODY>");
out.println("<HR>");
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
String url ="jdbc:odbc:mabase";
java.sql.Connection c=DriverManager.getConnection(url,"","");
java.sql.Statement st = c.createStatement();
java.sql.ResultSet rs =
st.executeQuery("Select * from matable where nom like '"
+req.getParameter("nom"+"*'"));
rs.next();
out.println(rs.getString("prenom")+" "+rs.getString("nom") );
}
catch (SQLException e){
out.println("Cette personne n'existe pas");
}
out.println("<P><A href = annuaire.html> Retour</A>"</P>);
out.println("</BODY>");
out.close();
}
public String getServletInfo(){
return "Servlet Annuaire";
}
Au lieu du try …catch
<error-page>
<exception-type> java.lang.NumberFormatException
</exception-type>
<location>/WEB-INF/NombreIncorrect.html
</location>
</error-page>
ou/et les sous-éléments suivant :
<error-page>
<code-type>500</exception-type>
<location>
/WEB-INF/ErreurServeur.html
</location>
</error-page>
Ajout de cookies à l ’entête de la réponse
void HttpServletResponse.
addCookie( Cookie cookie)
Le cookie peut être un cookie récupéré dans la
requête
Et modifié avant d’être ajouté à la réponse
Garder la mémoire des informations d'une page à l'autre :
Utiliser les cookies (sécurité!)
Syntaxe CGI : paramètres dans l'URL
Champs ``HIDDEN'' de formulaires
<INPUT TYPE=''HIDDEN'' NAME=''PARAM1''VALUE=''VAL1''>
Objet HttpSession
HttpSession session=request.getSession(true);
Classe objet = (Classe) session.getValue(''param1'');
Méthodes : getValue(), putValue(), removeValue()
HttpSession session = req.getSession(true);
If (session.isNew()){
session.putValue('‘toto'', new int[] {0});
}
Int[] toto = (int[]) session.getValue('‘toto'');
Le serveur maintient une session de 2 manières :
Cookie (Name: SESSIONID Value: To1010mC8601021835741167At)
▪ les cookies peuvent être désactivés sur le navigateur
Réécriture des URLs
Ouverture/récupération d ’une session
javax. servlet. http. HttpSession session = req. getSession( false);
// la session est récupérée ou null si elle n ’existait pas déjà
javax. servlet. http. HttpSession session = req. getSession( true);
//la session est récupérée ou ouverte si elle n ’existait pas déjà
Invalidation d ’une session
javax. servlet. http. HttpSession session = req. getSession( false);
session. invalidate(); la session est invalidée ( i. e. fermée)
javax. servlet. http. HttpSession session = req. getSession( false);
L ’identifiant
String sessionid= session. getId(); // par exemple: To1010mC8601021835741167At
La date de création
long datecreation= session. getCreationTime(); // nb de ms depu s 1/ 1/ 1970: 00: 00
La date du dernier accès
long datelastaccess= session. get astAccessedTime();
Exemple
HttpSession session = req. getSession( true);
if( session. get astAccessedTime() - session. getCreationTime() > 5* 60* 1000 ) {
session. invalidate();
}
javax. servlet. http. HttpSession session = req. getSession( false);
Méthode de suivi de session
boolean HttpServletRequest. isRequestedSessionIdFromCookie()
// test si le suivi de session utilise un cookie
boolean HttpServletRequest. isRequestedSessionIdFromUR ()
// test si le suivi de session utilise la réécriture d ’UR
Réécriture des URL (cas isRequestedSessionIdFromURL )
les URL générées doivent être encodées pour intégrer le suivi de session
String HttpServletResponse. encodeRedirectUR (String url)
String HttpServletResponse. encodeUR (String url)
Exemple
res. sendRedirect( res. encodeRedirectUR (" servlet login");
javax. servlet. http. HttpSession session = req.
getSession( true);
Ajout/remplacement d ’une valeur
void HttpSession. setAttribute( String name, Object value)
Suppression d ’une valeur
void HttpSession. removeAttribute( String name)
Récupération des valeurs/d ’une valeur
String[] HttpSession. getAttributeNames()
Object HttpSession. getAttribute( String name)
Motivations
réagir face à des événements intervenants dans la/les sessions
4 interfaces Listeners
HttpSessionActivationListener
la session peut être passivée puis réactivée
HttpSessionListener
changement sur la liste des sessions actives de l'application Web.
HttpSessionAttributeListener
changement sur les attributs d’une des sessions de l’application
Web.
HttpSessionBindingListener
un objet peut être notifié de sa liaison rupture à un session
HttpSessionActivationListener
la session peut être passivée puis réactivée
void sessionDidActivate( HttpSessionEvent se)
void sessionWillPassivate( HttpSessionEvent se)
HttpSessionListener
changement sur la liste des sessions actives de l'application Web.
void sessionCreated( HttpSessionEvent se)
Void sessionDestroyed( HttpSessionEvent se) invalidation
HttpSessionAttributeListener
attribute lists of sessions within this web application.
void attributeAdded( HttpSessionBindingEvent se)
void attributeRemoved( HttpSessionBindingEvent se)
void attributeReplaced( HttpSessionBindingEvent se)
HttpSessionBindingListener
un objet peut être notifié de sa liaison rupture à un session
void valueBound( HttpSessionBindingEvent event)
void valueUnbound( HttpSessionBindingEvent event)
Motivations
faire réagir les objets liés aux liaisons et « déliaisons »
fermer des fichiers, des connexions, valider des transactions, ...
API
interface HttpSessionBinding istener
public void valueBound( HttpSessionBindingEvent event)
public void valueUnbound( HttpSessionBindingEvent
event)
class HttpSessionBindingEvent extends EventObject
public Session getSession() la session concernée
public String getName() le nom de la liaison
Principe
l ’objet lié doit implanté HttpSessionBinding istener
valueBound () est invoqué quand l ’objet est lié ( putValue ())
valueUnbound () est invoqué quand la session est invalidé ou expire ou
quand l ’objet est délié ( setAttribute ()/ removeAttribute ()).
import java.io.IOException;
import java.io.PrintWriter;
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;
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.
La section <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);
}
}