Stripes contre Struts2

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.propertiesActionName 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.