Outils de développement informatique

JavaServer Pages (2)

kn@lri.fr

Modèle MVC

Qu'est-ce que le modèle MVC ?

C'est un design pattern qui permet de modéliser des applications « interactives » :

Ces trois aspects sont représentés par trois composants :

En quoi est-ce adapté aux applications Web ?

Une application Web typique :

Avantages du Modèle MVC ?

La séparation permet d'obtenir :

Maintenance simplifiée
Le code d'une action est centralisé à un seul endroit
Séparation des privilèges
Pas besoin que la vue ai un accès à la base de donnée par exemple
Test simplifié
Les composants peuvent être testés indépendamment

MVC avec JSP ?

Dans une application JSP typique, le modèle MVC peut être implémenté de la manière suivante :

Modèle (1)

Un annuaire

On se place dans le cadre d'une application permettant d'accéder à une annuaire. Un annuaire est juste une liste de contacts

class Contact { final private String lastname; final private String firstname; final private String phone; final private String email; public Contact(String l, String f, String p, String e) { lastname = l; firstname = f; phone = p; email = e; } public String getLastname () { return lastname; } public String getFirstname () { return firstname; } public String getPhone () { return Phone; } public String getEmail () { return email; } }

Classe Contact

Le getter pour une propriété foo est une méthode publique getFoo()

Classe ContactDB

public class ContactDB { private List<Contacts>contacts; public ContactDB() { contacts = new ArrayList<>(); } public List<Contact> getContactsByLastname (String s) { ArrayList<Contact> res = new ArrayList<>(); String u = s.toUpperCase(); for (Contact c : this.contacts) { if (c.getLastname().toUpperCase().contains(u)) { res.add(c); } } return res; } //autres méthodes ici }

Contrôleur : HttpServlet

HttpServlet

La classe HttpServlet permet d'implémenter le contrôleur. C'est vers cette classe que son compilées les pages JSP, mais dans le contrôleur, on ne va faire aucun affichage. On va calculer un résultat et le stocker pour que la vue puisse l'afficher.

On imagine le code de formulaire suivant dans une page contact.html: <form method="get" action="FindContactByNameServlet"> Nom : <input type="text" name="s"/></input><br/> <button type="submit">Rechercher</button> </form>

Nom :

Le contrôleur (1)

//Cette annotation permet de dire que le Servlet sera //associée à l'URL /APPNAME/FindContactByNameServlet @WebServlet("/FindContactByNameServlet") public class FindContactByNameServlet extends HttpServlet { //Tomcat se sert de l'ID Pour savoir qu'un servlet a été //modifié et donc que la version en cache doit être invalidée private static final long serialVersionUID = 1234L; //La méthode appelée si la requête est POST protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(request, response); } //La méthode appelée si la requête est GET protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { … } }

Le contrôleur (2)

Dans notre exemple on dit que si on est appelé en POST alors on fait la même chose qu'en GET.

Le contrôleur (3) : la méthode doGet

try { //On crée un Modèle et on le stocke dans la session ContactDB db = (ContactDB) getServletContext().getAttribute("db"); if (db == null) { db = new ContactDB(); getServletContext().setAttribute("db", db); } //Récupération du paramètre GET comme dans un JSP String s = request.getParameter("s"); ArrayList<Person> v = db.getContactsByLastname(s); request.setAttribute("contacts", v); RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/contact_list.jsp"); rd.forward(request,response); } catch (Exception e) { throw new ServletException(e); }

Le contrôleur (4)

Mécanisme général

  1. Dans un servlet S1 on effectue un traîtement, puis on appelle request.getRequestDispatcher("S2").forward (request,response)
  2. Dans S2 on effectue un traîtement, puis on appelle request.getRequestDispatcher("S3").forward (request,response)
  3. Dans Sn on effectue un traîtement, puis on appelle request.getRequestDispatcher("view.jsp").forward (request,response)

On peut ainsi enchaîner les servlets. Les Si peuvent travailler sur l'objet request ainsi que sur les headers de la réponse via l'objet response (.addCookie, addHeader, …).

Les Si ne doivent pas écrire le contenu de la réponse (i.e. pas de .getWriter() dans les servlets), sinon Si+1 renverra une erreur.

Vue

Retour sur JSP

Dans un premier temps, la vue est uniquement un fichier jsp. Elle va récupérer dans l'objet request les attributs déposés par le contrôleur pour les afficher.

La vue (1)

Dans le fichier WEB-INF/jsp/contact_list.jsp

<%@ page contentType="text/html; charset=UTF-8" %> <%@ page import="java.util.List,mypackage.Contact" %> Liste de contacts

Conclusion

On ne présente ici qu'une petite partie de JSP. Les problèmes restant :