« Programmation JEE/Servlets » : différence entre les versions

Contenu supprimé Contenu ajouté
Ftiercel (discussion | contributions)
m Relecture.
Ligne 1 :
{{JEE}}
{{JEE}}Un servlet est une classe JAVA coté serveur qui reçoit des données HTTP et qui opère un ou des traitements et devant respecter les contraintes de ce protocole HTTP.
Un servlet est une classe JAVA coté serveur qui reçoit des données HTTP et qui opère un ou des traitements et devant respecter les contraintes de ce protocole HTTP.
 
== Les Servlets ==
===Exemple de servlet===
 
==Exemple d'appel d'une servlet==
 
http://localhost:999/webTest/Hello
 
Résultat dans le browser :
<pre>
Hello World
</pre>
==Anatomie de l'url==
[Protocol://][DNS]:[PORT]/[RootEntryDirectory]/[ServletName]
 
==Exemple de servlet==
<source lang="java">
package servlet;
Ligne 47 ⟶ 36 :
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("Hello World");
Ligne 70 ⟶ 59 :
</source>
 
==== Description ====
 
On remarque deux méthodes dans cette classe : doGet et doPost, la première répond par HTTP à l'envoit d'une request GET, la seconde à l'envoi d'une request POST. Comme l'on veut que dans les deux cas la servlet réponde, doPost renvoit à doGet.
 
=== Déployement sous TomCat ===
* Placer la classe compilée avec son package dans le répertoire classes de WEB-INF du répertoire web de travail (ici : webTest)
 
* Modifier le web.xml de WEB-INF en ajoutant :
<sourcesyntaxhighlight lang="xml" highlight="10-17">
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Ligne 89 ⟶ 78 :
 
<servlet>
<servlet-name>Hello</servlet-name><!-- nomNom de la classclasse -->
<servlet-class>servlet.Hello</servlet-class><!-- arborescenceArborescence de la classe : avec le package -->
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name><!-- nomNom de la classe -->
<url-pattern>/Hello</url-pattern><!-- patternPattern de la classe dans l'url -->
</servlet-mapping>
 
Ligne 101 ⟶ 90 :
<web-app>
 
</syntaxhighlight>
</source>
 
Le WEB-INF comprend donc :
Ligne 110 ⟶ 99 :
classes
servlet
helloHello.class
</pre>
 
=== Appel de la servlet ===
== Méthodes d'informations sur l'URL==
http://localhost:999/webTest/Hello
 
Résultat dans le browser :
<pre>
Hello World
</pre>
 
=== Anatomie de l'url ===
[Protocol://][DNS]:[PORT]/[RootEntryDirectory]/[ServletName]
 
=== Méthodes d'informations sur l'URL ===
<source lang="java">
request.getServerName() // Retourne le nom du serveur
// retourne le nom du serveurrequest.getServerName();
request.getServerPort()
// retourne le port du server
request.getContextPath()
// retourne le nom de l'application hébergeant la servlet
request.getServletPath()
// retourne le chemin de la servlet
request.getMethod()
// retourne type de la requete http utillisee
request.getQueryString()
// retourne parametres passes dans url
request.getRequestURL()
// retourne url utilisee pour contacter la servlet
request.getLocalAddr()
// retourne l'adresse locale
request.getLocalName()
request.getLocalPort()
request.getRemoteAddr()
request.getRemoteHost()
</source>
 
// Retourne le port du serveur
request.getServerPort();
 
// Retourne le nom de l'application hébergeant la servlet
request.getContextPath();
 
// Retourne le chemin de la servlet
request.getServletPath();
 
// Retourne type de la requete http utillisee
request.getMethod();
 
// Retourne parametres passes dans URL
request.getQueryString();
 
// Retourne URL utilisee pour contacter la servlet
request.getRequestURL();
 
// Retourne l'adresse locale
request.getLocalAddr();
 
request.getLocalName();
 
request.getLocalPort();
 
request.getRemoteAddr();
 
request.getRemoteHost();
</source>
 
Exemple dans la servlet :
Ligne 154 ⟶ 164 :
@WebServlet("/Hello")
public class Hello extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
Ligne 165 ⟶ 175 :
 
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
{
PrintWriter out = response.setContentTypegetWriter("text/html;charset=UTF-8");
try {
PrintWriter out = response.getWriter();
out.println(request.getServerName());
try{
out.println(request.getServerName()"<br/>");
out.println("<br/>"request.getServerPort());
out.println(request.getServerPort()"<br/>");
out.println("<br/>"request.getContextPath());
out.println(request.getContextPath()"<br/>");
out.println("<br/>"request.getServletPath());
out.println(request.getServletPath()"<br/>");
out.println("<br/>"request.getMethod());
out.println(request.getMethod()"<br/>");
out.println("<br/>"request.getQueryString());
out.println(request.getQueryString()"<br/>");
out.println("<br/>"request.getRequestURL());
out.println(request.getRequestURL()"<br/>");
out.println("<br/>"request.getLocalAddr());
out.println(request.getLocalAddr()"<br/>");
out.println("<br/>"request.getLocalName());
out.println(request.getLocalName()"<br/>");
out.println("<br/>"request.getLocalPort());
out.println(request.getLocalPort()"<br/>");
out.println("<br/>"request.getRemoteAddr());
out.println(request.getRemoteAddr()"<br/>");
out.println("<br/>"request.getRemoteHost());
} finally {
out.println(request.getRemoteHost());
}finallyout.close();
{}
out.close();}
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
processRequest(request, response);
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
processRequest(request,response);
}
 
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
processRequest(request,response);
}
 
processRequest(request, response);
}
}
 
</source>
 
Cet appel : http://localhost:999/webTest/Hello
<pre>
localhost
999
/webTest
/Hello
GET
null
http://localhost:999/webTest/Hello
127.0.0.1
localhost
999
127.0.0.1
127.0.0.1
</pre>
 
=== Méthodes de lecture des paramètres ===
<source lang="java">
request.getParameter( // Recuperation du parametre par le nomParametre)
// recuperation du parametre par le request.getParameter(nomParametre);
 
request.getParameterNames()
// retourneRetourne une enumeration de tous les parametres d'une requete
request.getParameterValuesgetParameterNames(nomParametre);
 
// retourne toutes les valeurs du parametre de nomParametre
// Retourne toutes les valeurs du parametre de nomParametre
request.getParameterMap()
request.getParameterValues(nomParametre);
// retourne iteration de nom de parametres
 
// Retourne une iteration de nom de parametres
request.getParameterMap();
</source>
 
=== Méthodes de lecture des En-Têtes ===
<source lang="java">
// Retourne les noms du header
request.getHeaderNames()
request.getHeaderNames();
// retourne les noms du header
 
request.getHeaders()
// retourneRetourne les headers
request.getContentLengthgetHeaders();
 
// retourne le nombre d'octets dans la requête
// Retourne le nombre d'octets dans la requête
request.getContentType()
request.getContentLength();
// retourne le type de contenu de la requête
 
request.getLocale()
// retourneRetourne lale languetype de contenu de la privilégiéerequête
request.getLocalesgetContentType();
 
// retourne la liste des langues
// Retourne la langue privilégiée
request.getDateHeader(String name)
// retourne la date du headerrequest.getLocale();
 
request.getHeader(String name)
// retourneRetourne lela headerliste spécifiédes par le "name"langues
request.getHeadersgetLocales(String name);
 
// retourne les headers spécifiés par le "name"
// Retourne la date du header
request.getDateHeader(String name);
 
// Retourne le header spécifié par le "name"
request.getHeader(String name);
 
// Retourne les headers spécifiés par le "name"
request.getHeaders(String name);
</source>
 
=== Méthodes d'ajout d'informations à la requèterequête ===
<source lang="java">
// Assure le stockage d'un objet dans l'objet HttpServletRequest
request.setAttribute(String name, Object o)
request.setAttribute(String name, Object o);
// assure le stockage d'un objet dans l'objet HttpServletRequest
 
request.getAttribute(String name)
// retourneRetourne l'objet stocké "name"
request.getAttributeNamesgetAttribute(String name);
 
// returne enumeration des noms d'attributs
// Returne une enumeration des noms d'attributs
request.removeAttribute(String name)
request.getAttributeNames();
// supprime l'attribut "name" des attributs de la requête
 
// Supprime l'attribut "name" des attributs de la requête
request.removeAttribute(String name);
</source>
 
== Méthodes d'ajout des En-Têtes ==
=== Méthodes d'ajout des en-têtes ===
Les en-têtes HTTP sont utilisés pour ajouter à la réponse des informations supplémentaires.
<source lang="java">
response.setContentType(String type)
// Cette méthode permet d'indiquer la nature des informations présentes dans la réponse
response.setLocalesetContentType(LocaleString loctype);
 
// Cette méthode indique la langue locale
response.addHeadersetLocale(StringLocale name, String valueloc);
 
// Cette méthode ajoute le header "name" avec sa valeur "value"
response.addHeader(String name, String value);
</source>
== Elaboration du corps de la réponse ==
*(PrintWriter)getWriter() permet de transferer du texte dans le corps de la réponse HTTP
*(ServletOutputStream)getOUtputStream() permet de transférer du binaire dans le corps de la réponse HTTP
Ne jamais utiliser ces deux objets simultanément sous peine d'une exception IllegalStateException
 
=== Élaboration du corps de la réponse ===
* (PrintWriter)getWriter() permet de transferer du texte dans le corps de la réponse HTTP
* (ServletOutputStream)getOutputStream() permet de transférer du binaire dans le corps de la réponse HTTP
Ne jamais utiliser ces deux objets simultanément sous peine d'une exception IllegalStateException
 
Voici un exemple d'envoi binaire:
Ligne 316 ⟶ 340 :
@WebServlet("/ReponseHttp2")
public class ReponseHttp2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
Ligne 325 ⟶ 349 :
// TODO Auto-generated constructor stub
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.sendRedirect("images/toto.jpg");
{
response.sendRedirect("images/toto.jpg");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
processRequest(request,response);
}
 
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
processRequest(request,response);
}
 
}
</source>
* Dans cet exemple nous faisont appel à processRequest(request, response) pour obtenir invariablement le traitement en get et post
 
==Elaborer= Élaborer une réponse HTTP ===
Les codes de status estsont répartirépartis en 5 catégories :
:1XX : informatif
:2XX : succès
Ligne 362 ⟶ 385 :
Le détail des codes est disponible chez http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
 
* setStatus(int rc)
* sendError(int sc, String message)
 
... permettent de changer le status d'erreur de la page. Pour exemple nous allons générer une erreur serveur.
Ligne 383 ⟶ 406 :
@WebServlet("/ReponseHTTP")
public class ReponseHTTP extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
Ligne 394 ⟶ 417 :
 
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
{
PrintWriter out = response.setContentTypegetWriter("text/html;charset=UTF-8");
try {
PrintWriter out = response.getWriter();
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "le serveur est surchargé. Veuillez réessayer plus tard");
try{
} finally {
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,"le serveur est surchargé. Veuillez réessayer plus tard");
}finallyout.close();
{
out.close();
}
}
}
/**
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
processRequest(request,response);
processRequest(request, response);
}
}
 
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
processRequest(request, response);
}
 
}
Ligne 426 ⟶ 447 :
</source>
 
== Autres ressources ==
=== RequestDispatcher ===
==== include ====
Inclusion d'une ressource externe.
<source lang="java">
RequestDispatcher rd = null;
 
rd = getServletContext().getRequestDispatcher("/header.html");
RequestDispatcher rd=null;
rd=getServletContext().getRequestDispatcher("/header.html");
rd.include(request, response);
 
</source>
 
==== forward ====
Transfert du resultat d'une servlet vers une autre ressource.
<source lang="java">
Ligne 450 ⟶ 469 :
import javax.servlet.HttpServletResponse;
 
public class Result extends HttpServlet {
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Ligne 457 ⟶ 475 :
response.setContenctType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
{ int result = 10;
intRequestDispatcher Resultrd = 10null;
rd = getServletContext().getRequestDispatcher("/result.jsp");
RequestDispatcher rd=null;
rd=getServletContext()request.getRequestDispatchersetAttribute("/resultat", result.jsp");
requestrd.setAttributeforward("resultat"request,Result response);
} finally {
rd.forward(request,response);
}finally{
out.close();
}
Ligne 488 ⟶ 505 :
</source>
 
=== Redirection ===
Le serveur informe le navigateur de faire une requête HTTP vers l'url indiquée.
==== location ====
<source lang="java">
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // pourPour une réponse HTTP 301
response.setHeader("location", "http://www.google.be"); // pourPour une réponse HTTP 302
</source>
==== redirect ====
<source lang="java">
response.sendRedirect("http://www.google.be");
</source>
 
== Filtres ==
Les filtres ajoutent un traitement sur une requête HTTP avant qu'elle soit reçue par une servlet ou sur la réponse HTTP avant qu'elles soient transmises.
 
Leurs roles sont :
 
* Contrôle des accès
* Journalisation des accès
* Décompression des données
* Décryptage
* Conversion des données
 
Plusieurs réponses peuvent être exécutées successivement. La classe filtre doit implémenter <code>javax.servlet.Filter</code>.
 
== EvénementsÉvènements ==
Les évènements nous informent des opérations de l'application comme l'instanciation et la destruction des objets.
 
* EvenementsÉvènements liés à l'application : Ceux déclenchés par servlet context.
* EvenementsÉvènements liés aux sessions : Les classes de ce type doivent implémenter <code>HttpSessionListener</code>, <code>HttpSessionAttributeListener</code>.
 
== Synchronisation des servlets ==
Cette synchronisation permet d'éviter au serveur d'utiliser deux threatthreads en même temps, par exemple, lorsque deux instances de la même classe appelentappellent une même méthode par deux clients différents. syncronizedsynchronized(this){} doit être appliquées aux traitements critiques comme les compteurs.
<source lang="java">
Publicpublic Classclass ... {
public void method() {
{
out = response.getWriter();
public void method()
synchronized(this) {
{
out = response.getWriter() ;
syncronized(this)
{
compteur++;
}
out.println("La valeur du compteur est " + compteur) ;
}
}