3. Les contrôleurs
Notre contrôleur est le point d'entrée dans notre
application. C'est un des premiers modules que nous avons
développé car il a été nécessaire dès
le début de trouver une méthode unifiée pour dispatcher
les requêtes (les pages demandées) des utilisateurs vers les
servlets traitant ces demandes.
Dans le but de nous familiariser avec l'architecture et pour
appréhender son fonctionnement, nous avons décidé de coder
notre propre moteur. Comme dans les frameworks récents, nous avons
développé une servlet unique (architecture de type MVC-2) qui
réceptionne toutes les requêtes et qui, suivant l'uri
demandée, transmet la vue a une classe qui s'occupe de lui renvoyer la
jsp correspondante.
Nous avons choisi de gérer tout le paramétrage dans
un fichier xml nommé config-servlet.xml dont le contenu est de
la forme suivante :
<delegate
id="main"
uri="/main"
jsp="/WEB-INF/vues/main.jsp" spring-id="delegate-main"
default="true" />
Ainsi, chaque page peut posséder son
élément « delegate » qui permet, grâce à
Spring, de charger automatiquement le générateur de vue
approprié pour retourner la page au client. Ce système permet
également d'utiliser le même générateur de vue pour
plusieurs pages.
Ensuite, dans le fichier spring-config-servlet.xml, on
trouve la correspondance entre l'identifiant passé dans
l'élément « delegate » précédent et la
classe à faire instancier à Spring.
10
<bean id=" delegate-main"
class="yaz.ecommerce.controleur.delegate.DelegateMain"/>
Cette classe est l'implémentation d'une interface
(IDelegate) possédant une méthode « process >
appelée par notre contrôleur pour générer la vue a
renvoyer a l'utilisateur
void process( HttpServletRequest
request, HttpServletResponse response,
ServletContext context, ServletConfig config, String
jsp)
throws AccesNonAuthoriseException,
ServletConfigInitialisationException;.
L'intérêt de notre contrôleur est qu'il
permet au générateur de vue de lancer des exceptions
correspondant a la logique métier de notre application. Ainsi, une page
nécessitant que l'utilisateur soit identifié va lancer une
exception de type AccesNonAuthoriseException pour signifier que l'utilisateur
n'a pas le droit d'accéder a cette page. Le contrôleur se chargera
alors de transmettre le traitement à la delegate appropriée pour
ce genre de cas, ce qui au final, enrichie notre contrôleur de nombreuses
possibilités d'extensions.
Nous avons également utilisé le contrôleur
de servlet de Struts pour gérer tous les formulaires présent dans
notre application. Pour ce faire, pour chaque formulaire, nous
définissions dans le fichier struts-config.xml les paramètres
suivant :
<form-beans>
<form-bean
name="formInscription"
type="yaz.ecommerce.formulaire.bean.InscriptionBean" />
<form-beans>
<action
name="formInscription"
path="/inscription"
scope="request"
type="yaz.ecommerce.formulaire.action.InscriptionAction"
validate="true" input="/WEB-INF/vues/inscription.jsp"
parameter="/WEB-INF/vues/main.jsp">
<forward name="success" path="/WEB-INF/vues/main.jsp"/>
</action>
Tout d'abord, on définit le « form-bean >.
L'attribut « name > donne le nom du bean et « type > le bean
étendant ActionForm contenant les membres correspondant aux
éléments du formulaire.
Ensuite, on définit l'action a appliquer une fois le
formulaire validé. On retrouve le paramètre « name >
précédent, pour faire la correspondance entre l'ActionForm
(le bean contenant les données du formulaire) et la classe
Action (la classe contenant les actions à effectuer une fois le
bean correctement rempli). Viennent ensuite l'uri a laquelle on trouve le
formulaire (attribut « path >), la portée dans laquelle sont
transmises les données entre le formulaire et l'ActionForm
(attribut « scope >, pouvant prendre les valeurs de «
application >, « session >, ou « request >), la classe
12
14
Action (propriété « type »), la
demande de valider ou non les données du formulaire en appelant la
fonction validate ,la page vers laquelle rediriger l'utilisateur en
cas d'erreur dans la valorisation de l'ActionForm (attribut «
input ») et enfin un ou plusieurs forwards permettant de déterminer
quelle va être la jsp à afficher.
Ainsi, au bean InscriptionBean correspond le formulaire
suivant :
public class InscriptionBean
extends ActionForm{
private String civilite;
private String nom;
private String prenom;
public String getCivilite(){ return
this.civilite; }
~
<html:form action="/inscription" >
<html:select property="civilite">
<html:option value="Monsieur"></html:option>
<html:option value="Madame"></html:option>
<html:option value="Madamoiselle"></html:option>
</html:select><br/>
<html:text property="nom" maxlength="20"/><br/>
<html:text property="prenom" maxlength="20"/><br/> <html:submit
value="Soumettre" >
<html:reset value="Reset" >
</html:form>
Il est intéressant de noter que dans la jsp, il est
obligatoire d'utiliser les balises de la taglib html de Struts et non pas les
éléments html classiques (input*text+ input*submit+, select,
etc...) afin que le contrôleur de Struts puisse correctement
récupérer les valeurs des champs afin de valoriser les membres
correspondant dans l'ActionForm.
Une fois validées par le client, les données
sont transmises a l'ActionForm qui, avant de rendre la main à la classe
Action, va tenter de vérifier si elles sont bien valides. Dans le cas
contraire, la fonction validate retourne un objet de type
ActionErrors contenant la liste des erreurs et redirige vers la jsp
spécifiée par l'attribut input dans son fichier de configuration.
Ce mécanisme est très puissant et très simple à
utiliser car le framework Struts propose dans sa taglib html un tag
nommé « html:errors » qu'il suffit d'appeler pour afficher la
liste des erreurs.
On l'utilise simplement comme suit :
<div id="inscriptionErreurs"> <html:errors />
</div>
En réalité, en appelant ce tag, le
contrôleur de Struts va analyser le contenu de l'objet
ActionErrors et pour chaque erreur désignée par un
ActionMessage, va aller chercher le code html à afficher
correspondant dans le fichier /classes/erreur.properties.
errors.header=<h1>Erreurs</h1><ul>
errors.footer=</ul>
inscription.nom.vide=<li>Veuillez renseigner votre
nom</li> inscription.nom.long=<li>Le nom ne doit pas excéder
20 caractères</li>
inscription.prenom.vide=<li>Veuillez renseigner votre
prénom</li> inscription.prenom.long=<li>Le prénom ne
doit pas excéder 20 caractères</li>
Ainsi, une erreur dans la saisie générera
automatiquement le code html suivant :
<div id="inscriptionErreurs">
<h1>Erreurs</h1>
<ul>
<li>Veuillez renseigner votre nom</li> </ul>
</div>
De plus, la classe ActionForm possède une
deuxième méthode intéressante, la méthode
reset. Cette méthode est appelée a chaque fois avant que
le formulaire ne soit affiché dans la page web, d'oi son utilisation
pour pré-remplir les champs. Par exemple, nous proposons à nos
utilisateurs une page (/ECommerce/editInfos) leur permettant de
modifier leurs coordonnées personnelles. Dès l'accès a
cette page, et puisqu'ils sont identifiés nous savons qui ils sont, nous
pouvons afficher leurs informations complètes grâce à cette
méthode afin de leur faciliter la saisie. La méthode
reset est également appelée lorsque l'utilisateur clique
sur un bouton de type input*reset+.
|