Master e-services 2015
JSP Standard Tag Library (JSTL) est une librairie qui étend les fonctionnalités de JSP en mettant à disposition de nouveaux tags à utiliser dans le HTML. L'objectif est de permettre d'écrire du code plus facilement et de manière plus cohérente avec le reste du HTML.
Ainsi, un développeur front-end ne sera pas trop perdu dans l'utilisation de ces balises, même si il ne connait rien à JAVA.
L'implémentation de base fourni différents types de balises regroupées dans différents espaces de nommage XML. Comprenez différents module dont on identifiera le nom dans le préfixe de la balise. Il existe ainsi les tags "core" (c), les tags "xml" (x), les tags "format" (fmt) et les tags "sql" (sql).
JSTL 1.2 offre également des facilités pour la manipulation et l'affichage des données provenant du "model". Cela va se faire par ce qui est nommé "Expression Language" (EL). Une expression est une chaine du type ${expression}
. "expression" peut simplement être le nom d'une variable du modèle ou une fonction plus aboutie fournie par EL.
Pour indiquer à notre compilateur JSP que notre page utilisera JSTL et EL, il suffit de placer cette déclaration de la taglib en haut de notre page JSP.
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
Ensuite les balises préfixées par "c" seront interprétées par le compilateur et généreront du code java particulier.
La taglib "core" fourni un ensemble de tag permettant de gérer de l'affichage et affectation de variable, des boucles, des conditions, de la création d'url en fonction du contexte, des redirections ...
Tag | Description |
---|---|
<c:out > | Identique à <%= ... >, mais pour les expressions. |
<c:set > | Affecte le résultat d'une expression à un 'scope' |
<c:remove > | Efface une variable (Depuis un scope, si défini). |
<c:catch> | Gère les exception 'Throwable' qui surviennent dans le contenu du tag. |
<c:if> | Tag permettant de traiter une condition (if). |
<c:choose> | Tag permettant de gérer un ensemble de conditions exclusives (identique à switch/break). |
<c:when> | Sous-tag de 'choose' pour traiter une condition. |
<c:otherwise > | Sous-tag de 'choose' pour traiter tout autre cas que ceux indiquer dans 'when'. |
<c:import> | Affecte le contenu d'une page pointée par une URL à une variable. |
<c:forEach > | Permet de faire une boucle sur tout ce qui est 'Iterable' ou tableaux. |
<c:forTokens> | Boucle sur une chaine possédant un séparateur défini (exemple 'chaine1,chaine2,chaine3'). |
<c:redirect > | Redirige l'utilisateur vers une nouvelle URL. |
<c:url> | Crée une URL absolue en fonction du contexte de la servlet, avec des paramètres ou non. |
<c:param> | Sous-tag de 'URL' permettant d'ajouter (ou remplacer) un paramètre à la Query String. |
Les autres taglibs ne devraient pas vous être utile dans le cadre de ce cours.
Tous les objets affectés au modèle sont exposés de manière immédiate par les EL.
Pour reprendre l'exemple de la liste des auteurs, si l'on a fait ceci dans notre contrôleur :
List<Author> authors = dao.listAll();
model.addAttribute("authors", authors);
Alors, il sera facile de faire une itération sur nos auteurs dans la vue avec le bout de code :
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<h1>Auteurs</h1>
<c:choose>
<c:when test="${empty authors}">
Liste des auteurs vide
</c:when>
<c:otherwise>
<ul>
<c:forEach items="${authors}" var="author">
<li>${author.firstname} ${author.lastname}</li>
</c:forEach>
</ul>
</c:otherwise>
</c:choose>
Notez qu'il n'y a pas de "else" à la balise <c:if>
. Nous pouvons par contre utiliser "choose
" et "otherwise
" comme ici.${author.firstname}
" fonctionne, il est nécessaire d'avoir un getter sur la propriété "firstname". Par convention les propriétés d'un objets sont résolue selon la norme "javabeans". Donc, il faut créer des getters sur les propriétés que vous voulez exposer dans vos vues.
De nouvelles taglib peuvent être créées afin d'enrichir les fonctionnalités offertes dans les vues.
Spring fournit une taglib "form" bien pratique pour manipuler les objets java à éditer dans des formulaires HTML.
Apprenons par l'exemple en observant ce que cela peut donner sur nos auteurs.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<h1>Author</h1>
<form:form modelAttribute="author">
<form:input type="hidden" path="id" /> <br/>
firstname : <form:input path="firstname" /> <br/>
lastname :<form:input path="lastname" /> <br/>
<input type="submit" value="Enregistrer"/>
</form:form>
Vous pouvez consulter la documentation dédiée aux vues spring et plus particulièrement la section "comment utiliser la taglib form".
Du côté de notre contrôleur il sera nécessaire de distinguer deux opérations. Une première pour traiter l'affichage du formulaire (en GET) et une deuxième pour gérer l'enregistrement des données du formulaire (en POST) et mettre à jour les données dans la base. Quelques annotations nous serons utiles pour distinguer les deux opérations branchées sur la même URL. Une annotation @PathVariable
nous permettra d'extraire facilement une variable depuis l'url. L'annotation @ModelAttribute
permettra de créer un objet automatiquement à partir des données du formulaire envoyé en POST. Toutefois, pour que cela fonctionne vous devez exposer des "setter" sur les propriétés de votre model selon la convention "javabeans".
Le code du contrôleur ressemblera au final à cela :
@RequestMapping(value="/author/{id}.html", method=RequestMethod.GET)
public String edit( Model model, @PathVariable("id") int id ) {
Author author = dao.find(id);
model.addAttribute("author", author);
return "author/edit";
}
@RequestMapping(value="/author/{id}.html", method=RequestMethod.POST)
public String save( Model model, @ModelAttribute Author author ) {
dao.update(author);
model.addAttribute("author", author);
return "author/edit";
}
Dans notre contrôleur, nous définissons un ensemble d'opération et nous les branchons sur des URL.
Spring est capable de gérer les appels à ces opérations en fournissant automatiquement en paramètre les objets nécessaires.
Ainsi, si pour des besoins particuliers vous avez besoin d'un paramètre fourni en GET ou en POST, vous pourriez ajouter un paramètre annoté @RequestParam
@RequestMapping(value="/authors.html", method=RequestMethod.GET)
public String listByName( Model model, @RequestParam("nameLike") String name ) {
List<Author> authors = dao.findAuthorsLikeName( name );
model.addAttribute("authors", authors);
return "authors";
}
Cette opération serait accessible via l'url "http://localhost:8080/tp1/authors.html?nameLike=Cat" et permettrait de lister les auteurs dont le nom commence par "Cat". Le paramètre "nameLike" est ici passé dans la QueryString de la requête, en GET. Cela aurait pu être dans le corps d'une requête POST.
Si vous avez besoin d'accéder à l'objet HttpServletRequest (ou Response) il vous suffit de l'ajouter à la liste des paramètres de votre opération et spring vous le passera lors de l'invocation de la méthode.
Il n'est pas recommandable de créer ce type de dépendance vers l'API servlet car votre contrôleur pourrait être utilisé dans un tout autre contexte que celui d'une application web. Toutefois, il est parfois nécessaire de le faire et spring vous en offre la possibilité.
Consulter cette page pour voir la liste des types de paramètres que spring peut vous fournir !
★
Rendez-vous sur cette page et estimons ensemble, en "Story Point", chacune des fonctionnalités.
https://www.pointingpoker.com/xxxxxx remplacer les xxxx par le numéro de session fourni durant le TD.