PL2 15servlets
PL2 15servlets
PL2 15servlets
Servlets
Philippe Genoud
©
© Philippe
Philippe GENOUD
GENOUD UGA
UJF Février 2020
2005 1
La plateforme Java EE
les Servlets s'inscrivent dans la plateforme Java EE (Java Entreprise Edition)
Java EE (Java Enterprise Edition), anciennement J2EE (Java 2 Entreprise Edition) et maintenant Jakarta EE est
un ensemble de spécifications étendant JSE pour le développement d’applications d’entreprise.
EL (Unified Expression Language): langage simple pour lier des composants (JSP ou JSF) avec des objets Java,
Services Web
Java API for XML Web Services: pour la création de services web SOAP,
Java API for RESTful Web Services: support pour créer des services web conformes aux principes architecturaux REST
(Representational State Transfer);
Java API for JSON Processing: gestion d’informations encodées au format JSON format;,
Java API for JSON Binding: conversion d’informations JSON en classes et objets Java et inversement,
JTA (Java Transaction API) : interaction avec le support transactionnel offert par JEE with the transaction support
offert par Java EE.
JMS (Java Message Service) : création, envoi, réception de messages d’un système de messagerie d’entreprise.
Autres spécifications
Validation (Bean Validation API) : fournit un moyen unifié pour définir des contraintes sur les objets métiers (beans,
par exemple les classes de modèle JPA model) qui peuvent être appliquées sur plusieurs couches (persistance JPA,
vues JSF).
Batch Applications: exécution de programmes en tâches de fond.
Conteneur WEB
Client riche
présentation (application Java)
Pages JSP
Pages JSP Servlets
Tier web
Serveur JEE
Serveur Conteneur EJB Tier métier
métier d'applications EJB EJB EJBEJB
EJB
JEE
Serveur
Tier Système
données de bases
d'Information de
l'Entreprise de données
• Logique de l'application :
– Composants web (Servlet, JSP,JFS)
– Composants métiers (EJB Entreprise Java Beans)
• Services standards (cycle de vie des composants, multithreading, transactions, persistance…) pris en charge par les conteneurs
Web et EJB du serveur d'application JEE
WildFly (RedHat),
Serveurs JEE7
… http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.html
Servlet (https://javaee.github.io/tutorial/servlets001.html#BNAFE)
classe Java pour étendre les possibilités de serveurs hébergeant des applications accédées par un
modèle de programmation de type requête-réponse
JVM
servlets peuvent potentiellement répondre à tout type de requête mais dans la réalité sont le plus souvent
utilisées pour étendre des applications hébergées par un serveur web requêtes HTTP
contenu statique
réponse HTTP
HTTP frontend
requête HTTP
(1) requête HTTP
Serveur Web
API JDBC
Serveur BD
objets ServletHTTP
HTTP frontend
req1 client 1 pour différentes
req2 client 1 requêtes
req2 client 2
req3 client3
GenericServlet
+service(req:ServletRequest, resp: ServletResponse) <<interface>> ServletRequest <<interface>> ServletResponse
+init():void
+destroy():void +getAttribute(name:String):Object +setContentType(type:String):void
+getServletInfo():String +setAttribute(name:String, o:Object):void +getWriter():PrintWriter;
+getServletConfig():ServletConfig ... ...
+getServletContext():ServletContex
...
javax.Servlet.http
requête GET
réponse doGet(…)
service()
requête POST
doPost(…)
réponse
Utilisation :
Appel de la méthode service()
Destruction :
Peut être provoquée pour optimiser la mémoire
Servlet
import java.io.IOException;
import java.io.PrintWriter;
import java.utilDate;
import javax.servlet.ServletException; imports des différentes classes et interfaces
import javax.servlet.annotation.WebServlet; nécessaires à l'écriture du code de la servlet.
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
annotation définissant l'url
associée à cette servlet @WebServlet(name = "HelloWorldServlet", urlPatterns = {"/HelloWorld"})
(servlet Mapping)
avant JEE6 public class HelloWorldServlet extends HttpServlet { la servlet hérite de la classe HttpServlet
ces infos /**
étaient dans * Handles the HTTP <code>GET</code> method.
un fichier de * @param request servlet request
configuration: * @param response servlet response
web.xml * @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
redéfinition de la méthode doGet protected void doGet(HttpServletRequest request, HttpServletResponse response)
traitant les requêtes HTTP GET. throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet HelloWorldServlet</title>");
out.println("</head>"); construction de la réponse à la requête en
out.println("<body>"); utilisant l'objet PrintWriter fournit par
out.println("<h1>Hello World!!</h1>"); le paramètre HttpServletResponse.
out.println("<h2>Reponse envoyée le " + new Date() + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
} © Philippe GENOUD UGA Février 2020 14
Invoquer la servlet
http://localhost:8084/ServletsDemos/HelloWorld
HelloWorldServlet
serveur Web sous classe de HtppServlet
requête GET
doGet(…)
service()
réponse
conteneur de servlets
requête HTPP
réponse
2 Création d'un objet HttpServletResponse
permettra de construire et renvoyer une réponse au client
...
javax.Servlet.http
HttpServletResponse
<<interface>> HttpServletRequest <<interface>> HttpServletResponse
Contrôle de la réponse +getHeader(name:String):String
+getSession():HttpSession
+addCookie(c: Cookie):void
+addHeader(name, value : String):void
Données
Cookies
Status
...
Object
Pour envoyer des données sous forme de Pour envoyer des données sous forme binaire
chaînes de caractères
Writer OutputStream
PrintWriter out = resp.getWriter(); java.io ServletOutputStream out
= resp.getOutputStream();
PrintWriter ServletOutputStream
paramètres de la requête
formulaire HTML
http://localhost:8084/ServletsDemos/HelloWorld2?nom=Joe+Moose&nb=5 conteneur de servlets
requête GET/POST
nom "Joe Moose" Objet HttpServletRequest tableau associatif
nb (Map<String,String>) pour les paramètres
"5"
réponse
Objet HttpServletResponse
service(req,rep)
interrogation de l'objet utilisation de l'objet
HttpServletRequest pour HttpServletResponse
récupérer les paramètres de la pour construire et envoyer
doXXX(req,rep) la réponse au client qui a
requête
émis la requête
Appeler destroy()
3! = 120
5! = 120
<<interface>> RequestDispatcher
+ forward(servletRequest req, ServletResponse rep) : void
+ include(servletRequest req, ServletResponse rep) : void
doit commencer par un '/' et est interprété comme relatif au contexte de l'application
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import …..
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
// inclusion de l'en tête
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/includes/header.html");
dispatcher.include(request, response);
// contenu généré par la servlet
for (int i = 0; i < 5 ; i++) {
out.println("<h3>Hello Include</h3>");
}
// inclusion du pied de page
getServletContext().getRequestDispatcher("/includes/footer.html").include(request, response);
} finally {
out.close();
}
}
}
footer.html
<footer>
<p class="auteur"><small>© Philippe Genoud</small></p>
</footer>
</body>
</html>
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int noServlet = Integer.parseInt(request.getParameter("no"));
if (noServlet == 1) {
getServletContext().getRequestDispatcher("/demoForward1").forward(request, response);
} else {
getServletContext().getRequestDispatcher("/index.html").forward(request, response);
}
}
}
servlet
Servlet1
(url pattern
http://localhost:8080/ExemplesCours/demoForward?no=1&nom=TOTO
servlet /demoForward1)
HelloForward
http://localhost:8084/ExemplesCours/demoForward?no=2
index.html
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) servlet
throws ServletException, IOException { Servlet1
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try { (url pattern
out.println("<html>"); http://localhost:8080/ExemplesCours/demoForward?no=1&nom=TOTO /demoForward1)
servlet
out.println("<head>"); HelloForward
out.println("<title>Exemple Forward</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello " + request.getParameter("nom") + "</h1>");
out.println("<h3>Réponse produite par Servlet 1</h3>");
out.println("</body>");
out.println("</html>");
} finally {
paramètres de request sont ceux de la
}
out.close(); requête originale
}
}
@Override
http://localhost:8080/ExemplesCours/demoForward?no=1&nom=TOTO servlet protected void doGet(HttpServletRequest request, HttpServletResponse response)
Servlet2 throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
servlet out.println("<html>");
HelloForwardBis out.println("<head>");
(url pattern
/demoForward2) out.println("<title>Exemple Forward</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello " + request.getParameter("nom") + "</h1>");
out.println("<h3>Réponse produite par Servlet 2</h3>");
Les paramètres sont des String String origine = (String) request.getAttribute("demandeur");
Les attributs peuvent être des objets quelconques out.println("<h3>à la demande " + origine + "</h3>");
out.println("</body>");
out.println("</html>");
public void setAttribute(String name, Object value) } finally {
out.close();
}
public Object getAttribute(String name) }
}
traitement de l'exception et
envoi d'une réponse au client
appels 8
Container:
1 Tomcat
7
TestExceptionServlet:
service()
2 6
TestExceptionServlet:
doGet()
3 TestExceptionServlet: 5 remonté de l'exception jusqu'à trouver
processRequest() un bloc catch l'attrapant
4
objet NumberFormatException
lancé par Integer.parseInt()
…
API de login
java.util.log, Log4J, SL4J, JULI …
l'onglet affiche l'ensemble du fichier journal qui est stocké sur le disque dur et n'est pas effacé entre les différentes exécutions du serveur
Pour voir la dernière erreur bien se placer au bas du fichier log et vérifier les dates et heures
sur une machine de développement avec ou non intégration à un IDE (Netbeans, Eclispe….)
/var/lib/tomcat{X}/logs
Windows
Sous Windows dans
repertoire NetBeans
situé dans le profil
utilisateur
Servlet
objet exception
lancé par la servlet génère une
réponse HTML
intercepté (catch) et
traité par le conteneur
(Tomcat) qui a fait
l'appel à doGet
<!DOCTYPE html>
<html>
<head>
La logique de traitement de l'exception spécifique au conteneur de
<title>Apache Tomcat/8.5.11 –
...
Rapport d''erreur</title> servlets, selon le conteneur (Tomcat, Jetty, GlassFish, WildFly…)
</html>
une réponse HTML d'erreur différente peut être obtenue.
possibilité d'accéder à un certain nombre d'informations pouvant être utiles et positionnées comme
attributs de la requête par le conteneur.
localhost:8080/TestServletException/mauvaiseURI
classe javax.servlet.http.Cookie
requête HTTP
Cookie
+Cookie(String name, String value)
+getName():String récupérer un cookie
+getMaxAge():int
+getValue():String
via l'objet HttpServletRequest
+getDomain():String Cookie[] getCookies()
...
+setValue(String v):void
+setMaxAge(int expiry):void
+setdomain(String domain):void
...
réponse HTTP
une fois le cookie créé, son nom ne peut plus être
changé (pas de méthode setName())
déposer un cookie
via l'objet HttpServletResponse
void addCookie(Cookie c)
Sauvegarde d’objets :
Association clé ⇔ instance : void setAttribute(String key, Object value)
exemple :
HttpSession session = request.getSession();
String name= "Joe Moose";
session.setAttribute("nom", name);
session.setAttribute("couleur", new Color(222,114,14));
Extraction d’objets :
récupération d'un objet à partir de sa clé : Object getAttribute(String key)
exemple :
HttpSession session = request.getSession();
String theName = (String) session.getAttribute("nom");
Color c = (Color) session.getAttribute("couleur");
Introduits à partir de la version 2.3 de l'API des servlets les filtres permettent
d'intercepter les requêtes et réponses des servlets
• authentificiation
• redirection
• modification des entêtes
• cryptage des données
•…
request request
Servlet
response response
...
}
© Philippe GENOUD UGA Février 2020 59
Filtres
MaServlet
response
<!– Definition des filtres présents -->
<filter> FiltreAiguilleur
<filter-name>FiltreAiguilleur</filter-name> UnPageJSP
<filter-class>UnFiltre</filter-class>
</filter>
if (condition) {
RequestDispatcher rd = request.getRequestDispatcher("/UnePageJSP.jsp");
rd.dispatch(request,respeonse);
}
else
chain.doFilter (request, response);
}
...
}
request request
Servlet1
request
forward Servlet2
response
response response
Filtre1
Filtre appliqué :
<filter-class>filters.Filter2</filter-class>
</filter>
- au requêtes issues du client
- au requêtes issues d'un forward <!– association des filtres à des servlets ou des urls -->
<filter-mapping>
<filter-name>Filtre1</filter-name>
<url-pattern>/Servlet1</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<dispatcher>FORWARD</dispatcher>
<filter-mapping>
<filter-name>Filtre2</filter-name>
<url-pattern>/Servlet2</url-pattern>
</filter-mapping>
request request
Servlet1
request
request
forward Servlet2
response
response
response response
Filtre1 Filtre2