Voici quelques comparaisons entre Stripes et Struts2 :
| Stripes | Struts2 | |
|---|---|---|
| Version | 1.5 | 2.0.12 |
| Configuration | web.xml | web.xml, struts.xml, optionnellement struts.properties entre autres |
| Noyau | Des classes implémentant ActionBean | Des classes avec une méthode execute(), implémentant optionnellement Action, ou étendant ActionSupport |
| Mécanisme de Réponse | Instance de Resolution | Identifiant String qui est lié à un result dans struts.xml ou spécifié dans une annotation |
| Technologie de Vue | JSP ou FreeMarker | JSP, FreeMarker, ou Velocity |
| Mécanisme du Patron | Intégré, avec 3 balises layout. Pour ceux qui aiment Tiles ou SiteMesh, ils peuvent être utilisés aussi. | Tiles ou SiteMesh |
| Mécanisme de Reliure | Intégré | OGNL |
| Validation | @Validate et @ValidateNestedProperties | Configuré dans un fichier XML, ou avec annotations |
| Court-circuit de Validation | Intégré, avec when=ValidationState.ALWAYS et Validation.InvokeValidateWhenErrorsExist | Configuré avec short-circuit="true" sur la balise <field-validator> |
| Validation Customisée | Méthode annotée avec @ValidationMethod | Étend soit ValidatorSupport soit FieldValidatorSupport, puis configurée dans validators.xml |
| Transfert de Data Modèle-vers-Vue | L'attribut ${actionBean} | ValueStack |
| Conversion du Type | Implémentations de TypeConverter<T> (générique) | Implémentations de ognl.TypeConverter, typiquement les extensions de StrutsTypeConverter (non générique) |
| Formatage | Implémentations de Formatter<T> (générique) | Implémentations de ognl.TypeConverter, typiquement les extensions de StrutsTypeConverter (non générique) |
| Configuration du Module Customisé | Chargé automatiquement avec l'init-param Extension.Packages | Configuré dans struts.xml |
| Intercepteurs | Implémentations d'Interceptor, ou des méthodes annotées avec @Before/@After | Implémentations d'Interceptor, avec configuration dans struts.xml |
| Localisation | Un ou plusieurs ResourceBundle pour erreurs et noms du champ, et JSTL | Mécanisme de recherche de ResourceBundle |
Les Actions
Les actions Stripes sont définies par des classes qui implémentent l'interface ActionBean, et sont automatiquement chargées si elles existent dans un des répertoires (ou dans un des sous-répertoires) spécifiés par le paramètre d'initialisation ActionResolver.Packages.
Les actions Struts2 peuvent être des classes normales qui ont une méthode public String execute(), ou des classes qui implémentent l'interface Action. Elles doivent être déclarées dans struts.xml, ou automatiquement chargées par un mécanisme inspiré par Stripes.
Gestionnaire d'Événements
Dans Stripes, les méthodes qui portent la signature public Resolution methodName() dans un ActionBean deviennent gestionnaires d'événements. Spécifier l'attribut name= dans des balises submit et event= dans des balises link avec le nom de la méthode cible, déclenchera cette méthode cible. Pour arriver à avoir plus d'un gestionnaire d'événements, et donc plus d'un bouton submit dans un formulaire, il suffit tout simplement de définir plusieurs gestionnaires d'événements, puis de spécifier leur noms dans l'attribut name= et dans leur balises submit respectives.
Struts2 est conçu de façon à avoir une seule méthode comme gestionnaire d'événements : execute(). Il est possible de spécifier plusieurs gestionnaires d'événements avec des noms arbitraires, mais il faut configurer une stratégie dans struts.xml afin de lier un URL à un nom de méthode.
Struts2 rend étonnamment difficile le fait d'avoir plus d'un bouton submit dans un formulaire. C'est faisable, mais pas aussi aisément qu'avec Stripes, comme vous pouvez le vérifier ici.
Résolutions vs. Résultats
Les gestionnaires d'événements Stripes retournent des implémentations de l'interface Resolution. Stripes fournit des implémentations intégrées afin de forwarder ou redirectionner un requête, envoyer data par flux, retourne un objet JavaScript, ou retourne un code erreur HTTP. C'est très simple d'implémenter l'interface Resolution (il n'y a qu'une méthode) pour répondre à vos besoins.
Les méthodes execute() de Struts2 retournent un String, qui est un résultat symbolique qui doit être lié à quelque chose de concret, soit dans struts.xml ou avec une annotation. On peut soutenir que le fait de retourner un résultat symbolique alourdit inutilement le travail du développeur car, du coup, on a besoin de regarder ailleurs pour comprendre ce qu'il faut faire. Tim débat ici sur ce topic avec plus de détails.
Convertisseurs de Type Customisé
Avec Stripes, écrire un convertisseur de type customisé ne nécessite que l'implémentation de l'interface TypeConverter<T>, où T est le type cible. Ensuite, vous pouvez utiliser votre convertisseur de type pour chaque propriété du type T tout simplement en plaçant ce convertisseur de type dans le répertoire spécifié par Extension.Packages. Sinon, vous ne pouvez utiliser votre convertisseur de type que pour certaines propriétés spécifiques en annotant la propriété cible avec @Validate(converter=VotreTypeConverter.class).
Avec Struts2, implémenter un convertisseur de type customisé nécessite l'implémentation de l'interface ognl.TypeConverter, normalement en étendant la classe StrutsTypeConverter. Contrairement à celle de Stripes, l'interface de Struts2 n'est pas générique, du coup votre méthode retournera un Object. Pour utiliser le convertisseur de type pour chaque propriété de type T, il faut ajouter une ligne dans xwork-conversion.properties avec la propriété, qui est le nom complet du type T, et la valeur, qui est le nom complet de la classe de votre convertisseur de type. Pour une propriété spécifique, il faut ajouter le nom de la propriété et le nom complet de la classe de votre convertisseur de type dans ActionName-conversion.properties où ActionName est le nom de la classe de l'action, et le fichier est dans le même répertoire hiérarchiquement que le package de la classe de l'action.
Technologie de Vue
Le framework Stripes prend en charge n'importe quelle technologie de vue qui, elle-même, prend en charge les librairies de balise JSP. Ça veut dire que vous pouvez utiliser JSP et FreeMarker, vu que les deux peuvent être implémentés en tant que servlet-mapping. JSP fait partie de Java EE, FreeMarker doit être configuré comme dans le guide FreeMarker with Stripes. Il est également possible d'utiliser Velocity avec Stripes en utilisant le projet outil VelocityView, mais le soutien des taglibs vous manquera. Velocity 1.5 ne prend pas en charge les taglibs JSP, ce qui a été une caractéristique voulue de la version 2.0 depuis 2006.
Avec Struts2, JSP est pris en charge tout comme Stripes. Mais Struts2 fournit des plugins afin de gérer FreeMarker et Velocity ainsi que les fonctionnalités de ces technologies de vue. Cela dit, FreeMarker (ou JSP) est plus familier que Velocity. Par exemple, le code suivant:
<s:form action="Login"> <s:textfield name="pseudo" label="Pseudo"/> <s:submit value="Soumettre"/> </s:form>
Dans Velocity l'équivalent est :
#sform ("action=Login") #stextfield ("name=pseudo" "label=Pseudo") #ssubmit ("value=Soumettre") #end
Intercepteurs
Les Intercepteurs Stripes sont de classes qui implémentent l'interface Interceptor et spécifient le(s) cycle(s) de vie à intercepter avec l'annotation @Intercepts. Stripes chargera automatiquement la classe via le mécanisme Extension.Packages. Vous pouvez toujours configurer les intercepteurs dans web.xml si l'ordre d'exécution de vos intercepteurs est important.
Les intercepteurs Struts2 implémentent aussi une interface Interceptor. Vous devez également définir la classe de l'intercepteur dans struts.xml, puis définir un nouveau stack pour l'intercepteur qui utilise le stack par défaut en y ajoutant votre intercepteur. Finalement, il faut configurer lesquelles de vos actions utiliseront ce nouveau stack d'intercepteurs.