IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Développer une application Struts à l'aide de NetBeans


précédentsommairesuivant

II. Deuxième partie

II-A. Introduction

Partant de la première partie de ce tutoriel, j'ai ajouté un champ password à la class Bean ActionForm et je l'ai ajoutée au tableau de la page loginForm.jsp. Ensuite, j'ai utilisé l'EDI pour améliorer l'application avec tout un tas de fonctionnalités Struts. Les sections qui suivent montrent comment améliorer l'application en ajoutant les choses suivantes.

II-A-1. Fonctionnalité de validation

II-A-1-a. Syntax-Level

J'ai modifié la classe Bean ActionForm pour vérifier si les champs name et password de la page loginForm.jsp sont remplis. S'ils sont vides, on produit des messages d'erreur que la classe Bean ActionFrom obtient depuis le fichier ApplicationResource.properties.

II-A-1-b. Business-Level

Ajout d'une classe SecurityManager et utilisation de celle-ci dans la classe Action pour vérifier si le nom et le mot de passe entré dans loginForm.jsp sont corrects. Si l'un est incorrect, on produit un message d'erreur que la classe Action obtient depuis le fichier ApplicationResource.properties.

II-A-2. Fonctionnalité d'annulation

Ajout d'un bouton d'annulation à loginForm.jsp. Ajout de la méthode org.apache.struts.action.Action.isCancelled pour que, lorsque le bouton Cancel est enfoncé, une nouvelle page JSP est appelée via struts-config.xml.

II-A-3. Fonctionnalité de déconnexion

Ajout d'un lien 'Déconnection' à loginSuccessful.jsp qui, lorsqu'on clique dessus, appelle une nouvelle page JSP via struts-config.xml.

II-A-4. Fonctionnalité de gestion d'erreurs

Réécriture du code pour le bouton d'Annulation pour que, lorsqu'on clique dessus, une erreur se produit et une nouvelle page JSP soit appelée via struts-config.xml. La nouvelle page JSP affiche un message d'erreur qu'il obtient du fichier ApplicationResource.properties.

II-B. Ce à quoi on veut arriver

Visuellement, c'est ce à quoi l'application ressemble après que les fonctionnalités reprises ci-dessus ont été ajoutées. La première chose que vous voyez est loginForm.jsp, avec les messages d'erreur générés par la classe Bean ActionForm. En fait, je préférais que la méthode validate de la classe Bean ActionForm soit appelée seulement après que j'ai cliqué sur le bouton de Login. Aussi, si quelqu'un sait comment configurer cela, qu'il me le fasse savoir. J'ai contourné le problème en préfixant 'Hint' avant le message d'erreur, pour que l'utilisateur ne finisse pas par voir le mot « erreur » avant même d'avoir fait quelque chose dans l'application. Voici donc à quoi ressemble la première page :

Image non disponible

Du fait que les deux champs sont vides, la classe Bean ActionForm reçoit deux messages d'erreur via le fichier ApplicationResource.properties. Ensuite, si vous n'introduisez qu'un des deux champs (comme illustré ci-dessous), vous aurez toujours un message d'erreur pour le champ vide :

Image non disponible

Ensuite, même si les deux champs sont remplis, vous aurez un nouveau message d'erreur si le nom et le mot de passe ne sont pas remplis correctement (comme illustré ci-dessous) :

Image non disponible

Ce n'est que lorsque le nom et le mot de passe vaudront admin/admin (remarquez que le mot de passe est encrypté), comme illustré ci-dessous…

Image non disponible

… que vous arriverez sur la page loginSuccessful.jsp :

Image non disponible

Ensuite, lorsque vous cliquez sur le lien Logout, loginOut.jsp est affiché :

Image non disponible

Finalement, nous modifions le bouton Annuler pour qu'une java.lang.RuntimeException soit jetée lorsque le bouton Annuler est cliqué. On réimplémente la méthode isCanceled dans la classe Action pour que cela provoque l'appel d'une nouvelle page JSP qui affiche un message d'erreur obtenu depuis le fichier ApplicationResource.properties :

Image non disponible

II-C. Tutoriel

Pour implémenter toutes les fonctionnalités reprises ci-dessus, suivez les étapes décrites ci-dessous.

II-C-1. Ajout de la fonctionnalité de validation au niveau de la syntaxe

Dans Struts, le Bean ActionForm agit comme un lien entre la page JSP et une action Struts. Il capture les entrées de l'utilisateur sur les pages JSP et les passe à l'action. Un Bean ActionForm peut également valider l'entrée avant de le passer à l'action. Aussi, nous voyons ici que le Bean ActionForm vérifie si les champs sont remplis ou pas (notez que le premier champ, name, est créé et validé par défaut lorsque vous utilisez l'assistant New ActionForm Bean dans l'EDI) :

 
Sélectionnez
    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
         ActionErrors errors = new ActionErrors();
         if (getName() == null || getName().length() < 1) {
             errors.add("nameEmpty", new ActionMessage("error.name.required"));
         }
         if (getPassword() == null || getPassword().length() < 1) {
             errors.add("passwordEmpty", new ActionMessage("error.password.required"));
         }
         return errors;
    }

Le fichier ApplicationResource.properties (que l'EDI a créé lorsque vous avez ajouté Struts au projet) contient tous les messages qui doivent être affichés. Deux messages sont créés ci-dessus. Leur texte est trouvé par Struts dans le fichier ApplicationResource.properties, et affiché dans LoginForm.jsp. Ainsi donc, ajoutez ce qui suit au fichier ApplicationResource.properties :

 
Sélectionnez
    error.name.required=Type your name in the Name field.
    error.password.required=Type your password in the Password field.

Et voici comment je les affiche dans loginForm.jsp :

 
Sélectionnez
    <html:errors property="nameEmpty" />
    <html:errors property="passwordEmpty" />

Pour utiliser les tags <html:errors> ci-dessus, vous devez avoir cette directive taglib au début de votre loginForm.jsp :

 
Sélectionnez
    <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>

II-C-2. Ajout de la fonctionnalité de validation au niveau business

Pour la première fois, j'ai vraiment compris la différence entre la validation au niveau syntaxe, et la validation au niveau business. Posez-vous cette question : est-ce que le business pour lequel cette application est créée se soucie du fait que les champs du formulaire d'identification sont vides ou pas ? Je doute que oui ! Mais est-ce qu'ils vont se soucier de savoir si l'utilisateur est capable d'accéder à l'application sans y être autorisé ? Oui, évidemment qu'ils vont s'en soucier. Et bien Struts fait la distinction entre une validation au niveau de la syntaxe et une validation au niveau business. La première est faite par la classe Bean ActionForm, tandis que la seconde est faite par la classe Action. Du fait que la classe Bean ActionForm agit comme une passerelle entre la page JSP et l'action, vous désirerez que la validation de la syntaxe se fasse dans la classe Bean ActionForm, parce que cette classe négocie directement avec la page JSP, alors que l'action non. L'action est plus concernée par les problèmes au niveau business.

J'ai donc ici une classe très simple, appelée SecurityManager :

 
Sélectionnez
    package com.myapp.struts;
    
    public class SecurityManager {
        
        /** Creates a new instance of SecurityManager */
        public SecurityManager() {
        }
        
        public static boolean AuthenticateUser(String name, String password) {
            // Business level authentication - simple check of user name/password = admin/admin
            // TODO: Implement authentication (e.g. use database, etc.)
            return name.equals("admin") && password.equals("admin");
        }
    }

Et dans la méthode execute de la classe Action, j'ai ceci :

 
Sélectionnez
    if (SecurityManager.AuthenticateUser(newStrutsActionForm.getName(),newStrutsActionForm.getPassword())){
       return mapping.findForward(SUCCESS);
    } else {
       return mapping.getInputForward();
    }

Notez que le nom et le mot de passe sont récupérés de la classe Bean ActionForm et authentifiés à l'aide de la classe SecurityManager. Pour être capable d'utiliser la classe ActionForm, vous devez la caster vers le type correct. Faites ceci au début de la méthode execute de la classe Action, comme ceci :

 
Sélectionnez
    NewStrutsActionForm newStrutsActionForm = (NewStrutsActionForm)form;

Aussi, si le nom et le mot de passe récupérés de la classe Bean ActionForm ne sont pas corrects, la page loginForm.jsp est à nouveau affichée (c'est ce que fait getInputForward()). Cependant, l'utilisateur ne sait pas ce qui ne va pas, parce que vous n'avez pas affiché un message d'erreur approprié.

Ajouter ce qui suit juste au-dessus de la ligne return mapping.getInputForward() :

 
Sélectionnez
    ActionMessages errors = new ActionMessages();
    ActionMessage error = new ActionMessage("errors.login.invalid");
    errors.add("loginWrong",error);
    saveErrors(request.getSession(),errors);

Vous voyez ici qu'un nouveau message d'erreur est créé. Il vous faut également aller dans le fichier ApplicationResource.properties et définir le texte à afficher pour l'erreur errors.login.invalid :

 
Sélectionnez
    errors.login.invalid=Wrong name or password. Try again.

Et l'afficher ensuite dans la page loginForm.jsp, juste comme les messages d'erreurs précédents :

 
Sélectionnez
    <html:errors property="loginWrong" />

II-C-3. Ajouter la fonctionnalité d'annulation

Ajouter un bouton d'annulation est quelque chose de très simple dans Struts. Ici, vous voyez le mien, juste en dessous du bouton de soumission (il est mis en évidence dans la copie d'écran) :

Image non disponible

Mais comment spécifier ce qui doit se passer lorsqu'on clique sur le bouton ? Ajouter ceci à la méthode execute de la classe Action :

 
Sélectionnez
    if (isCancelled(request)){
      return mapping.findForward(CANCEL);
    }

Heureusement, la Javadoc de Struts, disponible dans l'EDI vous dit ce que fait le code ci-dessus :

Image non disponible

Maintenant, vous avez besoin de faire correspondre cette variable CANCEL à quelque chose. Au début de la classe Action, ajoutez la ligne suivante juste en dessous de la ligne SUCCESS :

 
Sélectionnez
    private final static String CANCEL = "cancel";

Que devrait-il donc se produire lorsqu'on clique sur le bouton Cancel ? Ajoutez une page JSP appelée loginCancel.jsp et remplacez le texte par défaut entre les tags H1 par 'Login Cancelled!'. Maintenant, allez dans struts-config.xml, cliquez droit n'importe où et choisissez Struts et ensuite Add Forward :

Image non disponible

Dans la boite de dialogue Add Forward, introduisez ceci :

Image non disponible

Lorsque vous cliquez sur Add, vous verrez cette nouvelle ligne dans l'Éditeur de Source :

 
Sélectionnez
    <forward name="cancel" path="/loginCancel.jsp"/>

Maintenant, lorsque l'utilisateur cliquera sur 'Cancel', la méthode isCancelled sera appelée, et le struts-config.xml va faire suivre à (c'est-à-dire afficher) loginCancel.jsp.

II-C-4. Ajouter la fonctionnalité de logout

Dans loginSuccessful.jsp, assurez-vous que la directive taglib HTML de Struts est présente au début de la page (comme pour loginForm.jsp). Ajoutez ensuite ce tag Struts en dessous des tags H1 :

 
Sélectionnez
    <html:link action="/logout" linkName="Log me out">Logout</html:link>

Mais que devrait-il se passer lorsqu'on clique sur ce lien ? Tout d'abord, notez que le lien ci-dessus référence une action appelée logout. Ensuite, créez une page JSP appelée loginOut.jsp et modifier les tags H1 par quelque chose comme Have a nice day!. Maintenant, lorsqu'on clique sur le lien, vous désirez que votre nouvelle page soit ouverte. Aussi, dans struts-config.xml, cliquez droit n'importe où et choisissez Struts > Add Forward/Include Action. Spécifiez ensuite l'action que vous avez référencée dans le lien ainsi que la page JSP que vous aimeriez afficher lorsqu'on clique sur le lien.

Image non disponible

Cliquez sur Add. Notez que vous avez maintenant défini une nouvelle action forward :

 
Sélectionnez
    <action forward="/loginOut.jsp" path="/logout"/>

Le tac ci-dessus lie la page JSP que vous venez de créer avec le lien sur lequel l'utilisateur cliquera dans loginSuccessful.jsp pour se déconnecter de l'application.

II-C-5. Ajouter la Fonctionnalité de Gestion d'erreur

Peu de choses sont aussi déconcertantes pour un utilisateur que de voir un stack trace lorsqu'une java.lang.RuntimeException (ou toute autre exception) se produit. Vous aimeriez réduire le traumatisme causé par l'erreur. Aussi, il serait bien de créer une belle page JSP qui affichera votre erreur et pourquoi pas même quelques pistes pour une solution. Ma page de gestion d'erreur est appelée loginException.jsp. Elle contient la directive taglib pour la bibliothèque Struts HTML, et n'a rien de plus que ce qui suit entre les tags BODY :

Image non disponible

Ainsi, Struts va afficher toutes les erreurs sur cette page. Mais quelles erreurs ? Et comment Struts va les afficher ici ? Premièrement, forçons l'application à créer une erreur (juste pour illustrer notre exemple. Car dans la vie réelle, vous ne devrez pas forcer votre application à créer des erreurs). Retournez à la méthode isCancelled dans la classe Action. Mettez en commentaire le code qui appelle loginCancel.jsp, et remplacez-le par ceci :

 
Sélectionnez
    if (isCancelled(request)){
      throw new java.lang.RuntimeException();
      //return mapping.findForward(CANCEL);
    }

Vous pouvez voir que lorsqu'on cliquera sur le bouton Cancel une RuntimeException sera levée, générant un horrible stack trace à la figure de l'utilisateur. Mais retournons au fichier struts-config.xml, cliquez droit n'importe où et choisissez Struts > Add Exception. Ajoutez les valeurs suivantes dans la boite de dialogue Add Exception :

Image non disponible

Cliquez sur Add. Notez que strusts-config.xml inclut maintenant le tag suivant :

 
Sélectionnez
    <exception key="message.java.lang.RuntimeException" 
                    path="/loginExceptions.jsp" 
                    type="java.lang.RuntimeException"/>

Ajoutons maintenant ce qui suit au fichier ApplicationResource.properties :

 
Sélectionnez
    message.java.lang.RuntimeException=There was a <b><i>java.lang.runtime.exception</i></b>!

Voilà. C'est fait. Lorsque l'utilisateur clique sur le bouton 'Cancel', la java.lang.RuntimeException est levée, le struts-config.xml affiche la page loginException.jsp, et reprend le texte du message d'erreur du fichier ApplicationResource.properties.

II-D. Conclusion

Voilà. Nous avons tout parcouru – validation au niveau de la syntaxe, validation au niveau business, fonctionnalité d'annulation, fonctionnalité de déconnexion et fonctionnalité de gestion d'erreur. Toutes ces fonctionnalités sont très basiques et très peu sophistiquées, mais vous pouvez maintenant imaginer comment la machinerie de Struts fonctionne et comment l'EDI NetBeans 5.0 s'intègre dedans. Un grand merci à Karel Zikmund (qui travaille actuellement pour Microsoft à Seattle) qui – peu de temps avant de quitter l'équipe QE de NetBeans – a créé l'application et les instructions sur lequel ce blog est basé. Karle, tu nous manques!

Laissez-moi un commentaire si vous désirez que l'on continue à traduire les parties suivantes de ce tutoriel.


précédentsommairesuivant

Copyright © 2006 Vincent Brabant. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.