Balises UI et gestion des thèmes
Struts2 met à disposition un jeu de balises conçues pour simplifier la génération de composants d'interface. Bien qu'elles réduisent la duplication de code HTML, il est important de rappeler que ces tags sont évalués côté serveur avant d'être compilés en HTML pour le navigateur. Ce processus de rendu côté serveur introduit une surcharge non négligeable par rapport à l'utilisation exclsuive de balises HTML statiques. De plus, le marquage automatique généré par Struts2 peut interférer avec les architectures CSS modernes. Il est donc conseillé de recourir à ces balises uniquement lorsque leur intégration native avec le pipeline Struts2 justifie le coût de performance.
<%-- Structure de formulaire standard avec les tags Struts2 --%>
<s:form id="authForm" action="/process-login" method="POST">
<s:textfield label="Identifiant" name="account.login"/>
<s:password label="Mot de passe" name="account.passphrase"/>
<s:submit value="Valider"/>
</s:form>
Lors de l'inspection du code source généré, on observe que Struts2 enveloppe systématiquement les champs dans des structures de mise en forme supplémentaires. Pour supprimer cet encadrement automatique et obtenir un rendu minimaliste, il suffit d'appliquer le thème simple au formulaire :
<s:form theme="simple" ...>
Cette préférence peut être définie de manière globale dans le fichier de configuration principal :
<constant name="struts.ui.theme" value="simple"/>
Mécanisme de pré-remplissage des données
Le pré-remplissage des formulaires consiste à réinjecter des valeurs existantes dans les champs de saisie lors de l'affichage. Contrairement aux approches traditionnelles qui reposent sur le stockage explicite dans la portée HTTP (request ou session), Struts2 s'appuie sur sa pile de valeurs interne (ValueStack). Lorsque les données sont placées à la racine de cette pile, le moteur de liaison automatique établit la correspondance entre l'attribut name du tag et la propriété de l'objet, éliminant le besoin d'expressions OGNL complexes.
Implémentation côté contrôleur :
public String preparerFormulaire() {
ValueStack pile = ActionContext.getContext().getValueStack();
ProfilUtilisateur profil = new ProfilUtilisateur();
profil.setIdentifiant("responsable");
profil.setCourriel("resp@domaine.fr");
pile.push(profil); // Injection en tant qu'élément racine
return "succes";
}
Côté vue, le binding devient immédiat :
<s:form theme="simple">
<s:textfield label="Identifiant" name="identifiant"/>
<s:textfield label="Courriel" name="courriel"/>
</s:form>
Cette approche déléguée simplifie considérablement la maintenance des vues en supprimant les références manuelles aux portées de requête.
Gestion des sélections multiples avec checkboxlist
La balise <s:checkboxlist> permet de générer dynamiquement des groupes de cases à cocher. Ses attributs clés fonctionnent comme suit :
list: source de données (Collection ou Map) fournie par l'Action.listKey&listValue: spécifient respectivement les propriétés utilisées pour la valeur soumise et le texte affiché.name: atribut de l'Action destiné à recevoir les sélections (généralement un tableau ou une liste).value: définit les éléments initialement cochés lors du rendu.
Exemple concret pour la gestion de droits :
public String chargerDroits() {
ActionContext contexte = ActionContext.getContext();
contexte.put("catalogueDroits", serviceAutorisations.tousLesDroits());
if (utilisateur != null) {
Collection<autorisation> droitsActifs = serviceProfil.rechercherParUtilisateur(utilisateur.getUuid());
codesDroitsSelectionnes = droitsActifs.stream()
.map(Autorisation::getCode)
.toArray(String[]::new);
}
return "formulaire";
}</autorisation>
Asssociation avec la vue JSP :
<s:checkboxlist
list="#catalogueDroits"
name="codesDroitsSelectionnes"
listKey="code"
listValue="description"
value="codesDroitsSelectionnes"/>
Le framework compare automatiquement les valeurs de name et value pour appliquer l'état checked aux bonnes cases sans intervention supplémentaire.
Configuration de l'internationalisation
Struts2 intègre un moteur de localisation basé sur des fichiers de ressources .properties. Le chargement de ces bundles est simplifié par rapport aux implémentations Servlet classiques, nécessitant uniquement une déclaration constante. Il est impératif de veiller à l'encodage UTF-8 des fichiers pour garantir l'affichage correct des caractères spéciaux.
Déclaration dans struts.xml :
<constant name="struts.custom.i18n.resources" value="config/i18n/labels"/>
Contenu du fichier de ressources (labels.properties et ses variantes linguistiques) :
titre.interface=Espace de connexion
champ.identifiant=Nom d'utilisateur
champ.secret=Phrase de sécurité
action.acceder=Accéder
Exploitation dans la vue :
<head>
<title><s:text name="titre.interface"/></title>
</head>
<body>
<s:form action="/traitement" theme="simple">
<label><s:text name="champ.identifiant"/></label>
<input type="text" name="session.login"/>
<label><s:text name="champ.secret"/></label>
<input type="password" name="session.secret"/>
<s:submit value="%{getText('action.acceder')}"/>
</s:form>
</body>
Le moteur résout dynamiquement les clés en fonction de la locale associée à la requête HTTP, assurant une adaptation linguistique transparente sans modification du code applicatif.