JSF 2 : les principales nouveautés

La JSR 314 spécifiant la version 2 de Java Server Faces (JSF), le framework de développement d'IHM web fourni par JEE, a été livrée en version finale le 12 mai dernier (cf. http://jcp.org/en/jsr/detail?id=314).

Cette version 2 de JSF cherche à améliorer la productivité des développements, l'intégration d'AJAX et la ré-utilisation. Nous allons parcourir ici les principales nouveautés.

Les principales nouveautés

L'intégration native de fonctionnalités AJAX

Avec JSF 1, il fallait utiliser une autre librairie (RichFaces, IceFaces...) pour faire de l'AJAX, conduisant à une complexification de la configuration (ajout d'un filtre, de dépendances) et obligeant le développeur à maîtriser plusieurs frameworks. JSF2 dispose désormais d'un tag nommé "f:ajax" offrant la possibilité de mettre à jour une partie de la page lors d'évènements. Pour fonctionner, on doit inclure dans la page une librairie JavaScript fournie par JSF2. Par exemple, on veut ici mettre à jour la div panierDiv lors d'un clic sur le lien  addPronostic :

<h:outputScript name="jsf.js" library="javax.faces" target="body"></h> <h:form> <h:commandLink id="addPronostic" value="#{match.cote1}" action="#{mesPronosBean.addPronoCote1}"> <f :ajax render=":panierDiv" /> </h:commandLink> </h:form> <div id="panierDiv">...</div> De plus, JSF2 va traiter côté serveur uniquement la partie de la page nécessaire. C'est la notion de partial processing. Cela améliore grandement les performances car auparavant, toute la page était traitée.

Le remplacement de configuration XML par des annotations

JSF 1 centralisait la déclaration des managed bean, de la navigation et bien d'autres choses dans le fichier faces-config.xml. On peut désormais déclarer des managed beans avec des annotations (des frameworks comme Spring le permettaient déjà), économisant des dizaines de lignes de configuration dans le fichier faces-config.xml : @ManagedBean() @SessionScoped public class UserBean {...}

JSF 2 fournit également l'injection de dépendances de managed beans.

De même, les pages de destination peuvent être déclarées directement dans la réponse d'une méthode d'action : <h:commandButton id="loginButton" action="**#{monBean.doAction}**"/> Si la méthode "doAction" renvoie "hello", alors JSF interprétera  l'action « hello » comme la page hello.xhtml , et la cherchera dans les répertoires disponibles. S'il existe plusieurs pages du même nom, on pourra évidemment déclarer la navigation dans le fichier faces-config.xml. Cependant, JSF laisse la possibilité d'utiliser la déclaration XMLdans tous les cas. Cela peut être parfois plus pratique, par exemple pour centraliser les informations dans un projet assez complexe.

La simplification de la création de composant :

L'utilisation de composants est le grand avantage de JSF. Il doit permettre la ré-utilisation de composants développés en entreprise, ainsi que de composants offerts par des librairies du marché (open-sources ou non). Malheureusement, développer des composants avec JSF 1 était complexe et nécessitait l'écriture de nombreuses classes Java implémentant différentes interfaces, et de fichiers de configuration (cf. http://blogs.steeplesoft.com/jsf-component-writing-check-list/). Plusieurs initiatives ont vu le jour pour simplifier ce développement, comme le Component Development Kit de RichFaces. Le framework Facelets permettait également de simplifier un peu ce développement. JSF 2 a intégré Facelets et permet de créer des composants de manière déclarative dans un seul fichier XHTML, ne nécessitant plus ni l'écriture d'une classe Java (sauf si besoin est), ni de XML de description. De plus, on peut désormais créer des composants composites, qui peuvent être réutilisés dans d'autres composants.

Par exemple, on va définir un composant affichant le nom et le prénom d'une personne :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:composite="http://java.sun.com/jsf/composite"> <!-- interface --> <**composite:interface**> <**composite:attribute** name="user"/> </composite:interface> <!-- implémentation --> <**composite:implementation**> <h:form> <h:outputText value="Prénom : #{**cc.attrs.user.forname**} Nom : #{**cc.attrs.user.name**}``"/> </h:form> </composite:implementation> </html>

Points-clés :

  • composite:interface, composite:attribute et composite:implementation structurent la déclaration du composant.
  • #{cc.attrs.user} est la formulation JSF 2 pour récupérer le paramètre «monimage» déclaré par la vue ou le composant qui utilisera ce composant. Cc.attrs sont des mots réservés en JSF 2.
  • Le nom du composant est directement déduit du nom du fichier XHTML, et son namespace est construit avec http://java.sun.com/jsf/composite suivi du chemin où se trouve le composant, depuis la racine du site. Il est possible de modifier le préfixe "java.sun.com/jsf/composite", mais on complexifiera le code.

Pour l'utiliser dans une page, si le fichier précédent se nomme par exemple « usercomp.xhtml » et se trouve dans le répertoire « components/util », on l'utilisera comme suit : <html xmlns="http://www.w3.org/1999/xhtml" xmlns:util="http://java.sun.com/jsf/composite/components/util"> <util:usercomp user="#{sessionBean.user}"/> </html>

Ce composant est bien évidemment simpliste, et dès que l'on a du code plus complexe, on devra utliser une classe Java, etc.

Standardiser et simplifier le développement de composants est un point crucial pour l'avenir de JSF. Ces nouveautés vont donc dans la bonne direction. Il faudra encore que les outils de développements suivent pour que cela soit le plus efficace possible : intégration aux IDE, plug-ins et archetypes Maven...

Une gestion des ressources plus puissante

On peut désormais placer les ressources (images, CSS, JavaScript) dans un répertoire nommé « resources » en dehors du répertoire WEB-INF, ou même les inclure dans un JAR à déposer dans ce même répertoire. Cela permet un meilleur versioning des ressources. On accédera par exemple à une image appelée "monimage.jpg" et à la racine du répertoire resources de la façon suivante :

#{resource['images:monimage.jpg']}

Templating

En intégrant Facelets à la la spécification , JSF 2 intègre désormais nativement des fonctions de templating de vue dans JSF. Cela évite encore d'avoir à inclure un framework tiers.

Bilan

JSF2 n'apporte pas de nouveauté révolutionnaire, et pourrait ressembler plus à une amélioration de JSF 1.2 qu'à une nouvelle version majeure. Il améliore tout de même la productivité et la ré-utilisation en simplifiant les développements, et ce de façon non négligeable. Désormais, les limitations de JSF viendront sans doute de ses principes fondamentaux :

  • la nécessité pour JSF de gérer une représentation de la vue entière côté serveur, qui induit une charge de travail importante côté serveur, des temps de réponses plus longs et empêche de réaliser des vraies architectures stateless
  • son orientation navigation web classique, entre différentes pages, alors que les applications RIA tendent plutôt vers des applications à une seule page, manipulant des petits fragments du DOM via JavaScript et n'ayant pas besoin d'une vue globale de la page côté serveur
  • le principe de génération de HTML avec des tags, qui nécessite à la fois de savoir développer en HTML + CSS et de connaître les composants JSF. Sur ce point JSF peut souffrir à la fois de la concurrence de frameworks comme Wicket ou JavaScript classiques, qui sont non intrusifs dans le HTML et peuvent être mieux adaptés pour un bon développeur web, et de celle de GWT, qui permet de ne développer qu'en Java et être mieux adapté pour un développeur Java (cf. "faut-il-maitriser-son-code-html").

L'amélioration de la productivité du développement, grâce à l'utilisation de composants et aux outils, notamment le support par les IDE, sera la clef pour la réussite de JSF, si les fondamentaux du framework ne changent pas.

P.S: on remarquera l'absence des tests dans cet article. L'absence de nouveautés dans JSF 2 concernant ce point ne signifie pas pour autant qu'il est impossible de tester. Cela pourra faire l'objet d'un autre article.

Pour aller plus loin

Commencer à utiliser JSF

L'API et l'implémentation de référence de JSF 2 sont déjà disponibles ici : http://download.java.net/maven/2/com/sun/faces/ et presque finalisées. Bien que JSF 2 ne fera partie que de la version 6 de JEE, il tourne sur la plupart des serveurs JEE 5 du marché (Tomcat, JBoss, Glassfish...). Pensez- simplement à mettre à jour les librairies JSF fournies par le serveur sur JBoss et Glassfish...

JSF 2 au Paris JUG

Mon collègue Damien Gouyette et moi-même présenterons une session du Paris Java User Group consacrée à JSF 2 le 15 octobre prochain.

Pensez à réserver vos places!

Liens externes