Une servlet est un objet Java qui étend l'interface "Servlet" ou "HTTPServlet".
Cette interface définit 2 méthodes qui sont appelées lorsque le code est chargé/arrêté par le serveur web qui "expose" ces servlets à travers une URL.
Ces méthodes "init" et "destroy" permettent d'initialiser un certain nombre d'éléments au lancement de la servlet ou de nettoyer le contexte lors de leur arrêt.
Le serveur web va interpréter une partie de la requête HTTP envoyée par le navigateur de l'internaute et appeler une méthode de la servlet qui est responsable du traitement de cette requête.
C'est la méthode "service" qui est appelée.
Cette méthode possède une implémentation par défaut dans la classe abstraite "HTTPServlet". Elle appelle la méthode doGet, doPost, doHead, doOptions, doPut, doTrace en fonction du type de requête HTTP reçu par le serveur.
Les deux paramètres de ces opérations sont "HTTPServletRequest" et "HTTPServletResponse".
Ils permettent respectivement d'analyser la requête émise par l'internaute, et de lui répondre.
La vidéo suivante présente le principe de fonctionnement des servlets.
Transparents présentés dans la vidéo
Utiliser Firebug
Firebug est un plugin très pratique pour Firefox et vous devriez l'installer. Il permet de visualiser la structure HTML d'une page, de debugger du javascript, d'analyser les échanges réseaux, les cookies et bien d'autres choses.
Nous allons réaliser une première servlet très simple en essayant de "tout faire à la main".
Depuis l'écriture dans un éditeur de texte basique, la compilation et le lancement dans un serveur web de type "tomcat 8" allégé.
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/bonjour")
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("nom");
if ( name == null || name.isEmpty() ) name = "tout le monde";
Writer out = resp.getWriter();
out.write("<p>Bonjour <b>" + name + "</b> !</p>");
}
}
Pour compiler ce code il faudra avoir le répertoire $JAVA_HOME/bin dans votre PATH (voir installation des outils). Il faut en effet pouvoir exécuter le compilateur "javac" facilement.
Il sera également nécessaire de mettre la librairie "servlet-api.jar" dans votre CLASSPATH. Cette librairie contient toutes les interfaces et classes abstraites que nous implémentons en faisant des servlets.
Elle est fournie (entre autre) avec Tomcat, dans le répertoire "lib".
javac -cp (chemin vers tomcat)/lib/servlet-api.jar MyServlet.java
Cela a du créer un fichier "MyServlet.class" qui est notre servlet, branchée sur l'url "/bonjour" du contexte "/tp1".
Lançons notre serveur web.
Rendez-vous dans le répertoire tomcat8/bin et exécutez ./catalina.sh run
Après quelques secondes votre serveur est lancé et accessible sur "http://localhost:8080"
Utilisez votre navigateur, puis la commande curl pour interroger votre servlet
curl -v http://localhost:8080/tp1/bonjour
A. Essayez de passer votre nom en paramètre d'abord en GET.
B. Modifier votre servlet pour n'accepter que le paramètre en POST. Tester à l'aide d'un formulaire écrit dans un fichier html sauvegardé n'importe où ... puis avec curl
C. Modifiez votre servlet pour afficher le formulaire sur le GET et pour afficher "bonjour xxx" lors d'un POST.
Le screencast suivant illustre, par l'exemple, le développement d'une servlet.
Code présenté dans le screencast
JSP est un équivalent java des fichiers ASP ou PHP. C'est une manière de mettre du code Java, exécuté coté serveur, dans une page HTML. Le JSP n'est pas interprété, il est en fait traduit en Java puis compilé (généralement au premier appel de la page), et ensuite exécuté. C'est le résultat de cette exécution qui donne le code HTML renvoyé au navigateur.
Nous utiliserons "jasper" comme implémentation du moteur de JSP, il est fourni avec Tomcat.
Afin de distinguer le code HTML ou JavaScript à donner au navigateur et le code Java à exécuter sur le serveur, nous utilisons les balises "<%" et "%>" pour délimiter le code Java.
Une balise particulière permet de définir des propriétés sur le type de réponse HTTP, l'encodage de la page, ou encore les imports Java nécessaires pour la compilation de la page. Toutes ces directives se retrouvent entre les balises "<%@" et "%>".
Enfin, il est très courant de vouloir afficher le contenu d'une variable dans le code HTML qui sera renvoyé au navigateur. Cela peut se faire en faisant un <% out.print( maVariable ); %>
mais un tag a été défini pour réduire l'écriture à <%= maVariable %>
qui fait exactement la même chose.
Comme nous sommes de bon développeurs consciencieux, nous n'hésiterons également pas à utiliser le tag permettant de mettre des commentaires dans nos JSP : <%-- mon super commentaire qui ne sera pas compilé ou envoyé au navigateur --%>
Il faut bien comprendre que la JSP va être traduite en code Java. Plus précisément en une classe qui hérite de Servlet dont il sera exécuté la méthode "service". Dans certains cas il peut être utile de vouloir introduire des attributs ou des méthodes à cette classe générée et compilée.
Cela peut se faire avec le tag <%! private double montant; %>
Depuis votre code Java, vous pouvez utiliser les variables suivantes :
Pour rendre l'écriture de nos JSP un peu plus modulaire il est possible d'inclure du code JSP à partir d'une autre page JSP. Cela se fera via la directive <%@ include file="ma_page.jsp" %> Si vous donnez un chemin absolu au fichier (exemple /layout/header.jsp), la racine considérée est celle du contexte web du serveur. Il est ainsi plus facile d'être indépendant de l'environnement de déploiement.
Il est également possible de traiter le début d'une requête avec une servlet et de déléguer l'affichage à une page JSP. Dans la servlet nous utiliserons alors req.getRequestDispatcher("/ma/page.jsp").forward(req, resp)
Pour passer des objets de la servlet à la JSP, il sera possible d'utiliser l'objet request et ses méthodes setAttribute / getAttribute.
Il est alors possible de mettre en oeuvre un pattern MVC dont la partie "View" est traitée en JSP et la partie "Controller" est traitée par la servlet. Le modèle pourra quant à lui être cloisonné dans des classes d'accès au données (DAO) injectées dans le contrôleur.
La vidéo suivante présente le principe de fonctionnement des JSP.
Transparents présentés dans la vidéo.
Reprenez le contenu de ce fichier et mettez le dans un fichier "test.jsp", dans votre répertoire (tomcat) webapps/tp1.
Accédez à la page http://localhost:8080/tp1/test.jsp
Le premier accès est un peu plus long car "jasper", le moteur jsp, transforme votre source jsp en source java, puis le compile et enfin il exécute ce code.
Pour les appels suivants, le code est simplement exécuté comme n'importe quel autre servlet.
Vous pouvez d'ailleurs consulter le contenu du source Java généré dans le répertoire de travail de Tomcat :
(tomcat) work/Catalina/localhost/tp1/org/apache/jsp
Regarder le source peut aider à comprendre une erreur qui s'est glissée dans la JSP, ou à analyser une exception levée par le code exécuté.
Le screencast suivant illustre, par l'exemple, le développement d'une JSP.
Code présenté dans le screencast
Les vidéos suivantes permettent d'explorer différentes notions complémentaires associées aux servlets et ou aux JSP, notamment le protocole HTTP, la notion de session, la notion de request dispatcher, ainsi que le cycle de vie d'une servlet.
Transparents présentés dans la vidéo |
Transparents présentés dans la vidéo |
|
Transparents présentés dans la vidéo |
Transparents présentés dans la vidéo |
Nous vous proposons différents exercices qui permettront de vous familiariser par la pratique avec la programmation de servlet et de JSP.