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

| GeertJan Wielenga | Vincent Brabant (Traducteur) |

Ce tutoriel va vous faire découvrir l'ABC de Struts, au travers de l'EDI NetBeans 5.0 qui nous fournit un support Struts « out of the box ».
Un grand merci à GeertJan pour avoir donné son accord pour traduire cet article qui fut publié sur son blog. (cf. Remerciements.)

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

- Auteurs : GeertJan Wielenga, Vincent Brabant (Traducteur)

- Parution : 28 novembre 2005

- Mise à jour : 10 février 2020

- Licence : Copyright ® 2006 Vincent Brabant. Aucune reproduction, même partielle, ne peut être faite de ce site et 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.

Sommaire

- I. Première partie

- I-A. Configuration du projet

- I-B. Création des Pages JSP

- I-C. Création du Bean Struts ActionForm

- I-D. Création de l'Action Struts

- I-E. Exécution du Projet

- II. Deuxième partie

- II-A. Introduction

- II-A-1. Fonctionnalité de validation

- II-A-1-a. Syntax-Level

- II-A-1-b. Business-Level

- II-A-2. Fonctionnalité d'annulation

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

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

- II-B. Ce à quoi on veut arriver

- II-C. Tutoriel

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

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

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

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

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

- II-D. Conclusion

- III. Troisième partie

- III-A. Introduction

- III-A-1. Traduire les boutons

- III-A-2. Ajouter une fonctionnalité de Reset

- III-A-3. Cacher le mot de passe

- III-A-4. Souhaiter la bienvenue à l'utilisateur

- III-B. Ce à quoi on veut arriver

- III-C. Tutoriel

- III-C-1. Récupérer le Driver de base de données PointBase

- III-C-2. Ajouter la DataSource au fichier struts-config.xml

- III-C-3. Ajouter une classe JavaBean

- III-C-4. Créer une Action DAO

- III-C-5. Afficher le résultat

- Remerciements

- Autres Liens

I - Première partie

L'EDI NetBeans 5.0 simplifie Struts. En ne cochant qu'une seule case dans l'assistant New Web Application, toutes les bibliothèques Struts sont ajoutées à votre projet. De plus, vous aurez également le fichier magique struts-config.xml, où vous enregistrez toutes les fonctionnalités de Struts sur lesquelles vous travaillez. Des assistants sont également fournis, pour la création de deux catégories de classes Struts – actionform beans et les actions. Des assistants sont également accessibles depuis le fichier struts-config.xml, pour la génération du code utilisé pour enregistrer les fonctionnalités de Struts.

Voici une procédure toute simple permettant la création d'une application Struts dans l'EDI NetBeans 5.0. Vous utiliserez le framework Struts pour créer une très simple page d'identification :

écran d'identification

Tout le traitement sera fait par Struts (vous découvrirez ce en quoi consiste le traitement dans les étapes décrites ci-dessous). Vous n'allez pas apprendre beaucoup conceptuellement, mais à travers les étapes qui suivent ci-dessous, vous allez vous familiariser avec le framework Struts et la façon dont le support pour le framework a été implémenté dans l'EDI NetBeans 5.0.

I-A - Configuration du projet

Cliquez sur Maj-Ctrl-N. Dans la catégorie Web, choisissez Web Application, et cliquez sur Next. Appelez-la MyVideoStoreApplication. Cliquez sur Next. Sélectionnez Struts 1.2.7 et cliquez sur Add Struts TLD. Cliquez sur Finish.

Voici ce que vous devriez voir, avec le fichier le plus important (le fichier struts-config.xml) sélectionné :

Structure du Projet

I-B - Création des Pages JSP

Cliquez droit sur le nœud du projet MyVideoStoreApplication, choisissez New > JSP et appelez-la loginForm. Cliquez sur Finish. Créez une autre page JSP et appelez-la loginSuccessful. Dans l'Éditeur de Source, remplacez le contenu des tags H1 dans les deux nouveaux fichiers JSP par quelque chose de plus parlant. Par exemple, modifier le texte JSP Page en Login Form et Login Successful! respectivement. Faites de même pour le texte dans les tags TITLE.

Copiez maintenant les deux premières directives du fichier welcomeStruts.jsp en haut de votre nouvelle page loginForm.jsp. Dans loginForm.jsp, en dessous des tags H1, ajoutez ce qui suit :

<html:form action="login">
<html:submit value="Login" />
</html:form>

Il est facile de deviner que tout ce qui se trouve entre les tags html:form est géré par Struts. Notez que tout en tapant, l'EDI vous aide en suggérant différentes façons de compléter le code que vous tapez. Vous avez également accès à la Javadoc Struts.

Code Completion et Javadoc des tags Struts

Dans la Palette de Composant, à droite de l'Éditeur de Source, étendez la section HTML et déposez l'élément Table juste au-dessus de la ligne

<html:submit value="Login" />

La boite de dialogue Insert Table apparait. Assurez-vous que les valeurs de Rows et Columns sont bien sur 1, pour qu'il crée un tableau d'une ligne et une colonne. Cliquez sur OK. Entre les tags TH, introduisez ce qui suit :

<bean:message key="login.name" />

Entre les tags TD, introduisez ce qui suit :

<html:text property="name" />

Ajoutez login.name comme clef au fichier ApplicationResource.properties et ajoutez un message explication. Par exemple :

login.name=Name

Le corps de LoginForm.jsp contient maintenant :

Corps de LoginForm.jsp

I-C - Création du Bean Struts ActionForm

Cliquez droit sur le nœud du projet MyVideostoreApplication et choisissez New > File/Folder. Dans la catégorie Web, choisissez le Bean Struts ActionForm et cliquez sur Next. Sélectionnez com.myapp.struts dans la liste déroulante des package et pressez Finish. Le bean actionform s'ouvre dans l'Éditeur de Source. Ouvrez struts-config.xml dans l'Éditeur de Source et notez qu'il contient, parmi d'autres choses, ce qui suit :

<form-beans>
<form-bean name="NewStrutsActionForm" type="com.myapp.struts.NewStrutsActionForm"/>
</form-beans>

Naviguez maintenant jusque dans le bean actionform dans l'Éditeur de Source et jetez un œil à la méthode validate. Notez qu'un champ nommé name est validé par défaut. Si la validation échoue, ce qui se produit lorsqu'aucun nom n'est introduit dans la page JPS, un message qui est identifié par error.name.required est retourné. Ajoutez error.name.required comme clef dans le fichier ApplicationResource.properties, et ajoutez un message significatif. Par exemple :

error.name.required=Enter a name, banana brain!

Ajoutez maintenant ce qui suit dans le fichier loginForm.jsp, juste au-dessus du tag de clôture </html:form> :

<html:errors />

I-D - Création de l'Action Struts

Cliquez droit sur le nœud du projet MyVideoStoreApplication et choisissez New > File/Folder. Dans la catégorie Web, choisissez l'Action Struts et cliquez sur Next. Sélectionnez com.myapp.struts dans la liste déroulante des packages. Introduisez login dans l'Action Path (le contenu de l'Action Path est donc maintenant /login).Cliquez sur Next. Remarquez que l'EDI suggère que vous associez l'action avec le bean actionform créé dans l'étape précédente. Dans Input Resource, sélectionnez votre page loginForm.jsp. Cliquez sur Finish.

Notez que maintenant, struts-config.xml contient, parmi d'autres choses, ce qui suit :

<action-mappings>
<action input="/loginForm.jsp"
name="NewStrutsActionForm"
path="/login"
scope="session"
type="com.myapp.struts.NewStrutsAction"/>
<action path="/Welcome"
forward="/welcomeStruts.jsp"/>
</action-mappings>

Naviguez jusqu'à l'action et jetez un œil à la méthode execute. Notez que cette action redirige vers la vue résultante appelée success. Vous avez besoin de définir la page loginsuccessfil.jsp comme étant la vue résultante. Ouvrez struts-config.xml dans l'Éditeur de Source, cliquez droit n'importe où et choisissez Struts > Add forward. Introduisez success dans Forward Name. Naviguez jusqu'à la page loginSuccessful.jsp dans Resource File. Cliquez sur Action. Choisissez /login depuis la liste déroulante. Cliquez sur Add. Notez que le fichier struts-config.xml devrait maintenant être semblable à ceci :

<action-mappings>
<action input="/loginForm.jsp"
name="NewStrutsActionForm"
path="/login"
scope="session"
type="com.myapp.struts.NewStrutsAction">
<forward name="success"
path="/loginSuccessful.jsp"/>
</action>
<action path="/Welcome"
forward="/welcomeStruts.jsp"/>
</action-mappings>

I-E - Exécution du Projet

Cliquez droit sur le nœud du projet MyVideoStoreApplication et choisissez Run Project. Le projet déploie et affiche la page loginForm.jsp. Vous devriez voir quelque chose de semblable à ceci :

LoginForm

Lorsque vous introduisez un nom (ou n'importe quoi d'autre, pour autant que ce soit quelque chose), loginSuccessful.jsp est affiché. Une chose intéressante à faire à ce moment est de revenir dans le fichier ApplicationResource.properties. Modifiez les quatre premières clefs par ceci :

errors.header=
errors.prefix=<span style="color: red">
errors.suffix=
errors.footer=

Déployez à nouveau l'application. Si la page loginSuccessful.jsp s'affiche, et que vous ne le désirez pas, modifier l'attribut scope du chemin /login dans struts-config.xml en request au lieu de session. Déployez à nouveau et notez que le message d'erreur a été reformaté.

LoginForm avec message d'erreur

Dans un futur tutoriel, je vais étendre ce scénario pour qu'il fournisse plus de fonctionnalités et qu'il devienne une page de login plus utile.

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 :

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 :

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) :

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…

… que vous arriverez sur la page loginSuccessful.jsp :

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

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 :

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) :

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 :

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 :

<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 :

<%@ 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 :

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 :

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 :

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() :

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 :

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 :

<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) :

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 :

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 :

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 :

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 :

Dans la boite de dialogue Add Forward, introduisez ceci :

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

<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 :

<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.

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

<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 :

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 :

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 :

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

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

Ajoutons maintenant ce qui suit au fichier ApplicationResource.properties :

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.

III - Troisième partie

III-A - Introduction

Dans la première et la deuxième partie de ce tutoriel, nous avons créé une très simple application avec une page d'identification (login page). Mais aucune application n'est constituée que d'une seule page d'identification. Dans cette troisième partie, nous allons créer une application un peu plus réelle. Nous allons afficher des données issues d'une base de données PointBase, qui est incluse dans l'EDI (de plus, le serveur de base de données PointBase est également inclus avec l'EDI, ainsi que le Serveur Web Tomcat que nous déploierons plus tard). Et nous utiliserons une DataSource Struts pour faire la connexion. La chose agréable concernant les datasources Struts est que vous pouvez les utiliser avec n'importe quel serveur – aussi, au lieu de devoir créer un nouveau DataSource par serveur (parce qu'une DataSource est traditionnellement une ressource du serveur et de ce fait chacune est différente, selon le serveur en question), nous allons en créer une dans struts-config.xml et ensuite nous serons capables de redéployer l'application dans une variété de serveurs, pour montrer combien Struts est portable pour faire notre application.
Mais avant de faire tout cela, j'ai trouvé d'autres fonctionnalités que Struts rend disponibles. Maintenant, je sais comment…

III-A-1 - Traduire les boutons

Jusqu'à maintenant, les boutons que je créais ressemblaient à ceci :

<html:submit value="Login" />
<html:cancel/>

Mais il vaut mieux le faire comme ceci :

<html:submit><bean:message key="button.submit" /></html:submit>
<html:cancel><bean:message key="button.cancel" /></html:cancel>

Et maintenant, ajoutez le texte à afficher dans le fichier ApplicationResource.properties :

button.submit=Login
button.cancel=Cancel

III-A-2 - Ajouter une fonctionnalité de Reset

Un bouton Reset est très simple à rajouter :

<html:reset><bean:message key="button.reset" /></html:reset>

Et voici à quoi ressemble maintenant la page loginForm.jsp : Maintenant, lorsqu'on clique sur le bouton Reset, la valeur des champs retourne à la valeur qu'ils contenaient la dernière fois que le bouton Login fut cliqué.

III-A-3 - Cacher le mot de passe

Lorsqu'on tape un mot de passe, on ne désire pas que quelqu'un regarde par-dessus son épaule et voie le mot de passe. De ce fait, des astérisques sont utilisés à la place, comme montré dans l'illustration ci-dessus. Aucun code Java n'est nécessaire pour cela dans Struts. Jetez un œil sur les tags JSP ci-dessous et notez que la propriété name est dans un tag html:text, mais que la propriété password est dans un tag html:password :

III-A-4 - Souhaiter la bienvenue à l'utilisateur

Après avoir fourni un identifiant et un mot de passe valide, l'utilisateur aboutit sur la page loginSuccessful.jsp. Actuellement, tout ce qu'elle contient est un lien 'Logout' (voir les parties précédentes de ce tutoriel). Cependant, vous aimeriez retravailler cette page pour souhaiter la bienvenue à l'utilisateur. Au lieu de fournir un texte générique, style Identification réussie !, vous aimeriez personnaliser et humaniser les choses en disant 'Bienvenue, Ludwig van Beethoven !' (si, bien sûr, le nom de l'utilisateur est bien Ludwig van Beethoven).

Pour réaliser cela, vous avez besoin de récupérer le nom de l'utilisateur de la class Bean ActionForm. À nouveau, c'est la classe qui fait le lien entre la page JSP et la classe Action (c'est vraiment un backing bean). Pour récupérer le nom de l'utilisateur, vous devez tout d'abord ajouter un attribut à l'Action enregistrée dans struts-config.xml. Vous auriez pu faire cela dès le début, lorsque vous avez enregistré cette action. Lorsque vous regardez à l'assistant New Struts Action dans l'EDI, voici les champs que vous verrez :

Si certains de mes collègues voyaient l'écran ci-dessus, ils seraient assez révoltés. Ils diraient quelque chose comme « Comment l'utilisateur peut-il savoir ce que signifie Attribute ? et Parameter ? Nous devrions lui fournir un texte plus user-friendly ». Bien que je sois tout à fait d'accord avec cela, la situation malheureuse est que c'est comme cela qu'ils sont appelés dans le monde Struts. Le champ Attribute génère un attribut appelé attribute. Bien que cela ne soit pas d'une grande aide, c'est comme cela, – et ne rendons pas les choses encore plus confuses en modifiant cela dans l'EDI en quelque chose de plus compréhensible, mais totalement non Struts.

Qu'est-ce donc que le champ Attribut et Parameter ? Actuellement, j'ignore toujours la raison d'être de Parameter, mais je sais quoi à propos d'Attribute. Il met le Bean ActionForm dans le Scope (soit Session, soit Request, selon ce que vous aurez sélectionné dans la boite de dialogue) pour qu'on puisse faire quelque chose d'utile avec les valeurs dans Input Resource. Dans notre cas, l'Input Resource est loginForm.jsp. Nous désirons afficher 'Welcome, Ludwig van Beethoven!' dans loginSuccessful.jsp. Et donc, ajoutons un attribut dans l'enregistrement de l'action du path /login, comme montré ci-dessous :

<action input="/loginForm.jsp"
name="NewStrutsActionForm"
path="/login"
scope="request"
attribute="validlogin"
type="com.myapp.struts.NewStrutsAction">
<forward name="success"
path="/loginSuccessful.jsp"/>
<forward name="cancel"
path="/loginCancel.jsp"/>
<exception key="message.java.lang.RuntimeException"
path="/loginExceptions.jsp"
type="java.lang.RuntimeException"/>
</action>

Maintenant, dans loginSuccessful.jsp, nous pouvons ajouter cette ligne :

<h1>Welcome, <bean:write name="validlogin" property="name"/>!</h1>

Aussi, lorsque loginSuccessful.jsp s'ouvre, la classe Bean ActionForm est appelée dans le scope (c'est-à-dire rendue accessible) via le nom validLogin, et ensuite sa propriété name (c'est-à-dire le nom introduit par l'utilisateur dans la page loginForm.jsp) est affichée sur la page. Par exemple, si l'identification de Ludwig van Beethoven était valide, voici ce que vous verriez à l'écran :

III-B - Ce à quoi on veut arriver

Revenons maintenant à nos DataSources. À la fin de cette partie, vous aurez une DataSource de Struts qui accède à une base de données d'exemple de PointBase et on affichera les résultats dans loginSuccessful.jsp. Vous utiliserez les tags de Struts pour itérer dans le résultat (en d'autres mots, il n'y aura pas de tags JSTL du tout). Votre page loginSuccessful.jsp ressemblera à ceci :

Mais passons maintenant au tutoriel proprement dit.

III-C - Tutoriel

III-C-1 - Récupérer le Driver de base de données PointBase

Quel que soit le serveur que vous désirez utiliser, il aura besoin d'accéder à un driver de base de données PointBase. Pour Tomcat, copier soit pbclient.jar ou pbembeded.jar qui se trouvent dans le répertoire d'installation de PointBase dans le répertoire common/lib du répertoire d'installation de Tomcat. Si vous n'avez pas PointBase, téléchargez Sun Java System Application Server, car il inclut PointBase. Si vous n'avez pas Sun Java System Application Server, téléchargez l'EDI NetBeans, puisque l'une de ces versions inclut Sun Java System Application Server qui inclut PointBase.

III-C-2 - Ajouter la DataSource au fichier struts-config.xml

Voici ma datasource, au tout début de struts-config.xml :

<data-sources>
<data-source type="org.apache.tomcat.dbcp.dbcp.BasicDataSource" key="empTable">
<set-property property="driverClassName" value="com.pointbase.jdbc.jdbcUniversalDriver" />
<set-property property="url" value="jdbc:pointbase://localhost:9092/sample" />
<set-property property="username" value="pbpublic" />
<set-property property="password" value="pbpublic" />
<set-property property="validationQuery" value="SELECT * FROM CUSTOMER_TBL ORDER BY upper(NAME)" />
</data-source>
</data-sources>

Petite remarque : lorsque j'ai essayé de déployer mon application complète sur Sun Java System Application Server and JBoss Application Server, j'ai noté que le serveur ne savait pas comment gérer la DataSource Struts. C'est parce que Tomcat est livré avec toute une série de bibliothèques de classes que les autres serveurs n'incluent pas par défaut. De ce fait, lorsque vous utilisez un autre serveur, vous avez besoin d'autres bibliothèques de classes, comme commons.logging, dans votre classpath (d'un autre côté, Tomcat est parfait pour les applications Web. Pourquoi donc utiliser un serveur d'application lourd pour des applications web Struts relativement simples ?).

Depuis la DataSource, vous pouvez voir quelle base de données nous allons utiliser. Vous pouvez également le voir depuis l'EDI :

III-C-3 - Ajouter une classe JavaBean

Voici un simple POJO qui représente les deux champs ('name' et 'city') que nous désirons afficher :

package com.myapp.struts;

public class row {

/** Creates a new instance of Row */
private String name;
private String city;

/** Creates a new instance of Row */
public row(String name, String city) {
this.name = name;
this.city = city;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

III-C-4 - Créer une Action DAO

Maintenant, nous devons faire une connexion à la base de données via la DataSource. Cela, nous le faisons via une nouvelle action. Tout le code est ci-dessous. La majeure partie du code est un code de connexion à une base de données tout à fait normal. Mais lorsqu'il y avait des choses intéressantes, j'y ai rajouté un commentaire.

package com.myapp.struts;

import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
import java.util.ArrayList;
import javax.sql.*;
import org.apache.struts.Globals;

public class DatasourceConnectionAction extends Action {
private DataSource dataSource;
public ArrayList customerList = new ArrayList();
private final static String SUCCESS = "success";

public ActionForward execute(ActionMapping mapping, ActionForm  form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
HttpSession session = request.getSession();
/** Ici, la méthode qui fait la connexion à la DataSource est appelée: */
customerList = getCustomers() ;
/** Ici, nous mettons le customerList dans le scope, pour pouvoir l'utiliser dans la page JSP: */
if(customerList  != null){
session.setAttribute("allMyCustomers" , customerList);
}
return (mapping.findForward(SUCCESS));
}

private ArrayList getCustomers(){
Connection conn = null;
Statement  stmt = null;
PreparedStatement prpStmt = null;
ResultSet rs = null;
StringBuffer  resultString ;

try{
/** Ici, 'empTable' est associé à la clef de la DataSource dans struts-config.xml: */
dataSource = (DataSource)servlet.getServletContext().getAttribute("empTable");

conn = dataSource.getConnection();
String sqlQuery = "SELECT * FROM CUSTOMER_TBL";
prpStmt = conn.prepareStatement(sqlQuery);
rs = prpStmt.executeQuery();

/** Ici, nous avons mis le champ 4 (le nom) et le champ 7 (la ville) dans la customerList: */
while (rs.next()) {
customerList.add(new row(rs.getString(4), rs.getString(7)));
}
rs.close();

} catch ( SQLException e ) {
System.err.println("SQL Exception occured while accessing the table" );
e.printStackTrace();
return null;

} catch ( Exception e ) {
e.printStackTrace();
return null;
}

return customerList;
}
}

Aussi, pour tester le code ci-dessus, sans devoir passer par loginForm.jsp à chaque fois, j'ai ajouté ce qui suit à l'action-mapping dans struts-config.xml.

<action path="/MyDS" type="com.myapp.struts.DatasourceConnectionAction">
<forward name="success" path="/mydatasourceSuccessful.jsp"/>
</action>

Ensuite, lorsque je déploie l'application (après avoir configuré la page JSP, comme on le verra dans l'étape suivante), je suis capable d'aller directement sur une nouvelle page appelée mydatasourceSuccessful.jsp. (Une autre possibilité aurait été de changer la variable scope en session.)

Aussi, n'oubliez pas de modifier l'enregistrement d'action du path /login dans le fichier struts-config.xml pour que votre nouvelle action (celle ci-dessus, qui se connecte à la DataSource) soit appelée.

III-C-5 - Afficher le résultat

En haut de la page JSP, vous devez ajouter les directives taglib de Struts qui suivent :

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

Ensuite, dans le code, vous devez utiliser le préfixe logic pour itérer sur les clients (customers). Les clients sont exposés du fait d'une partie de code très importante de DataSourceConnectionAction.java.

if(customerList != null){
session.setAttribute("allMyCustomers" , customerList);
}

En utilisant l'attribut allMyCustomers, vous pouvez maintenant travailler dans la page JSP avec les données retournées (une chouette chose avec Struts est que ses tags sont suffisamment descriptifs).

Et voilà ! Maintenant, vous pouvez déployer l'application et, lorsqu'une combinaison valide utilisateur/mot de passe est entrée (voir SecurityManager pour plus de détails, dans la partie 2 de ce tutoriel), l'utilisateur reçoit un message de bienvenue dans loginSuccessful.jsp, et une table est montrée avec les clients issus d'une base de données PointBase d'exemple.

Remerciements

Developpez.com a obtenu la permission de traduire en français le blog de GeertJan. GeertJan est une personne travaillant actuellement pour NetBeans et qui est chargée d'écrire des tutoriels concernant l'EDI NetBeans 5.0. Ce tutoriel n'est que le premier tutoriel d'une longue liste. Si vous ne pouvez attendre, vous pouvez toujours vous rendre sur le blog de GeertJan.

Un merci à vedaer et autres membres de la rédaction pour la relecture du tutoriel.

Un merci particulier à vous, lecteurs, qui avez l'air d'apprécier ce genre de tutoriel.

N'oubliez pas de me faire parvenir vos réactions.

Autres Liens

Ce tutoriel est également disponible au format PDF (miroir HTTP)