Présentation :

Lien vers le powerpoint de notre présentation

Fusion de Struts 1 et de WebWork, Struts 2 constitue le nouveau framework de persistance de la communauté Open Source Apache. Son fonctionnement se veut ouvert aux technologies Web et s’intègre parfaitement aux applications J2EE respectant nottamment Spring. Présent depuis peu sur le marché, Struts 2 se veut être la nouvelle référence de développement Web.
Struts 2 intègre la nouvelle architecture MVC2. Il se trouve être plus flexible et propose plus de fonctionnalités que la version 1 tout en diminuant le couplage entre les objets.

Comparaison entre Struts 1 et 2 :

Caractéristiques Struts 1 Struts 2
Classe Action Struts requiert qu'une classe Action étende une classe abstraite basique. Programmer avec des classes abstraites au lieu d'interfaces est un problème courant avec Struts 1. Un objet Action de Struts 2 peut implémenter l'interface Action, avec également d'autre interfaces qui permettent d'utiliser des services personnalisés et optionnels. Struts 2 fournit une classe basique ActionSupport pour implémenter des interfaces couramment utilisées. En revanche, une interface Action n'est pas requise. N'importe quel objet POJO avec une signature peut être utilisé comme un objet Action de Struts 2.
Dépendance avec la Servlet L'objet Action de Struts 1 possède des dépendances avec l'API Servlet car HttpServletRequest et HttpServeltResponse sont passés dans la méthode "execute" quand l'objet Action est appelé. L'objet Action de Struts 2 n'est pas couplé à un conteneur. La plupart du temps les contextes de la Servlet sont représentés comme une simple "Map", permettant aux objets Actions d'être testés à part. Struts 2 peut néanmoins toujours utiliser les HttpServletRequest et HttpServletResponse si besoin. Néanmoins, d'autres éléments d'architecture réduisent, voir éliminent, le besoin de les utiliser directement.
Modèle de Threading Les objets Action de Struts 1 sont des singletons et doivent être "thread-safe" car ils seront la seule instance de la classe à gérer toutes les requetes pour cet objet Action. La stratégie du singleton place des restrictions sur ce qui peut être fait avec les objets Action de Struts 1 et requiert plus d'attention durant le développement. Les objets Action de Struts 2 sont instanciés à chaque requête. Il n'y a donc pas de problème de "thread-safe".
Testabilité Un obstacle majeur pour tester les objets Action de Struts 1 est que la méthode "execute" expose l'API servlet. Une extension tierce, Struts TestCase, offre un ensemble d'objets au comportement similaire pour Struts 1. Les objets Action de Struts 2 peuvent être testés en instanciant l'objet, fixant les propriétés et invoquant les méthodes.

Rétrospection :

Suite à notre expérience de développement du projet de gestion de contacts, nous reviendrons sur les points suivants :

  • L'installation du framework
  • - Son déploiement
  • - La création des classes "Action*"
  • - La création des JSP
  • - Le mapping de l'ensemble
  • Un approfondissement sur des aspects particuliers du développement
  • - Les validateurs de formulaires
  • - Les retours personnalisés
  • - L'encodage en UTF-8

L'installation du framework

Son déploiement

Pour une installation de base et rapide, Apache a mis à notre disposition des projets pré-installés au format WAR. Celui qui nous intéresse sera le fichier "struts2-blank-2.x.x.war" que vous pourrez trouver à l'adresse "/apps" de l'archive. Si vous travaillez sous Eclipse, vous pouvez l'importer via la fenêtre d'import (File -> Import) en choisissant "WAR File" (Web -> WAR File). Pour tout autre éditeur, je vous laisse chercher par vous même, le format WAR étant un standard.

import1 import2

Par la suite, si vous êtes amenés à travailler fréquemment avec Struts, je vous conseille de déployer une fois pour toutes le framework tel qu'il vous convient, configuré pour votre entreprise par exemple puis de vous en faire votre propre WAR; fichier que vous redéploierez ainsi instantannément.

La création des classes "Action*"

Une fois le framework déployé, la suite concerne la programmation de l'application. On commencera par les classes "Action*". C'est une des nouveautés de Struts 2, le développeur n'est plus contraint d'étendre une classe donnée et libère au maximum des objets du J2EE pour faciliter les tests unitaires. Ca laisse notamment la possibilité de créer une classe mère pour ses controleurs, dans laquelle vous pourrez écrire tout leur code commun (factorisation) et qui implémentera l'interface "ActionSupport". Vous vous trouverez alors avec une super-classe compatible avec le framework et qui peut vous libérer de certaines contraintes du framework (l'action par défaut par exemple).

Un petit point pratique, toujours pour ceux qui développent sous Eclipse, je vous conseille de changer le chemin du fichier source pour préciser celui de Java. Vous aurez alors l'éditeur Java pour travailler avec vos classes. Vous pouvez le faire via les propriétés de votre projet.

sources

La création des JSP

Struts2 a conservé le système de balises propres du type "<s:></s:>".

Pour l'utiliser dans les JSP, il suffit d'ajouter le tag suivant :

           <%@ taglib prefix="s" uri="/struts-tags" %>.

NB : L'utilisation de ces balises typées est obligatoire pour la réalisation d'un formulaire.

Voici l'allure d'un formulaire générique :

La balise <s:actionerror> permet d'afficher une erreur survenue lors du traitement du formulaire. Son utilisation nécessite d'avoir correctement paramétré le X-validation.xml(validateur de formulaire) et le struts.xml (Mapping des Action).

Le mapping

Struts2 n'utilise plus de servlet mais des "Action*" reliées à une servlet globale. Un mapping doit être réalisé dans struts.xml afin de définir les traitements pour action, ainsi que leurs retours dans les différents cas (succès, échec,...). Les actions sont précisées par des classes et, éventuellement, par un nom de méthode ce qui permet d'avoir plus action dans une même classe ; pour un CRUDE par exemple.

Voici un exemple de fichier de mapping Struts2 "struts.xml" :

Un approfondissement sur des aspects particuliers du développement

Les validateurs de formulaire

La validation des formulaires peut être automatisée avec Struts 2 et évite ainsi les contrôles de champs pouvant être faits en J2EE. Cette validation se fait par l'intermédiaire d'un fichier xml nommé X-validation.xml, X étant le nom de la classe Controller associée.

L'attribut name de <field> désigne le nom du champ du formulaire. Ce dernier doit coincider avec le nom de membre de la classe de formulaire ainsi que le nom du champ demandé dans la JSP par la librairie de tags. Ces champs peuvent être validés à la fois par leur remplissage mais aussi par leur format. Pour cela, il existe des validateurs pré-faits pour les principaux types de données (comme on peut le voir dans cet exemple). Sachez qu'il existe des validateurs plus souples acceptants des regexps. Si par hasard, ces validateurs ne vous conviendraient pas, sachez que vous pouvez créer les vôtres via des interfaces Java.
Sachez aussi qu'il est possible dans ce fichier de programmer des dépendances entre champs. Par exemple, si un champ est rempli, tel champ doit être aussi rempli. Si un champ possède une valeur précise, tel autre champ doit vérifier telles conditions. Un système très complet existe mais n'a pas été montré dans cet exemple pour ne pas le surcharger.

Les retours personnalisés

On a pu voir dans l'écriture des JSP que les méthodes d'action retournent des String. Dans les cas précédents, les valeurs de retour étaient les constantes success ou error. Ces constantes ne sont rien d'autres que les chaînes "sucess" et "error". Vous avez pu choisir ces mots dans le fichier de mapping de struts dans l'attribut "result" des noeuds "result" (ainsi que la valeur "input", qui correspond à la non saisie d'un champ de formulaire obligatoire). Mais sachez que vous pouvez créer vos propres valeurs de retour.

Prenons l'exemple du login. Nous allons créer un code de retour dans le cas où l'utilisateur ne serait pas loggué. Ou mieux le placer que dans notre classe mère de tous les controlleurs de nos applications : celle qui étend "ActionSupport". Pour cela, on rajoute une constante protected final String NOTLOGGED = "notlogged";. Dans les controllers, il suffira de tester si votre utilisateur est loggué, et dans le cas contraire, retourner NOTLOGGED. Maintenant, nous pouvons profiter de cette valeur de retour pour rediriger vers la page de login. Il suffit pour cela de rajouter dans la descrption de l'action, le noeud suivant : <result name="notlogged">/contacts/Login.jsp</result>. Et voilà, en plus de vos retours habituels de succès et d'erreur, vous gérez maintenant le cas d'un utilisateur non loggué.

L'encodage en UTF-8

Un point intéressant qui mérite d'être soulevé est l'encodage en UTF-8. Celui-ci se configure à plusieurs endroits. Commençons par le plus simple.
Tout d'abord, pensez à vérifier que votre projet est bien en UTF-8 pour Eclipse. Ensuite, n'oubliez pas de préciser le charset dans les JSP pour les tags. Cela se fait via "<%@page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>".

Un point plus délicat quand à lui, est le traitement des données en entrée et sortie ; comme celles des formulaires. Il va être nécessaire de faire comprendre que ce qui rentre est sort doit être interprété dans le bon charset. Pour cela, on va utiliser un filtre qui interceptera toutes les requêtes, configurera le Servlet puis passera la main à Struts 2. Pour cela, rajouter le servlet de filtre. Une fois fait, modifier votre fichier web.xml pour rajouter le filtre. Je vous laisse le remplacer par celui-ci, en prenant soin de bien cibler le servlet fraichement rajouté.
On notera que cette solution n'est pas intrusive. Elle ne modifie pas l'architecture de votre projet et ne change en rien votre configuration de Struts 2. De plus, elle s'adapte pour tous les charsets.

Critiques :

En conclusion, Struts 2 est un framework très complet et très puissant. Il possède bien toutes les attentes que l'on peut avoir pour un framework MVC. Mais cet avantage soulève des problèmes de lourdeur et de difficultés de prises en main. A tel point qu'il faudra s'armer de patience pour entreprendre son premier CRUDE, opération qui se fera non sans mal et avec quelques heures passées dans la documentation.

De ce côté, la documentation est complète mais un peu brouillonne pour un projet Apache. En effet, le format wiki et le manque de rigueur dans la mise en page peut rendre l'accès à l'information moins aisé. Qu'à cela ne tienne, de nombreux sites seront là pour vous épauler dans votre développement ; ce qui prouve bien la domination de Struts 2 dans son domaine.

Cas d'étude

Lien vers le .war de notre projet

Bibliographie :