3. Troisième partie▲
3.1. 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éploieront plus tard). Et nous utiliserons une DataSource Struts pour faire la
connection. 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 seront capable 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
rends disponible. Maintenant, je sais comment...
3.1.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
3.1.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é.
3.1.3. Cacher le mot de passe▲
Lorsqu'on tape un mot de passe, on ne désire pas que quelqu'un regarde pas 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 oeil 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:
3.1.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 fournit 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. A 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 rajouter 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 suis 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 champs 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 quelques 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, Rajoutons 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 rajouter 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:
3.2. Ce à quoi on veut arriver▲
Revenons maintenant à nos DataSources. A 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
3.3. Tutoriel▲
3.3.1. Récupérer le Driver de Base de Données PointBase▲
Quelque 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 trouve 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.
3.3.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 coté, 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:
3.3.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;
}
}
3.3.4. Créer une Action DAO▲
Maintenant, nous devons faire une connection à 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 connection à 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 connection à 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 champs 4 (le nom) et le champs 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éploye 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.
3.3.5. Afficher le résultat▲
En haut de la page JSP, vous devez rajouter 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ée (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 utilitateur/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.
Aussi, deux des meilleurs ressources concernant Struts que j'ai trouvé concernait Struts 1.1 et ... l'EDI NetBeans 3.4! Allez voir par vous-même la partie1 et la partie2. Tout spécialement la partie2, qui fut très utile pour rédiger cet article.