 |
 |
15) Informatique distribuée |
|
 |
|
Texte original |
 |
Traducteur :
Jean-Pierre Vidal, Alban Peignier |
|
 |
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
There’s one other issue when using
HttpServlet. This class provides doGet( ) and
doPost( ) methods that differentiate between a CGI “GET”
submission from the client, and a CGI “POST.” GET and POST vary only
in the details of the way that they submit the data, which is something that I
personally would prefer to ignore. However, most published information that
I’ve seen seems to favor the creation of separate doGet( ) and
doPost( ) methods instead of a single generic service( )
method, which handles both cases. This favoritism seems quite common, but
I’ve never seen it explained in a fashion that leads me to believe that
it’s anything more than inertia from CGI programmers who are used to
paying attention to whether a GET or POST is being used. So in the spirit of
“doing the simplest thing that could possibly
work,”[75] I
will just use the service( ) method in these examples, and let it
care about GETs vs. POSTs. However, keep in mind that I might have missed
something and so there may in fact be a good reason to use doGet( )
and doPost( ) instead.
|
 |
L'utilisation de HttpServletpose une autre question. Cette
classe fournit les méthodes doGet( ) et doPost( )qui
différencient une soumission « GET » CGI de la part du client, et un « POST »CGI.
« GET et POST se différencient uniquement par les détails de la manière dont ils soumettent les
données, ce qui est une chose que personnellement je préfère ignorer.
Toutefois, la plupart des informations publiées que j'ai pu voir semblent recommander la création
de méthodes doGet( )et doPost( ) séparées plutôt qu'une
seule méthode générique service( )qui traiterait les deux cas. Ce favoritisme
semble faire l'unanimité, mais je ne l'ai jamais entendu expliquer d'une manière qui me laisserait
supposer qu'il s'agit d'autre chose que de l'inertie des programmeurs CGI habitués à porter leur
attention sur le fait qu'on doit utiliser un GET ou un POST. Aussi, dans l'esprit de faire les
choses les plus simples qui fonctionnent ][75 «
"text-decoration: none">,j'utiliserai uniquement la méthode
service( ) pour ces exemples, et laisserai au lecteur le soin de choisir
entre les GETs et les POSTs. Gardez toutefois à l'esprit qu'il aurait pu m'arriver d'oublier
quelque chose et que cette simple dernière remarque pourrait être une excellente raison d'utiliser
de préférence les méthodes doGet( ) et
doPost( ).
|
 |
 |
 |
Whenever a form is submitted to a
servlet, the HttpServletRequest comes preloaded with all the form data,
stored as key-value pairs. If you know the names of the fields, you can just use
them directly with the getParameter( ) method to look up the values.
You can also get an Enumeration (the old form of the Iterator) to
the field names, as is shown in the following example. This example also
demonstrates how a single servlet can be used to produce the page that contains
the form, and to respond to the page (a better solution will be seen later, with
JSPs). If the Enumeration is empty, there are no fields; this means no
form was submitted. In this case, the form is produced, and the submit button
will re-call the same servlet. If fields do exist, however, they are
displayed.
|
 |
Quand un formulaire est soumis à un servlet,
HttpServletRequest est préchargée avec les données du formulaire présentées sous
la forme de paires clef/valeur. Si on connaît le nom des champs, il suffit d'y accéder directement
avec la méthode getParameter( ) pour connaître leur valeur. Il est également
possible d'obtenir un objet Enumeration (l'ancienne forme d'un
Iterator) vers les noms des champs, ainsi que le montre l'exemple qui suit. Cet
exemple montre aussi comment un seul servlet peut être utilisé pour produire à la fois la page
contenant le formulaire et la réponse à cette page (on verra plus tard une meilleure solution
utilisant les JSP). Si Enumeration est vide, c'est qu'il n'y a plus de
champs ; cela signifie qu'aucun formulaire n'a été soumis. Dans ce cas, le formulaire est
élaboré, et le bouton de soumission rappellera la même servlet. Toutefois les champs sont affichés
lorsqu'ils existent.
|
 |
 |
 |
//: c15:servlets:EchoForm.java
// Dumps the name-value pairs of any HTML form
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class EchoForm extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse res) throws IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
Enumeration flds = req.getParameterNames();
if(!flds.hasMoreElements()) {
// No form submitted -- create one:
out.print("<html>");
out.print("<form method=\"POST\"" +
" action=\"EchoForm\">");
for(int i = 0; i < 10; i++)
out.print("<b>Field" + i + "</b> " +
"<input type=\"text\""+
" size=\"20\" name=\"Field" + i +
"\" value=\"Value" + i + "\"><br>");
out.print("<INPUT TYPE=submit name=submit"+
" Value=\"Submit\"></form></html>");
} else {
out.print("<h1>Your form contained:</h1>");
while(flds.hasMoreElements()) {
String field= (String)flds.nextElement();
String value= req.getParameter(field);
out.print(field + " = " + value+ "<br>");
}
}
out.close();
}
} ///:~
|
 |
//: c15:servlets:EchoForm.java // Affiche les couples nom-valeur d'un formulaire HTML import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*;
public class EchoForm extends HttpServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); Enumeration flds = req.getParameterNames(); if(!flds.hasMoreElements()) { // Pas de formulaire soumis -- on en crée un: out.print("<html>"); out.print("<form method=\"POST\"" + " action=\"EchoForm\">"); for(int i = 0; i < 10; i++) out.print("<b>Field" + i + "</b> " + "<input type=\"text\""+ " size=\"20\" name=\"Field" + i + "\" value=\"Value" + i + "\"><br>"); out.print("<INPUT TYPE=submit name=submit"+ " Value=\"Submit\"></form></html>"); } else { out.print("<h1>Your form contained:</h1>"); while(flds.hasMoreElements()) { String field= (String)flds.nextElement(); String value= req.getParameter(field); out.print(field + " = " + value+ "<br>"); } } out.close(); } } ///:~
|
 |
 |
 |
One drawback you’ll notice here is
that Java does not seem to be designed with string processing in mind—the
formatting of the return page is painful because of line breaks, escaping quote
marks, and the “+” signs necessary to build String objects.
With a larger HTML page it becomes unreasonable to code it directly into Java.
One solution is to keep the page as a separate text file, then open it and hand
it to the Web server. If you have to perform any kind of substitution to the
contents of the page, it’s not much better since Java has treated string
processing so poorly. In these cases you’re probably better off using a
more appropriate solution (Python would be my choice; there’s a version
that embeds itself in Java called JPython) to generate the response
page.
|
 |
On peut penser en lisant cela que Java ne semble pas conçu pour traiter des
chaînes de caractères car le formatage des pages à renvoyer est pénible à cause des retours à la
ligne, des séquences escape, et du signe + inévitable dans la construction des objets
String. Il n'est pas raisonnable de coder une page HTML quelque peu conséquente en
Java. Une des solutions est de préparer la page en tant que fichier texte séparé, puis de l'ouvrir
et de la passer au serveur Web. S'il fallait de plus effectuer des substitutions de chaînes dans le
contenu de la page, ce n'est guère mieux car le traitement des chaînes en Java est très pauvre. Si
vous rencontrez un de ces cas, il serait préférable d'adopter une solution mieux appropriée (mon
choix irait vers Python ; voici une version incluse dans un programme Java appelé JPython) qui
génère une page-réponse.
|
 |
 |
 |
Servlets and
multithreading
|
 |
Les Servlets et le multithreading
|
 |
 |
 |
The servlet container has a pool of
threads that it will dispatch to handle client requests. It is quite likely that
two clients arriving at the same time could be processing through your
service( ) at the same time. Therefore the service( )
method must written in a thread-safe manner. Any access to common resources
(files, databases) will need to be guarded by using the synchronized
keyword.
|
 |
Le conteneur de servlet dispose d'un ensemble de threads qu'il peut lancer
pour traiter les demandes des clients. On peut imaginer cela comme si deux clients arrivant au même
moment étaient traités simultanément par la méthode service( ). En
conséquence la méthode service( ) doit être écrite d'une manière sécurisée
dans un contexte de thread. Tous les accès aux ressouces communes (fichiers, bases de données)
demandent à être protégés par le mot clef synchronized.
|
 |
 |
 |
The following simple example puts a
synchronized clause around the thread’s sleep( )
method. This will block all other threads until the allotted time (five seconds)
is all used up. When testing this you should start several browser instances and
hit this servlet as quickly as possible in each one—you’ll see that
each one has to wait until its turn comes up.
|
 |
L'exemple très simple qui suit utilise une clause
synchronized autour de la méthode sleep( )du thread. En
conséquence les autres threads seront bloqués jusqu'à ce que le temps imparti (cinq secondes) soit
écoulé. Pour tester cela il faut lancer plusieurs instances d'un navigateur puis lancer ce servlet
aussi vite que possible ; remarquez alors que chacun d'eux doit attendre avant de voir le
jour.
|
 |
 |
 |
//: c15:servlets:ThreadServlet.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class ThreadServlet extends HttpServlet {
int i;
public void service(HttpServletRequest req,
HttpServletResponse res) throws IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
synchronized(this) {
try {
Thread.currentThread().sleep(5000);
} catch(InterruptedException e) {
System.err.println("Interrupted");
}
}
out.print("<h1>Finished " + i++ + "</h1>");
out.close();
}
} ///:~
|
 |
//: c15:servlets:ThreadServlet.java import javax.servlet.*; import javax.servlet.http.*; import java.io.*;
public class ThreadServlet extends HttpServlet { int i; public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); synchronized(this) { try { Thread.currentThread().sleep(5000); } catch(InterruptedException e) { System.err.println("Interrupted"); } } out.print("<h1>Finished " + i++ + "</h1>"); out.close(); } } ///:~
|
 |
 |
 |
It is also possible to synchronize the
entire servlet by putting the synchronized keyword in front of the
service( ) method. In fact, the only reason to use the
synchronized clause instead is if the critical section is in an execution
path that might not get executed. In that case, you might as well avoid the
overhead of synchronizing every time by using a synchronized clause.
Otherwise, all the threads will have to wait anyway so you might as well
synchronize the whole
method.
|
 |
On peut aussi synchroniser complètement la servlet en mettant le mot clef
synchronized juste avant la méthode service( ). En réalité,
l'unique justification pour utiliser la clause synchronized à la place de cela est
lorsque la section critique se trouve dans un chemin d'exécution qui ne doit pas être exécuté. Dans
un tel cas, il serait préférable d'éviter la contrainte de synchronisation à chaque fois en
utilisant une clause synchronized. Sinon, chaque thread particulier devrait
systématiquement attendre, il vaut donc mieux synchroniser la méthode en entier.
|
 |
 |
 |
Handling sessions with
servlets
|
 |
Gérer des sessions avec les servlets
|
 |
 |
 |
HTTP is a “sessionless”
protocol, so you cannot tell from one server hit to another if you’ve got
the same person repeatedly querying your site, or if it is a completely
different person. A great deal of effort has gone into mechanisms that will
allow Web developers to track sessions. Companies could not do e-commerce
without keeping track of a client and the items they have put into their
shopping cart, for example.
|
 |
HTTP est un protocole qui ne possède pas la notion de session, on ne peut
donc savoir d'un appel serveur à un autre s'il s'agit du même appelant ou s'il s'agit d'une
personne complètement différente. Beaucoup d'efforts ont été faits pour créer des mécanismes
permettant aux développeurs Web de suivre les sessions. À titre d'exemple, les compagnies ne
pourraient pas faire de e-commerce si elles ne gardaient pas la trace d'un client, ainsi que les
renseignements qu'il a saisi sur sa liste de courses.
|
 |
 |
 |
There are several methods of session
tracking, but the most common method is with persistent “cookies,”
which are an integral part of the Internet standards. The HTTP Working Group of
the Internet Engineering Task Force has written cookies
into the official standard in RFC 2109 (ds.internic.net/rfc/rfc2109.txt
or check www.cookiecentral.com).
|
 |
Il existe plusieur méthodes pour suivre une session, mais la plus commune
utilise les » cookies persistants, « qui font intégralement partie du standard Internet. Le HTTP
Working Group de l'Internet Engineering Task Force a décrit les cookies du standard officiel dans
RFC 2109 (ds.internic.net/rfc/rfc2109.txt ou voir
www.cookiecentral.com).
|
 |
 |
 |
A cookie is nothing more than a small
piece of information sent by a Web server to a browser. The browser stores the
cookie on the local disk, and whenever another call is made to the URL that the
cookie is associated with, the cookie is quietly sent along with the call, thus
providing the desired information back to that server (generally, providing some
way that the server can be told that it’s you calling). Clients can,
however, turn off the browser’s ability to accept cookies. If your site
must track a client who has turned off cookies, then another method of session
tracking (URL rewriting or hidden form fields) must be incorporated by hand,
since the session tracking capabilities built into the servlet API are designed
around cookies.
|
 |
Un cookie n'est pas autre chose qu'une information de petite taille envoyée
par un serveur Web à un navigateur. Le navigateur sauvegarde ce cookie sur le disque local, puis
lors de chaque appel à l'URL associée au cookie, ce dernier est envoyé de manière transparente en
même temps que l'appel, fournissant ainsi au serveur l'information désirée en retour (en lui
fournissant généralement d'une certaine manière votre identité). Toutefois les clients peuvent
inhiber la capacité de leur navigateur à accepter les cookies. Si votre site doit suivre un client
qui a inhibé cette possibilité, alors une autre méthode de suivi de session doit être intégrée à la
main (réécriture d'URL ou champs cachés dans un formulaire), car les fonctionnalités de suivi de
session intégrées à l'API servlet sont construites autour des cookies.
|
 |
 |
 |
The Cookie class
|
 |
La classe Cookie
|
 |
 |
 |
The servlet API (version 2.0 and up)
provides the Cookie class. This class incorporates all the HTTP header
details and allows the setting of various cookie attributes. Using the cookie is
simply a matter of adding it to the response object. The constructor takes a
cookie name as the first argument and a value as the second. Cookies are added
to the response object before you send any content.
|
 |
L'API servlet (à partir de la version 2.0) fournit la classe
Cookie. Cette classe inclut tous les détails de l'en-tête HTTP et permet de
définir différents attributs de cookie. L'utilisation d'un cookie consiste simplement à l'ajouter à
l'objet réponse. Le constructeur a deux arguments, le premier est un nom du cookie et le deuxième
une valeur. Les cookies sont ajoutés à l'objet réponse avant que l'envoi ne soit
effectif.
|
 |
 |
 |
Cookie oreo = new Cookie("TIJava", "2000");
res.addCookie(cookie);
|
 |
Cookie oreo = new Cookie("TIJava", "2000"); res.addCookie(cookie);
|
 |
 |
 |
Cookies are recovered by calling the
getCookies( ) method of the HttpServletRequest object, which
returns an array of cookie objects.
|
 |
Les cookies sont récupérés en appelant la méthode
getCookies( ) de l'objet HttpServletRequest, qui renvoie un
tableau d'objets Cookie.
|
 |
 |
 |
Cookie[] cookies = req.getCookies();
|
 |
Cookie[ « cookies = req.getCookies();
|
 |
 |
 |
You can then call getValue( )
for each cookie, to produce a String containing the cookie contents. In
the above example, getValue("TIJava") will produce a String
containing “2000.”
|
 |
En appelant getValue( )pour chaque cookie, on obtient
une String initialisée avec le contenu du cookie. Dans l'exemple ci-dessus,
getValue("TIJava")renverrait une String contenant » 2000.]
|
 |
 |
 |
The Session class
|
 |
La classe Session
|
 |
 |
 |
A session is one or more page requests by
a client to a Web site during a defined period of time. If you buy groceries
online, for example, you want a session to be confined to the period from when
you first add an item to “my shopping cart” to the point where you
check out. Each item you add to the shopping cart will result in a new HTTP
connection, which has no knowledge of previous connections or items in the
shopping cart. To compensate for this lack of information, the mechanics
supplied by the cookie specification allow your servlet to perform session
tracking.
|
 |
Une session consiste en une ou plusieurs requêtes de pages adressées par un
client à un site Web durant une période définie. Par exemple, si vous faites vos courses en ligne,
la session sera la période démarrant au moment où vous ajoutez un achat dans votre panier jusqu'au
moment où vous envoyez effectivement la demande. Chaque achat ajouté au panier déclenchera une
nouvelle connexion HTTP, qui n'a aucun rapport ni avec les connexions précédentes ni avec les
achats déjà inclus dans votre panier. Pour compenser ce manque d'information, les mécanismes
fournis par la spécification des cookies permet au servlet de suivre la session.
|
 |
 |
 |
A servlet Session object lives on
the server side of the communication channel; its goal is to capture useful data
about this client as the client moves through and interacts with your Web site.
This data may be pertinent for the present session, such as items in the
shopping cart, or it may be data such as authentication information that was
entered when the client first entered your Web site, and which should not have
to be reentered during a particular set of transactions.
|
 |
Un objet servlet Session réside du côté serveur sur le
canal de communication ; son rôle est de capturer les données utiles à propos du client
pendant qu'il navigue sur votre site Web et qu'il interagit avec lui. Ces données peuvent être
pertinentes pour la session actuelle, comme les achats dans le panier, ou bien peuvent être des
information d'authentification fournies lors de l'accès du client au site Web, et qu'il n'y a pas
lieu de donner à nouveau durant un ensemble particulier de transactions.
|
 |
 |
 |
The Session class of the servlet
API uses the Cookie class to do its work. However, all the Session
object needs is some kind of unique identifier stored on the client and passed
to the server. Web sites may also use the other types of session tracking but
these mechanisms will be more difficult to implement as they are not
encapsulated into the servlet API (that is, you must write them by hand to deal
with the situation when the client has disabled cookies).
|
 |
La classe Session de l'API servlet utilise la classe
Cookie pour effectuer ce travail. Toutefois, l'objet Session n'a
besoin que d'une sorte d'identifiant unique stocké chez le client et passé au serveur. Les sites
Web peuvent aussi utiliser les autres systèmes de suivi de session mais ces mécanismes sont plus
difficiles à mettre en oeuvre car ils n'existent pas dans l'API servlet (ce qui signifie qu'on doit
les écrire à la main pour traiter le cas où le client n'accepte pas les cookies).
|
 |
 |
 |
Here’s an example that implements
session tracking with the servlet API:
|
 |
Voici un exemple implémentant le suivi de session au moyen de l'API
servlet :
|
 |
 |
 |
//: c15:servlets:SessionPeek.java
// Using the HttpSession class.
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionPeek extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
// Retrieve Session Object before any
// output is sent to the client.
HttpSession session = req.getSession();
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<HEAD><TITLE> SessionPeek ");
out.println(" </TITLE></HEAD><BODY>");
out.println("<h1> SessionPeek </h1>");
// A simple hit counter for this session.
Integer ival = (Integer)
session.getAttribute("sesspeek.cntr");
if(ival==null)
ival = new Integer(1);
else
ival = new Integer(ival.intValue() + 1);
session.setAttribute("sesspeek.cntr", ival);
out.println("You have hit this page <b>"
+ ival + "</b> times.<p>");
out.println("<h2>");
out.println("Saved Session Data </h2>");
// Loop through all data in the session:
Enumeration sesNames =
session.getAttributeNames();
while(sesNames.hasMoreElements()) {
String name =
sesNames.nextElement().toString();
Object value = session.getAttribute(name);
out.println(name + " = " + value + "<br>");
}
out.println("<h3> Session Statistics </h3>");
out.println("Session ID: "
+ session.getId() + "<br>");
out.println("New Session: " + session.isNew()
+ "<br>");
out.println("Creation Time: "
+ session.getCreationTime());
out.println("<I>(" +
new Date(session.getCreationTime())
+ ")</I><br>");
out.println("Last Accessed Time: " +
session.getLastAccessedTime());
out.println("<I>(" +
new Date(session.getLastAccessedTime())
+ ")</I><br>");
out.println("Session Inactive Interval: "
+ session.getMaxInactiveInterval());
out.println("Session ID in Request: "
+ req.getRequestedSessionId() + "<br>");
out.println("Is session id from Cookie: "
+ req.isRequestedSessionIdFromCookie()
+ "<br>");
out.println("Is session id from URL: "
+ req.isRequestedSessionIdFromURL()
+ "<br>");
out.println("Is session id valid: "
+ req.isRequestedSessionIdValid()
+ "<br>");
out.println("</BODY>");
out.close();
}
public String getServletInfo() {
return "A session tracking servlet";
}
} ///:~
|
 |
//: c15:servlets:SessionPeek.java // Utilise la classe HttpSession. import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*;
public class SessionPeek extends HttpServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Obtenir l'Objet Session avant tout // envoi vers le client. HttpSession session = req.getSession(); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HEAD><TITLE> SessionPeek "); out.println(" </TITLE></HEAD><BODY>"); out.println("<h1> SessionPeek </h1>"); // Un simple compteur pour cette session. Integer ival = (Integer) session.getAttribute("sesspeek.cntr"); if(ival==null) ival = new Integer(1); else ival = new Integer(ival.intValue() + 1); session.setAttribute("sesspeek.cntr", ival); out.println("You have hit this page <b>" + ival + "</b> times.<p>"); out.println("<h2>"); out.println("Saved Session Data </h2>"); // Boucler au travers de toutes les données de la session: Enumeration sesNames = session.getAttributeNames(); while(sesNames.hasMoreElements()) { String name = sesNames.nextElement().toString(); Object value = session.getAttribute(name); out.println(name + " = " + value + "<br>"); } out.println("<h3> Session Statistics </h3>"); out.println("Session ID: " + session.getId() + "<br>"); out.println("New Session: " + session.isNew() + "<br>"); out.println("Creation Time: " + session.getCreationTime()); out.println("<I>(" + new Date(session.getCreationTime()) + ")</I><br>"); out.println("Last Accessed Time: " + session.getLastAccessedTime()); out.println("<I>(" + new Date(session.getLastAccessedTime()) + ")</I><br>"); out.println("Session Inactive Interval: " + session.getMaxInactiveInterval()); out.println("Session ID in Request: " + req.getRequestedSessionId() + "<br>"); out.println("Is session id from Cookie: " + req.isRequestedSessionIdFromCookie() + "<br>"); out.println("Is session id from URL: " + req.isRequestedSessionIdFromURL() + "<br>"); out.println("Is session id valid: " + req.isRequestedSessionIdValid() + "<br>"); out.println("</BODY>"); out.close(); } public String getServletInfo() { return "A session tracking servlet"; } } ///:~
|
 |
 |
 |
Inside the service( ) method,
getSession( ) is called for the request object, which returns the
Session object associated with this request. The Session object
does not travel across the network, but instead it lives on the server and is
associated with a client and its requests.
|
 |
À l'intérieur de la méthode service( ), la méthode
getSession( ) est appelée pour l'objet requête et renvoie un objet
Session associé à la requête. L'objet Session ne voyage pas sur
le réseau, il réside sur le serveur et est associé à un client et à ses requêtes.
|
 |
 |
 |
getSession( ) comes in two
versions: no parameter, as used here, and getSession(boolean).
getSession(true) is equivalent to getSession( ). The only
reason for the boolean is to state whether you want the session object
created if it is not found. getSession(true) is the most likely call,
hence getSession( ).
|
 |
La méthode getSession( ) possède deux versions :
sans paramètres, ainsi qu'elle est utilisée ici, et getSession(boolean). L'appel
de getSession(true) est équivalent à getSession( ).Le
boolean sert à indiquer si on désire créer l'objet session lorsqu'on ne le trouve
pas. L'appel le plus probable est getSession(true), d'où la forme
getSession( ).
|
 |
 |
 |
The Session object, if it is not
new, will give us details about the client from previous visits. If the
Session object is new then the program will start to gather information
about this client’s activities on this visit. Capturing this client
information is done through the setAttribute( ) and
getAttribute( ) methods of the session object.
|
 |
L'objet Session, s'il n'est pas nouveau, nous donne des
informations sur le client à partir de visites antérieures. Si l'objet Session est
nouveau alors le programme commencera à recueillir des informations à propos des activités du
client lors de cette visite. Le recueil de cette information est effectué au moyen des méthodes
setAttribute( ) et getAttribute( ) de l'objet
session.
|
 |
 |
 |
java.lang.Object getAttribute(java.lang.String)
void setAttribute(java.lang.String name,
java.lang.Object value)
|
 |
java.lang.Object getAttribute(java.lang.String) void setAttribute(java.lang.String name, java.lang.Object value)
|
 |
 |
 |
The Session object uses a simple
name-value pairing for loading information. The name is a String, and the
value can be any object derived from java.lang.Object. SessionPeek
keeps track of how many times the client has been back during this session. This
is done with an Integer object named sesspeek.cntr. If the name is
not found an Integer is created with value of one, otherwise an
Integer is created with the incremented value of the previously held
Integer. The new Integer is placed into the Session object.
If you use same key in a setAttribute( ) call, then the new object
overwrites the old one. The incremented counter is used to display the number of
times that the client has visited during this session.
|
 |
L'objet Session utilise une simple paire nom/valeur pour
garder l'information. Le nom est du type String, et la valeur peut être n'importe
quel objet dérivé de java.lang.Object. SessionPeek garde la trace
du nombre de fois où le client est revenu pendant cette session, au moyen d'un objet
Integer nommé sesspeek.cntr. Si le nom n'existe pas on crée un
Integer avec une valeur de un, sinon on crée un Integer en
incrémentant la valeur du précédent. Le nouvel Integer est rangé dans l'objet
Session. Si on utilise la même clef dans un appel à
setAttribute( ), le nouvel objet écrase l'ancien. Le compteur incrémenté sert
à afficher le nombre de visites du client pendant cette session.
|
 |
 |
 |
getAttributeNames( ) is
related to getAttribute( ) and setAttribute( ); it
returns an enumeration of the names of the objects that are bound to the
Session object. A while loop in SessionPeek shows this
method in action.
|
 |
La méthode getAttributeNames( ) est en relation avec
getAttribute( ) et setAttribute( ) et renvoie une
énumération des noms des objets associés à l'objet Session. Une boucle
while de SessionPeek montre cette méthode en action.
|
 |
 |
 |
You may wonder how long a Session
object hangs around. The answer depends on the servlet container you are using;
they usually default to 30 minutes (1800 seconds), which is what you should see
from the ServletPeek call to getMaxInactiveInterval( ). Tests
seem to produce mixed results between servlet containers. Sometimes the
Session object can hang around overnight, but I have never seen a case
where the Session object disappears in less than the time specified by
the inactive interval. You can try this by setting the inactive interval with
setMaxInactiveInterval( ) to 5 seconds and see if your
Session object hangs around or if it is cleaned up at the appropriate
time. This may be an attribute you will want to investigate while choosing a
servlet container.
|
 |
Vous vous interrogez sans doute sur la durée de vie d'un objet
Session. La réponse dépend du conteneur de servlet qu'on utilise ;
généralement la durée de vie par défaut est de 30 minutes (1800 secondes), ce que l'on peut voir au
travers de l'appel de getMaxInactiveInterval( ) par
ServletPeek. Les tests semblent montrer des résultats différents suivant le
conteneur de servlet utilisé. De temps en temps l'objet Session peut faire le tour
du cadran, mais je n'ai jamais rencontré de cas où l'objet Session disparaît avant
que le temps spécifié par « inactive interval » soit écoulé. On peut tester cela en
initialisant « inactive interval » à 5 secondes au moyen de
setMaxInactiveInterval( )puis voir si l'objet Session est
toujours là ou au contraire a été détruit à l'heure déterminée. Il se pourrait que vous ayez à
étudier cet attribut lorsque vous choisirez un conteneur de servlet.
|
 |
 |
 |
Running the servlet examples
|
 |
Faire fonctionner les exemples de servlet
|
 |
 |
 |
If you are not already working with an
application server that handles Sun’s servlet and JSP technologies for
you, you may download the Tomcat
implementation of Java servlets and JSPs, which is a free, open-source
implementation of servlets, and is the official reference implementation
sanctioned by Sun. It can be found at
jakarta.apache.org.
|
 |
Si vous ne travaillez pas encore sur un serveur d'applications gérant les
servlets Sun ainsi que les technologies JSP, il vous faudra télécharger l'implémentation Tomcat des
servlets Java et des JSP, qui est une implémentation libre et « open-source » des
servlets, et de plus l'implémentation officielle de référence de Sun. Elle se trouve à
jakarta.apache.org.
|
 |
 |
 |
Follow the instructions for installing
the Tomcat implementation, then edit the server.xml file to point to the
location in your directory tree where your servlets will be placed. Once you
start up the Tomcat program you can test your servlet programs.
|
 |
Suivez les instructions d'installation de l'implementation Tomcat, puis
éditez le fichier server.xml pour décrire l'emplacement de votre répertoire qui
contiendra vos servlets. Une fois lancé le programme Tomcat vous pouvez tester vos programmes
servlet.
|
 |
 |
 |
This has only been a brief introduction
to servlets; there are entire books on the subject. However, this introduction
should give you enough ideas to get you started. In addition, many of the ideas
in the next section are backward compatible with
servlets.
|
 |
Ceci n'était qu'une brève introduction aux servlets ; il existe des
livres entiers traitant de ce sujet. Toutefois, cette introduction devrait vous donner suffisamment
d'idées pour démarrer. De plus, beaucoup de thèmes développés dans la section suivante ont une
compatibilité ascendante avec les servlets.
|
 |
 |
 |
Java Server Pages
|
 |
Les Pages Java Serveur - Java Server Pages
|
 |
 |
 |
Java Server Pages (JSP) is a standard
Java extension that is defined on top of the servlet Extensions. The goal of
JSPs is the simplified creation and management of dynamic Web
pages.
|
 |
Les Java Server Pages (JSP) sont une extension standard Java définie
au-dessus des extensions servlet. Le propos des JSP est de simplifier la création et la gestion des
pages Web dynamiques.
|
 |
 |
 |
The previously mentioned, freely
available Tomcat reference implementation from jakarta.apache.org
automatically supports JSPs.
|
 |
L'implémentation de référence Tomcat, déjà mentionnée et disponible
librement sur jakarta.apache.org "font-style: normal">, supporte automatiquement les
JSP.
|
 |
 |
 |
JSPs allow you to combine the HTML of a
Web page with pieces of Java code in the same document. The Java code is
surrounded by special tags that tell the JSP container that it should use the
code to generate a servlet, or part of one. The benefit of JSPs is that you can
maintain a single document that represents both the page and the Java code that
enables it. The downside is that the maintainer of the JSP page must be skilled
in both HTML and Java (however, GUI builder environments for JSPs should be
forthcoming).
|
 |
Les JSP permettent de mélanger le code HTML d'une page Web et du code Java
dans le même document. Le code Java est entouré de tags spéciaux qui indiquent au conteneur JSP
qu'il doit utiliser le code pour générer une servlet complètement ou en partie. L'avantage que
procurent les JSP est de maintenir un seul document qui est à la fois la page HTML et le code Java
qui la gère. Le revers est que celui qui maintient la page JSP doit être autant qualifié en HTML
qu'en Java (toutefois, des environnements GUI de construction de JSP devraient apparaître sur le
marché).
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |