1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
21 22 23 24 25 26 27 28 

Struts - Un framework MVC pour vos applications J2EE

3.8.Fichier de configuration

Le fichier de configuration est le point central de toute application Struts. En effet, il regroupe l’ensemble des objets et de leur configuration. On peut connaître l’ensemble de la logique de l’application (navigation) avec ce fichier. Malgré la lourdeur d’utilisation de xml dans une application web complexe (suivant le nombre de fonctionnalités), les outils qui ont été mis en œuvre pour aider le développeur dans le paramétrage de ce fichier sont maintenant stables et robustes.

3.8.1.Assemblage de l'application

Le fichier de configuration : struts-config.xml (le plus souvent nommé ainsi) est chargé d’indiquer à Struts quels sont les formulaires, les actions disponibles et permet également d’ajouter un certain nombre de modèles « enfichables » au package Struts de base.
Nous étudierons ici l’ensemble des balises de bases utilisées dans une application Struts grâce à la DTD fournit par Struts à l’adresse suivante : http://jakarta.apache.org/struts/dtds/struts_config_1_2.dtd (DTD de la version 1.2).
La première balise que l’on retrouve dans le fichier de configuration est : « struts-config ». La dtd correspondante est celle-ci :
<!ELEMENT struts-config (display-name?, description?, data-sources?, form-beans?, global-exceptions?, global-forwards?, action-mappings?, controller?, message-resources*, plug-in*)>
<!ATTLIST struts-config id ID #IMPLIED>
On l’appelle la balise « root », c'est-à-dire la racine de toutes les autres. On ne peut trouver qu’une seule de cette balise dans un même fichier. Il est aisé de voir qu’elle accepte (dans son corps) les balises :
  • display-name : nom de l’application liée au fichier de configuration en cours
  • description : description du fichier de configuration
  • data-sources : l’ensemble des sources de données (1 instance acceptée)
  • form-beans : l’ensemble des « form-bean » (1 instance acceptée)
  • global-exceptions : l’ensemble des handler d’exception (1 instance acceptée)
  • global-forwards : l’ensemble des points de retour de type « global » (1 instance acceptée)
  • action-mappings : l’ensemble des mappings d’action (1 instance acceptée)
  • controller : paramétrage d’un contrôleur spécifique (dit RequestController) (1 instance acceptée)
  • message-resources : définition d’un bundle de messages (multiples instances acceptées)
  • plug-in : définition d’un package (extérieur) connecté : plug’in (multiples instances acceptées)

3.8.2.Datasources

Vos objets modèles ont peut être besoin d’établir une connexion avec une base de données. Dans ce cas, vous pouvez utilisez Struts pour initialiser un pool de connexion plutôt que de passer directement par votre serveur d’application. L’intérêt premier est que vous n’aurez pas à « toucher » à la configuration de votre serveur d’application lors du déploiement de votre application. Cela simplifie donc grandement le déploiement de celle-ci.
Voici la partie de DTD correspondante aux DataSource :
<!ELEMENT data-sources (data-source*)>
<!ATTLIST data-sources id ID #IMPLIED>
<!ELEMENT data-source (set-property*)>
<!ATTLIST data-source id ID #IMPLIED>
<!ATTLIST data-source className %ClassName; #IMPLIED>
<!ATTLIST data-source key %AttributeName; #IMPLIED>
<!ATTLIST data-source type %ClassName; #REQUIRED>

La balise data-sources regroupe l’ensemble des data-source configuré pour l’application. Elle contient donc de 0 à n balises data-source.

Chaque balise data-source définit précisément les paramètres de configuration des connexions à une source de données (et plus précisément à des objets JDBC 2.0 DataSource). Voici les différentes balises qu’elle peut contenir :
  • className : cette balise est optionnelle. Elle définit la classe servant à configurer la source de données et doit donc contenir toutes les données nécessaires pour instancier une DataSource du type requis. Autrement dit, elle doit gérer l’ensemble des propriétés spécifiées dans les clauses set-property (cf. plus bas) de la balise. Si cette balise est omise, Struts utilise la classe par défaut : org.apache.struts.config.Config pour gérer les propriétés.
  • key : est une clé qui permet à l’application d’accéder à l’objet datasource créé par Struts. Par exemple dans le cas d’une clé : « stockdb », l’application pourra y accéder via : « org.apache.struts.action.DATA_SOURCE/stockdb » (si aucun préfixe de module n’existe : préfixe = "")
  • type : spécifie le nom de la classe de la DataSource qui doit implémenter java.sql.DataSource. Cette classe est utilisée par Struts pour créer une instance de la datasource, elle configuré via la classe définit dans l’attribute « className ».
  • set-property : cette balise permet d’attribuer une clé et une valeur. Elles servent principalement à configurer les paramètres de connexion à la source de données (login, password, paramètres de la base…)
Voici la DTD correspondante :

<!ELEMENT set-property EMPTY>
<!ATTLIST set-property id ID #IMPLIED>
<!ATTLIST set-property property %PropName; #REQUIRED>
<!ATTLIST set-property value CDATA #REQUIRED>

  • property : représente la clé (propriété)
  • value : représente la valeur liée à la clé

3.8.2.1.Exemple

Voici un exemple XML de la clause data-sources :

<data-source>
<set-property property="autoCommit" value="true"/>
<set-property property="decription" value="DataSource - MysqlLocal"/>
<set-property property="driverClass" value="com.mysql.jdbc.Driver"/>
<set-property property="maxCount" value="4"/>
<set-property property="minCount" value="1"/>
<set-property property="user" value="root"/>
<set-property property="password" value=""/>
<set-property property="url" value="jdbc:mysql://localhost/contacts"/>
</data-source>

3.8.2.2.Utilisation dans l’application

Vous pouvez accéder à l’objet DataSource depuis une Action via le code suivant :

DataSource ds = servlet.getServletContext().getAttribute(“org.apache.struts.action.DATA_SOURCE/stockdb”);

A partir de là, vous pourrez récupérer une connexion à votre source de données et effectuer tous les traitements que vous désirer.

3.8.3.FormBeans

Les balises form-beans et form-bean indiquent à Struts à quel identifiant unique est associé une classe ActionForm. Elles servent également à initialiser les DynaForms (cf. §5.3).
Voici la partie de DTD correspondante :
<!ELEMENT form-beans (form-bean*)>
<!ATTLIST form-beans id ID #IMPLIED>
<!ATTLIST form-beans type %ClassName; #IMPLIED>

<!ATTLIST form-bean id ID #IMPLIED>
<!ATTLIST form-bean className %ClassName; #IMPLIED>
<!ATTLIST form-bean dynamic %Boolean; #IMPLIED>
<!ATTLIST form-bean name %BeanName; #REQUIRED>
<!ATTLIST form-bean type %ClassName; #REQUIRED>

<!ELEMENT form-property (set-property*)>
<!ATTLIST form-property className %ClassName; #IMPLIED>
<!ATTLIST form-property initial CDATA #IMPLIED>
<!ATTLIST form-property name %PropName; #REQUIRED>
<!ATTLIST form-property size %Integer; #IMPLIED>
<!ATTLIST form-property type %ClassName; #REQUIRED>

Voici une description de chacune des balises :
  • form-beans : encapsule la liste des beans formulaires définis. L’attribut type a été déclassé.
  • form-bean : définit un formulaire unique.
    • className : sert à définir un bean de configuration pour ce formulaire (comme pour les DataSource) cependant cela est n’est pas commun.
    • dynamic : a été déclassé
    • name : représente l’identifiant unique qui permet d’accéder au formulaire et d’associé ultérieurement le formulaire à une action. Remarque importante : si la portée de votre formulaire est celle de la session, vous pouvez accéder au formulaire via la méthode getAttribute() de l’objet session.
    • type : doit indiquer une classe ActionForm valide. C’est cette classe qui sera instanciée pour créer le formulaire.
Si le type dérive (ou est) : org.apache.struts.action.DynaActionForm, les balises form-property sont également inspectées par Struts. Chacune d’elles définit une valeur initiale, un nom et un type (par exemple java.lang.String) pour chaque propriété du formulaire (cf. §5.3)

3.8.3.1.Exemple


<form-bean name="contactForm"
type="com.society.contactbook.application.forms.ContactForm" />

3.8.4.Exceptions

La balise global-exceptions regroupe l’ensemble des exceptions que votre application gère au plus bas niveau durant le traitement d’une requête. Vous pouvez gérer autant de type d’exception que vous le souhaitez. Nous pouvons assimiler cette partie de configuration au try … catch dans le langage Java. En effet vous déclarez un bloc « catch » via une balise exception.
Voici une description des attributs qu’admet cette balise :
  • bundle : spécifie le nom du bundle de ressources qui contiendra les messages pour cette exception.
  • handler : spécifie la classe appelée lorsque l’exception se produit. Elle doit impérativement dérivée de la classe org.apache.struts.action.ExceptionHandler ou d’une classe dérivée.
  • key : désigne la clé du message d’erreur qui sera généré et qui sera recherché dans le bundle de messages.
  • path : définit l’URL à laquelle le contrôle est transféré lorsque l’exception survient.
  • scope : indique à Struts s’il doit mémoriser les ActionError créées par la gestion de l’exception dans la portée de la session ou la requête.
  • type : nomme l’exception qui sera interceptée par ce gestionnaire.

3.8.4.1.Exemple


<global-exceptions>
<exception key=”database.error” path=”/errors/generalErrors.jsp”
scope=”request” type=”java.sql.SQLException” />
</global-exceptions>
Si une exception est lancée durant le traitement, le modèle database.error est recherché dans le bundle de ressources par défaut (ApplicationResources.properties), une nouvelle ActionError est créée à l’aide du modèle, puis elle est placée dans les attributs de la requête et le contrôle est transmis à la page d’erreur standard.

3.8.5.Global Forwards

Les transferts globaux servent à définir des chemins d’accès utilisables par toutes les actions définies dans la configuration. Si par exemple un certains nombre d’actions doivent transférer le contrôle à un écran de connexion, vous pouvez définir ce transfert ici au lieu de le faire dans chaque action.
Voici la partie de la DTD correspondante :
<!ELEMENT global-forwards (forward*)>
<!ATTLIST global-forwards id ID #IMPLIED>
<!ATTLIST global-forwards type %ClassName; #IMPLIED>

<!ELEMENT forward (icon?, display-name?, description?, set-property*)>
<!ATTLIST forward id ID #IMPLIED>
<!ATTLIST forward className %ClassName; #IMPLIED>
<!ATTLIST forward contextRelative %Boolean; #IMPLIED>
<!ATTLIST forward module %RequestPath; #IMPLIED>
<!ATTLIST forward name CDATA #REQUIRED>
<!ATTLIST forward path %RequestPath; #REQUIRED>
<!ATTLIST forward redirect %Boolean; #IMPLIED>
Voici la description de l’ensemble des attributs :
  • contextRelative : indique si « path » est relatif au module d’une application modulaire (si faux) ou de l’application web (si vraie)
  • name : représente l’identifiant unique du forward. Il permet de retrouver ce forward dans une action avec la méthode findForward()
  • redirect : si positionné à true le contrôle est transmis à la page avec une redirection plutôt qu’un transfert. Une nouvelle requête est donc créée
Nous n’utilisons généralement pas les balises set-property pour les forward. Cependant celles-ci peuvent vous être utiles si vous souhaitez créer vos propres classes de forward (dérivant de la classe de base). Dans ce cas là vous devrez également indiquer le nom complet de la classe dans l’attribut : className.

3.8.5.1.Exemple

Voici un exemple simple d’utilisation de global-forwards :
<global-forwards>
<forward name=”home” path=”/pages/home.jsp” />
</global-forwards>

3.8.6.Action mappings

Cette partie est sans doute la plus complexe. Elle relie les actions, les formulaires et les transferts.
Voici la partie de la DTD correspondante :
<!ELEMENT action-mappings (action*)>
<!ATTLIST action-mappings id ID #IMPLIED>
<!ATTLIST action-mappings type %ClassName; #IMPLIED>

<!ELEMENT action (icon?, display-name?, description?, set-property*, exception*, forward*)>
<!ATTLIST action id ID #IMPLIED>
<!ATTLIST action attribute %BeanName; #IMPLIED>
<!ATTLIST action className %ClassName; #IMPLIED>
<!ATTLIST action forward %RequestPath; #IMPLIED>
<!ATTLIST action include %RequestPath; #IMPLIED>
<!ATTLIST action input %RequestPath; #IMPLIED>
<!ATTLIST action name %BeanName; #IMPLIED>
<!ATTLIST action parameter CDATA #IMPLIED>
<!ATTLIST action path %RequestPath; #REQUIRED>
<!ATTLIST action prefix CDATA #IMPLIED>
<!ATTLIST action roles CDATA #IMPLIED>
<!ATTLIST action scope %RequestScope; #IMPLIED>
<!ATTLIST action suffix CDATA #IMPLIED>
<!ATTLIST action type %ClassName; #IMPLIED>
<!ATTLIST action unknown %Boolean; #IMPLIED>
<!ATTLIST action validate %Boolean; #IMPLIED>

Voici une description de chacune des balises :
  • attribute : spécifie un ID unique permettant de mémoriser l’ActionForm dans la portée de la requête ou la session sinon name est utilisé
  • forward / include : permettent de transférer le contrôle à un nouveau chemin au lieu de traiter l’action
  • input : indique la page ou action qui a généré le formulaire servant à entrer les données
  • parameter : permet de transmettre un autre paramètre à l’action, cependant il est alors préférable d’utiliser la balise plus générale : set-property
  • path : sert à relier la requête à l’action – ce doit être le chemin de l’action sans aucun suffixe. Si par exemple vous avez spécifié « /admin/add.do » dans l’action de votre formulaire alors vous indiquerez « /admin/add » dans le path
  • prefix / suffixe : spécifient respectivement un préfixe et un suffixe qui seront ajoutés aux noms de propriétés du bean ActionForm avant de les associer aux noms de paramètre de la requête
  • roles : permet de restreindre l’accès à l’action en indiquant un ensemble de rôle séparée par une virgule.
  • type : spécifie la classe de l’Action.
  • validate : si cette attribut est positionné à false, le contrôleur n’exécute pas la méthode validate() de l’ActionForm

3.8.6.1.Exemple



<action path="/Welcome"
scope="request"
validate=”false”
type="com.society.contactbook.application.actions.WelcomeAction">
<forward name="success" path="home" />
</action>

3.8.7.Controller

Cette balise n’est pas souvent utilisée. Seules les personnes souhaitant modifier le noyau de Struts s’en serviront !
<!ELEMENT controller (set-property*)>
<!ATTLIST controller id ID #IMPLIED>
<!ATTLIST controller bufferSize %Integer; #IMPLIED>
<!ATTLIST controller className %ClassName; #IMPLIED>
<!ATTLIST controller contentType CDATA #IMPLIED>
<!ATTLIST controller forwardPattern CDATA #IMPLIED>
<!ATTLIST controller inputForward %Boolean; #IMPLIED>
<!ATTLIST controller locale %Boolean; #IMPLIED>
<!ATTLIST controller maxFileSize CDATA #IMPLIED>
<!ATTLIST controller memFileSize CDATA #IMPLIED>
<!ATTLIST controller multipartClass %ClassName; #IMPLIED>
<!ATTLIST controller nocache %Boolean; #IMPLIED>
<!ATTLIST controller pagePattern CDATA #IMPLIED>
<!ATTLIST controller processorClass %ClassName; #IMPLIED>
<!ATTLIST controller tempDir CDATA #IMPLIED>
Voici la description de chacun des attributs :
  • bufferSize : permet de modifier la taille du tampon d’entrée lors du traitement de chargement de fichiers
  • maxFileSize : définit la taille maximale du fichier pouvant être chargé et peut être suivi d’un K (kilo), d’un M (méga) ou d’un G (giga)
  • contenType : permet de définir un autre type de contenu par défaut que « text/html »
  • debug : active le débuggage si la valeur est supérieure à 0
  • forwardPattern : permet de modifier la façon dont le chemin d’une application est lié à une URL relative au contexte à l’aide de forwardPattern. La valeur de $A est expansée en préfixe de l’application (/applicationContext par exemple) et celle de $P dans le chemin requis. Par défaut la valeur est $A$P
  • inputForward : positionné à true, les paramètres des attributs input des balises action sont traités comme des transferts et non comme des chemins. C'est-à-dire qu’ils sont comparés aux balises forward définies globalement et localement au lieur d’être traités comme des URI
  • locale : mémorise un locale dans la session de l’utilisateur si ce n’est pas déjà fait. (lorsque cet attribut est positionné à true)
  • nocache : une requête de désactivation de la mise en cache des contenus est envoyée au navigateur client avec chaque réponse HTTP
  • pagePattern : indique à Struts comment relier les pages à l’URL sous-jacente, d’une façon assez semblable à forwardPattern
  • processorClass : remplace la classe « processor de requête » par défaut de Struts par une personnalisée.

3.8.7.1.Exemple

Voici un exemple de balise pouvant être utilisée :
<controller nocache=”true” contentType=”image/jsp”/>

3.8.8.Message-resources

Cette balise vous permet de définir un bundle de ressources pour votre application. Vous pouvez, bien entendu, en définir plusieurs si besoin est.
<!ELEMENT message-resources (set-property*)>
<!ATTLIST message-resources id ID #IMPLIED>
<!ATTLIST message-resources className %ClassName; #IMPLIED>
<!ATTLIST message-resources factory %ClassName; #IMPLIED>
<!ATTLIST message-resources key %AttributeName; #IMPLIED>
<!ATTLIST message-resources null %Boolean; #IMPLIED>
<!ATTLIST message-resources parameter CDATA #REQUIRED>
Voici une description de chacun des attributs :
  • factory : permet de spécifier d’où proviennent les données de la ressource de messages. Par défaut, il est configuré pour lire des fichiers « properties »
  • key : définit une clé pour accéder au bundle.
  • null : permet de spécifier ce qu’il faut faire lorsqu’un message n’est pas trouvé. Si l’attribut est positionné à true, il retourne null. Positionné à false, il retourne un message d’erreur avec la clé érronée.
  • parameter : permet de transmettre un paramètre à la fabrique lorsque le bundle est créé. Pour les fabriques à base de fichiers de propriétés, c’est le chemin du fichier.

3.8.8.1.Exemple

Voici un exemple de configuration d’un bundle :
<message-resources
key=”com.labosun.MAIN_MESSAGES”
parameter=”com.labosun.MainMessages” />
Vous devez avoir un fichier MainMessages.properties dans votre package : com.labosun

3.8.9.Plug-in

Ce dernier élément vous permet de charger dynamiquement des fonctionnalités supplémentaires dans le framework Struts.
<!ELEMENT plug-in (set-property*)>
<!ATTLIST plug-in id ID #IMPLIED>
<!ATTLIST plug-in className %ClassName; #REQUIRED>

Voici une description de chacun des attributs :
  • className : spécifie la classe qui charge le plug-in.
  • set-property : permet de transférer au plug-in les arguments nécessaires à son fonctionnement

3.8.9.1.Exemple

Voici un exemple de configuration du plug-in « validator » :
<plug-in className=”org.apache.struts.validator.ValidatorPlugIn”>
<set-property property=”pathnames”
value=”/WEB-INF/validator-rules.xml”,
”/WEB-INF/validation.xml” />
</plug-in>

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
21 22 23 24 25 26 27 28 

Retrouvez ci-dessous les autres sections du Laboratoire Sun
Exemples de code
JavaManipuler les looks and feel (lister et affecter)10/15/07
JavaFaire sa propre injection de dépendance avec les annotations5/9/06
JavaSplash screen avec progress Bar5/5/06
JavaFaire un splash screen en swing5/5/06

Essentiels de cours Java
JavaEJB 3 - Les Entreprise Java Bean version 3 (JavaBeans)
Cet essentiel est la suite de « Entreprise JavaBean 2.1 ». Cependant, nous allons étudier les nouvelles spécifications 3.0 qui simplifient énormément le développement par rapport aux EJB 2.6/20/06
JavaSWT - Créer des interfaces graphiques performantes
SWT (Standard Widget Toolkit) est une librairie graphique qui vous permet de réaliser des applications graphiques Java beaucoup plus avancées et surtout plus rapide à l’exécution.1/29/06
JavaStruts - Un framework MVC pour vos applications J2EE
Struts est un framework open-source qui vous permet de gagner du temps, mais qui permet aussi de voir des applications complexes comme une suite de composants de base : Vues, Actions, Modèles. Vous gagnez ainsi en évolutivité et en lisibilité du code.1/13/06
JavaHibernate - Persistance objet - relationnel
Cet essentiel explique comment utiliser Hibernate afin de gérer la persistance objet relationnel au sein de vos applications Java.12/14/05
JavaIntroduction J2EE - Applications d'entreprise
Cours d'introduction aux diverses technologies et outils que l'on peut rencontrer dans le monde du Java orienté entreprise J2EE12/14/05
JavaEJB 2 - Les Entreprise Java Bean (JavaBeans)
L'objectif avec EJB2 (Entreprise JavaBeans) est d'introduire les concepts de l’Ingénierie Logicielle Basée sur les Composants.12/14/05
JavaDesign Patern - Améliorez l'architecture de vos programmes
Afin de répondre a des situation récurrentes en programmation, les "design partern" apportent une solution type à beaucoup de contraintes liées à la programmation objet.12/14/05
JavaArchitecture J2EE - Comment organiser son application J2EE
Ce cours explique comment créer un code modulable, lisible et évolutif afin d'assurer la pérénité de son application.12/14/05
JavaLes web-services - Publication de services
Le développement tend vers les technologies du Web. Il est difficile de faire la distinction entre les différents logiciels qui sont de plus en plus intégrés au Web. Les Web Services rentrent dans l’optique de différencier bien précisément les couches.12/14/05
JavaAnt - L'automatisation des tâches du programmeur
Ecrire des scripts afin d'exécuter les tâches récurrentes10/31/05
JavaIntroduction au langage Java - Présentation & historique
Présentation des origines du langage, ainsi que se buts premiers8/11/05
JavaLa Syntaxe Java - Bases & nomenclatures
Bases de la syntaxe du langage Java8/11/05
JavaLes Classes - Concepts & héritage
Base du développement objet en Java grâce aux classes8/11/05
JavaLes Exceptions - Gestion d'erreurs
Gérer les erreurs liés à la programmation8/11/05

Articles
Eclipse Europa : le successeur de Callisto
Après Eclipse Callisto (Eclipse 3.2), la fondation Eclipse sort la nouvelle mouture d'Eclipse appelée Europa (Eclipse 3.3) faisant ainsi passer le nombre de projets embarqués de 10 à 21. Que ceux qui sont réticents aux « distributions » d'Eclipse se rassu12/21/07
JavaCruiseControl : l’outil d’intégration continue à avoir dans sa boite à outils
CruiseControl est un projet open-source offrant de multiples fonctionnalités pour l’intégration, que ce soit pour des développements Java ou .Net. Il est courant sur un projet d’être plusieurs développeurs avec des tâches de développement réparties. Dans7/2/07
JavaEJB3 - Des concepts à l'écriture du code - Editions DUNOD
Consulter le résumé du premier ouvrage du laboratoire Sun de SUPINFO : EJB3 - Des concepts à l'écriture du code. Guide du développeur, éditions DUNOD.5/27/07
JavaPassage de certification Java Web (SCWCD)
Passer une certification est toujours un moment important car cela permet de mieux faire reconnaître ses compétences face à un recruteur ou un employeur.5/12/07
JavaGoogle Web Toolkit
Google Web Toolkit est un framework java pour générer du javascript et des requêtes Ajax à partir d’un code java. Voilà comment il fonctionne.5/10/07
JavaJ2ME Vs SDE
Demain, les terminaux « légers » seront plus nombreux que les ordinateurs personnels, ce qui entraîne une bataille sur le choix d’une plateforme identique à tous ces terminaux… Aujourd’hui nous retrouvons le J2ME ainsi que le SDE qui s’offrent une rude b4/22/07

Tips du laboratoire
EclipseVisual Editor avec Eclipse Europa, c'est possible3/28/08
EclipseGérer les projets dans un workspace.10/16/07
JavaManager votre server d'application avec Eclipse4/21/07
JavaVue des sub-packages avec Eclipse4/21/07
JavaGlisser-déposer avec Eclipse4/21/07

Laboratoire SUPINFO des technologies Sun
labo-sun@supinfo.com


Conditions d'utilisation et © Copyright SUPINFO International University
23, rue de Château Landon - 75010 PARIS - Tél : +33 (0) 153359700 Fax : +33 (0) 153359701
Respect de la vie privée