Struts2 est une infrastructure d'application Web populaire et mature basée sur le modèle de conception MVC. Struts2 n'est pas seulement la prochaine version de Struts 1, mais c'est une réécriture complète de l'architecture Struts.

Voici quelques-unes des fonctionnalités intéressantes qui peuvent vous obliger à envisager Struts2 -

  • POJO forms and POJO actions- Struts2 a supprimé les formulaires d'action qui faisaient partie intégrante du framework Struts. Avec Struts2, vous pouvez utiliser n'importe quel POJO pour recevoir l'entrée du formulaire. De même, vous pouvez désormais voir n'importe quel POJO en tant que classe Action.

  • Tag support - Struts2 a amélioré les balises de formulaire et les nouvelles balises permettent aux développeurs d'écrire moins de code.

  • AJAX support - Struts2 a reconnu la prise de contrôle des technologies Web2.0 et a intégré le support AJAX dans le produit en créant des balises AJAX, qui fonctionnent de manière très similaire aux balises Struts2 standard.

  • Easy Integration - L'intégration avec d'autres frameworks comme Spring, Tiles et SiteMesh est maintenant plus facile avec une variété d'intégration disponible avec Struts2.

  • Template Support - Prise en charge de la génération de vues à l'aide de modèles.

  • Plugin Support- Le comportement principal de Struts2 peut être amélioré et augmenté par l'utilisation de plugins. Un certain nombre de plugins sont disponibles pour Struts2.

Le modèle Model-View-Controller dans Struts2 est réalisé avec les cinq composants principaux suivants:

  • Actions

  • Interceptors

  • Value Stack / OGNL

  • Résultats / types de résultats

  • Voir les technologies

Voici le cycle de vie d'une demande dans l'application Struct2 -

  • L'utilisateur envoie une demande au serveur pour demander une ressource (c'est-à-dire des pages).

  • Le FilterDispatcher examine la demande, puis détermine l'action appropriée.

  • Les fonctionnalités des intercepteurs configurés s'appliquent telles que la validation, le téléchargement de fichiers, etc.

  • L'action sélectionnée est exécutée pour exécuter l'opération demandée.

  • Là encore, des intercepteurs configurés sont appliqués pour effectuer tout post-traitement si nécessaire.

  • Enfin, le résultat est préparé par la vue et renvoie le résultat à l'utilisateur.

Le fichier struts.xml contient les informations de configuration que vous modifierez au fur et à mesure du développement des actions. Ce fichier peut être utilisé pour remplacer les paramètres par défaut d'une application, par exemple struts.devMode = false et d'autres paramètres définis dans le fichier de propriétés. Ce fichier peut être créé dans le dossier WEB-INF / classes.

La balise constante ainsi que les attributs de nom et de valeur seront utilisés pour remplacer l'une des propriétés suivantes définies dans default.properties, comme nous venons de définir la propriété struts.devMode. La définition de la propriété struts.devMode nous permet de voir plus de messages de débogage dans le fichier journal.

Nous définissons les balises d'action correspondant à chaque URL à laquelle nous voulons accéder et nous définissons une classe avec la méthode execute () qui sera accessible chaque fois que nous accéderons à l'URL correspondante.

Les résultats déterminent ce qui est renvoyé au navigateur après l'exécution d'une action. La chaîne renvoyée par l'action doit être le nom d'un résultat. Les résultats sont configurés par action comme ci-dessus, ou en tant que résultat «global», disponible pour chaque action d'un package. Les résultats ont des attributs de nom et de type facultatifs. La valeur par défaut du nom est "succès".

Le fichier de configuration struts-config.xml est un lien entre les composants View et Model dans le client Web.

C'est là que vous mappez votre sous-classe ActionForm à un nom. Vous utilisez ce nom comme alias pour votre ActionForm dans le reste du fichier struts-config.xml, et même sur vos pages JSP.

Cette section associe une page de votre application Web à un nom. Vous pouvez utiliser ce nom pour faire référence à la page réelle. Cela évite le codage en dur des URL sur vos pages Web.

C'est là que vous déclarez les gestionnaires de formulaires et ils sont également appelés mappages d'actions.

Cette section indique à Struts où trouver vos fichiers de propriétés, qui contiennent des invites et des messages d'erreur.

Ce fichier de configuration fournit un mécanisme pour modifier le comportement par défaut du framework. En fait, toutes les propriétés contenues dans le fichier de configuration struts.properties peuvent également être configurées dans le fichier web.xml en utilisant le paramètre init-param, ainsi qu'en utilisant la balise constante dans le fichier de configuration struts.xml. Mais si vous souhaitez garder les choses séparées et plus spécifiques, vous pouvez créer ce fichier dans le dossier WEB-INF / classes. Les valeurs configurées dans ce fichier remplaceront les valeurs par défaut configurées dans default.properties qui est contenu dans la distribution struts2-core-xyzjar.

Les intercepteurs sont conceptuellement identiques aux filtres de servlet ou à la classe JDK Proxy. Les intercepteurs permettent de mettre en œuvre des fonctionnalités transversales séparément de l'action ainsi que du cadre. Vous pouvez réaliser ce qui suit en utilisant des intercepteurs -

  • Fournir une logique de prétraitement avant que l'action ne soit appelée.

  • Fournir une logique de post-traitement après l'appel de l'action.

  • Attraper des exceptions afin qu'un autre traitement puisse être effectué.

La création d'un intercepteur personnalisé est facile; l'interface qui doit être étendue est l'interface Interceptor.

L'action réelle sera exécutée à l'aide de l'intercepteur par appel invocation.invoke (). Ainsi, vous pouvez effectuer un pré-traitement et un post-traitement en fonction de vos besoins.

Le framework lui-même démarre le processus en effectuant le premier appel à invoke () de l'objet ActionInvocation. Chaque fois que invoke () est appelé, ActionInvocation consulte son état et exécute l'intercepteur suivant. Lorsque tous les intercepteurs configurés ont été invoqués, la méthode invoke () provoquera l'exécution de l'action elle-même.

La classe Action gère l'état de l'application et le type de résultat gère la vue.

Le type de résultat par défaut est dispatcher, qui est utilisé pour envoyer aux pages JSP.

Le type de résultat du répartiteur est le type par défaut et est utilisé si aucun autre type de résultat n'est spécifié. Il est utilisé pour transférer vers un servlet, une JSP, une page HTML, etc. sur le serveur. Il utilise la méthode RequestDispatcher.forward ().

Le type de résultat de redirection appelle la méthode standard response.sendRedirect (), ce qui oblige le navigateur à créer une nouvelle requête vers l'emplacement donné. Nous pouvons fournir l'emplacement soit dans le corps de l'élément <result ...>, soit en tant qu'élément <param name = "location">.

La pile de valeurs est un ensemble de plusieurs objets qui conserve les objets suivants dans l'ordre fourni -

  • Temporary Objects- Il existe différents objets temporaires qui sont créés lors de l'exécution d'une page. Par exemple, la valeur d'itération actuelle pour une collection en boucle dans une balise JSP.

  • The Model Object - Si vous utilisez des objets de modèle dans votre application Struts, l'objet de modèle actuel est placé avant l'action sur la pile de valeurs.

  • The Action Object - Ce sera l'objet d'action en cours d'exécution.

  • Named Objects - Ces objets incluent #application, #session, #request, #attr et #parameters et font référence aux portées de servlet correspondantes.

Le langage OGNL (Object-Graph Navigation Language) est un langage d'expression puissant utilisé pour référencer et manipuler des données sur ValueStack. OGNL aide également au transfert de données et à la conversion de type.

La carte ActionContext comprend les éléments suivants:

  • application - variables de portée de l'application.

  • session - variables de portée de session.

  • root / value stack - toutes vos variables d'action sont stockées ici.

  • request - demander des variables de portée.

  • parameters - paramètres de demande.

  • atributes - les attributs stockés dans la portée de la page, de la requête, de la session et de l'application.

Le téléchargement de fichiers dans Struts est possible via un intercepteur prédéfini appelé intercepteur FileUpload, disponible via la classe org.apache.struts2.interceptor.FileUploadInterceptor et inclus dans le defaultStack.

Voici les propriétés de configuration Struts2 qui contrôlent le processus de téléchargement des fichiers -

  • struts.multipart.maxSize- La taille maximale (en octets) d'un fichier à accepter comme téléchargement de fichier. La valeur par défaut est 250M.

  • struts.multipart.parser- La bibliothèque utilisée pour télécharger le formulaire en plusieurs parties. Par défaut, c'est jakarta.

  • struts.multipart.saveDir- L'emplacement de stockage du fichier temporaire. Par défaut, javax.servlet.context.tempdir.

L'intercepteur fileUplaod utilise plusieurs touches de message d'erreur par défaut -

  • struts.messages.error.uploading - Une erreur générale qui se produit lorsque le fichier n'a pas pu être téléchargé.

  • struts.messages.error.file.too.large - Se produit lorsque le fichier téléchargé est trop volumineux comme spécifié par maximumSize.

  • struts.messages.error.content.type.not.allowed - Se produit lorsque le fichier téléchargé ne correspond pas aux types de contenu attendus spécifiés.

Vous pouvez remplacer le texte de ces messages dans les fichiers de ressources WebContent / WEB-INF / classes / messages.properties.

Au cœur de Struts, nous avons le cadre de validation qui aide l'application à exécuter les règles pour effectuer la validation avant que la méthode d'action ne soit exécutée. La classe Action doit étendre la classe ActionSupport pour que la méthode validate soit exécutée.

Lorsque l'utilisateur appuie sur le bouton d'envoi, Struts 2 exécutera automatiquement la méthode validate et si l'une des instructions if répertoriées dans la méthode est vraie, Struts 2 appellera sa méthode addFieldError. Si des erreurs ont été ajoutées, Struts 2 ne procèdera pas à l'appel de la méthode d'exécution. Au lieu de cela, le framework Struts 2 retournera une entrée à la suite de l'appel de l'action.

Ainsi, lorsque la validation échoue et que Struts 2 retourne l'entrée, le framework Struts 2 réaffichera le fichier de vue. Puisque nous avons utilisé des balises de formulaire Struts 2, Struts 2 ajoutera automatiquement les messages d'erreur juste au-dessus du formulaire déposé.

Ces messages d'erreur sont ceux que nous avons spécifiés dans l'appel de la méthode addFieldError. La méthode addFieldError prend deux arguments. Le premier est le nom du champ de formulaire auquel l'erreur s'applique et le second est le message d'erreur à afficher au-dessus de ce champ de formulaire.

La deuxième méthode de validation consiste à placer un fichier xml à côté de la classe d'action. La validation basée sur XML Struts2 offre plus d'options de validation comme la validation par e-mail, la validation de plage d'entiers, le champ de validation de formulaire, la validation d'expression, la validation regex, la validation requise, la validation de chaîne requise, la validation de longueur de chaîne, etc.

Le fichier xml doit être nommé «[classe d'action]» - validation.xml.

Vous trouverez ci-dessous la liste des différents types de validation au niveau du champ et hors du champ disponibles dans Struts2 -

  • validateur de date

  • double validateur

  • validateur d'email

  • validateur d'expression

  • validateur int

  • validateur de regex

  • validateur requis

  • validateur de chaîne requis

  • validateur de longueur de chaîne

  • validateur d'url

L'internationalisation (i18n) est le processus de planification et de mise en œuvre de produits et de services afin qu'ils puissent être facilement adaptés à des langues et cultures locales spécifiques, un processus appelé localisation. Le processus d'internationalisation est parfois appelé traduction ou activation de la localisation.

Struts2 fournit la localisation ie. prise en charge de l'internationalisation (i18n) via des ensembles de ressources, des intercepteurs et des bibliothèques de balises aux endroits suivants -

  • Les balises UI.

  • Messages et erreurs.

  • Au sein des classes d'action.

Le format de dénomination le plus simple pour un fichier de ressources est -

bundlename_language_country.properties

Ici, le bundlename peut être ActionClass, Interface, SuperClass, Model, Package, Global resource properties. La partie suivante language_country représente les paramètres régionaux du pays. Par exemple, les paramètres régionaux espagnols (Espagne) sont représentés par es_ES et les paramètres régionaux anglais (États-Unis) sont représentés par en_US, etc. Ici, vous pouvez ignorer la partie pays qui est facultative.

Lorsque vous référencez un élément de message par sa clé, le framework Struts recherche un ensemble de messages correspondant dans l'ordre suivant -

  • ActionClass.properties

  • Interface.properties

  • SuperClass.properties

  • model.properties

  • package.properties

  • struts.properties

  • global.properties

La classe StrutsTypeConverter indique à Struts comment convertir l'environnement en chaîne et vice versa en remplaçant deux méthodes convertFromString () et convertToString ().

Struts 2 est livré avec trois thèmes intégrés -

  • simple theme- Un thème minimal sans "cloches et sifflets". Par exemple, la balise textfield rend la balise HTML <input /> sans étiquette, validation, rapport d'erreurs ou toute autre mise en forme ou fonctionnalité.

  • xhtml theme - C'est le thème par défaut utilisé par Struts 2 et fournit toutes les bases que le thème simple fournit et ajoute plusieurs fonctionnalités telles que la disposition de table standard à deux colonnes pour le HTML, les étiquettes pour chacun des HTML, la validation et les rapports d'erreurs, etc.

  • css_xhtml theme - Ce thème fournit toutes les bases que le thème simple fournit et ajoute plusieurs fonctionnalités telles que la mise en page standard à deux colonnes basée sur CSS, en utilisant <div> pour les balises HTML Struts, des étiquettes pour chacune des balises HTML Struts, placées selon le CSS feuille de style.

Struts facilite la gestion des exceptions grâce à l'utilisation de l'intercepteur "exception". L'intercepteur "d'exception" est inclus dans la pile par défaut, vous n'avez donc rien à faire de plus pour le configurer. Il est prêt à l'emploi et prêt à être utilisé.

Une annotation @Results est une collection de résultats. Sous l'annotation @Results, nous pouvons avoir plusieurs annotations @Result.

@Results({
   @Result(name = "success", value = "/success.jsp"),
   @Result(name = "error", value = "/error.jsp")
})
public class Employee extends ActionSupport{
 ...
}

Les annotations @result ont le nom qui correspond au résultat de la méthode d'exécution. Ils contiennent également un emplacement indiquant quelle vue doit être servie correspondant à la valeur de retour de execute ().

@Result(name = "success", value = "/success.jsp")
public class Employee extends ActionSupport{
 ...
}

Ceci est utilisé pour décorer la méthode execute (). La méthode Action prend également une valeur qui est l'URL sur laquelle l'action est appelée.

public class Employee extends ActionSupport{
   private String name;
   private int age;
   @Action(value = "/empinfo")
   public String execute() {
      return SUCCESS;
   }
}

L'annotation @After marque une méthode d'action qui doit être appelée après la méthode d'action principale et le résultat a été exécuté. La valeur de retour est ignorée.

public class Employee extends ActionSupport{
   @After
   public void isValid() throws ValidationException {
      // validate model object, throw exception if failed
   }
   public String execute() {
      // perform secure action
      return SUCCESS;
   }
}

L'annotation @Before marque une méthode d'action qui doit être appelée avant que la méthode d'action principale et le résultat ne soient exécutés. La valeur de retour est ignorée.

public class Employee extends ActionSupport{
   @Before
   public void isAuthorized() throws AuthenticationException {
      // authorize request, throw exception if failed
   }
   public String execute() {
      // perform secure action
      return SUCCESS;
   }
}

L'annotation @BeforeResult marque une méthode d'action qui doit être exécutée avant le résultat. La valeur de retour est ignorée.

public class Employee extends ActionSupport{
   @BeforeResult
   public void isValid() throws ValidationException {
    // validate model object, throw exception if failed
   }
   public String execute() {
      // perform action
      return SUCCESS;
   }
}

Cette annotation de validation vérifie s'il existe des erreurs de conversion pour un champ et les applique si elles existent.

public class Employee extends ActionSupport{
   @ConversionErrorFieldValidator(message = "Default message", 
                        key = "i18n.key", shortCircuit = true)
   public String getName() {
       return name;
   }
}

Cette annotation de validation vérifie qu'un champ de date a une valeur dans une plage spécifiée.

public class Employee extends ActionSupport{
   @DateRangeFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   min = "2005/01/01", max = "2005/12/31")
   public String getDOB() {
       return dob;
   }
}

Cette annotation de validation vérifie qu'un champ double a une valeur dans une plage spécifiée. Si ni min ni max ne sont définis, rien ne sera fait.

public class Employee extends ActionSupport{
   @DoubleRangeFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   minInclusive = "0.123", maxInclusive = "99.987")
   public String getIncome() {
       return income;
   }
}

Cette annotation de validation vérifie qu'un champ est une adresse de messagerie valide s'il contient une chaîne non vide.

public class Employee extends ActionSupport{
   @EmailValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true)
   public String getEmail() {
       return email;
   }
}

Ce validateur de niveau non-champ valide une expression régulière fournie.

@ExpressionValidator(message = "Default message", key = "i18n.key", 
shortCircuit = true, expression = "an OGNL expression" )

Cette annotation de validation vérifie qu'un champ numérique a une valeur dans une plage spécifiée. Si ni min ni max ne sont définis, rien ne sera fait.

public class Employee extends ActionSupport{
   @IntRangeFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   min = "0", max = "42")
   public String getAge() {
       return age;
   }
}

Cette annotation valide un champ de chaîne à l'aide d'une expression régulière.

@RegexFieldValidator( key = "regex.field", expression = "yourregexp")

Cette annotation de validation vérifie qu'un champ n'est pas nul. L'annotation doit être appliquée au niveau de la méthode.

public class Employee extends ActionSupport{
   @RequiredFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true)
   public String getAge() {
       return age;
   }
}

Cette annotation de validation vérifie qu'un champ String n'est pas vide (c'est-à-dire non nul avec une longueur> 0).

public class Employee extends ActionSupport{
   @RequiredStringValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, trim = true)
   public String getName() {
       return name;
   }
}

Ce validateur vérifie qu'un champ String est de la bonne longueur. Il suppose que le champ est une chaîne. Si ni minLength ni maxLength ne sont définis, rien ne sera fait.

public class Employee extends ActionSupport{
   @StringLengthFieldValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true, 
   trim = true, minLength = "5",  maxLength = "12")
   public String getName() {
       return name;
   }
}

Ce validateur vérifie qu'un champ est une URL valide.

public class Employee extends ActionSupport{
   @UrlValidator(message = "Default message", 
   key = "i18n.key", shortCircuit = true)
   public String getURL() {
       return url;
   }
}

Si vous souhaitez utiliser plusieurs annotations du même type, ces annotations doivent être imbriquées dans l'annotation @Validations ().

public class Employee extends ActionSupport{
  @Validations(
   requiredFields =
      {@RequiredFieldValidator(type = ValidatorType.SIMPLE, 
      fieldName = "customfield", 
      message = "You must enter a value for field.")},
   requiredStrings =
      {@RequiredStringValidator(type = ValidatorType.SIMPLE, 
      fieldName = "stringisrequired", 
      message = "You must enter a value for string.")}
   )
   public String getName() {
       return name;
   }
}

Cette annotation peut être utilisée pour les validateurs personnalisés. Utilisez l'annotation ValidationParameter pour fournir des paramètres supplémentaires.

@CustomValidator(type ="customValidatorName", fieldName = "myField")

Il s'agit d'une annotation de marqueur pour les conversions de type au niveau du type. L'annotation de conversion doit être appliquée au niveau du type.

@Conversion()
   public class ConversionAction implements Action {
}

Cette annotation définit le CreateIfNull pour la conversion de type. L'annotation CreateIfNull doit être appliquée au niveau du champ ou de la méthode.

@CreateIfNull( value = true )
private List<User> users;

Cette annotation définit l'élément pour la conversion de type. L'annotation Élément doit être appliquée au niveau du champ ou de la méthode.

@Element( value = com.acme.User )
private List<User> userList;

Cette annotation définit la clé pour la conversion de type. L'annotation Key doit être appliquée au niveau du champ ou de la méthode.

@Key( value = java.lang.Long.class )
private Map<Long, User> userMap;

Cette annotation définit la KeyProperty pour la conversion de type. L'annotation KeyProperty doit être appliquée au niveau du champ ou de la méthode.

@KeyProperty( value = "userName" )
protected List<User> users = null;

Cette annotation d'annotation est utilisée pour les règles de conversion à l'échelle de la classe et de l'application. L'annotation TypeConversion peut être appliquée au niveau de la propriété et de la méthode.

@TypeConversion(rule = ConversionRule.COLLECTION, 
converter = "java.util.String")
public void setUsers( List users ) {
   this.users = users;
}