VIII. MODIFICATION DE DONNEES EN BASE▲
VIII-A. Etape 9 : Modification d'enregistrements dans la base de données▲
VIII-A-1. Intégration de la librairie Commons Collections▲
Décompresser la librairie "commons-collections-3.2.1.jar" de "commons-collections-3.2.1-bin.zip" dans "WEB-INF/lib", afin d'obtenir :
VIII-A-2. Création de la classe de bean▲
Créer une classe "ModifElementCourseBean" dans le package "com.developpez.rpouiller.monapplication".
Saisir le code suivant pour le bean.
package
com.developpez.rpouiller.monapplication;
import
java.io.Serializable;
public
class
ModifElementCourseBean implements
Serializable {
private
static
final
long
serialVersionUID =
58409687792501803
L;
private
Long idObjet;
private
String libelle;
private
String quantite;
public
Long getIdObjet
(
) {
return
idObjet;
}
public
void
setIdObjet
(
Long idObjet) {
this
.idObjet =
idObjet;
}
public
String getLibelle
(
) {
return
libelle;
}
public
void
setLibelle
(
String libelle) {
this
.libelle =
libelle;
}
public
String getQuantite
(
) {
return
quantite;
}
public
void
setQuantite
(
String quantite) {
this
.quantite =
quantite;
}
}
VIII-A-3. Modification de la classe DAO▲
Ajouter la méthode "modifierElementsCourse" dans la classe "ListeCoursesDAO".
/**
* Modifie la liste des éléments passée en paramètre (modification de la quantité seulement)
*
@param
pListeElements
Liste des éléments à modifier
*
@return
Erreur s'il y a lieu
*/
public
String modifierElementsCourse
(
final
List<
ModifElementCourseBean>
pListeElements) {
try
{
final
Context lContext =
new
InitialContext
(
);
final
DataSource lDataSource =
(
DataSource) lContext.lookup
(
NOM_RESOURCE_JDBC);
final
Connection lConnection =
lDataSource.getConnection
(
);
// Modification des enregistrements
for
(
final
ModifElementCourseBean lElement : pListeElements) {
final
PreparedStatement lPreparedStatementCreation =
lConnection.prepareStatement
(
"UPDATE LISTECOURSES SET QUANTITE = ? WHERE IDOBJET = ?"
);
lPreparedStatementCreation.setInt
(
1
, new
Integer
(
lElement.getQuantite
(
)));
lPreparedStatementCreation.setLong
(
2
, lElement.getIdObjet
(
));
lPreparedStatementCreation.executeUpdate
(
);
}
return
null
;
}
catch
(
NamingException e) {
return
"NamingException : "
+
e.getMessage
(
);
}
catch
(
SQLException e) {
return
"SQLException : "
+
e.getMessage
(
);
}
}
VIII-A-4. Création de la classe de formulaire▲
Créer une classe "ModificationListeCoursesForm" dans le package "com.developpez.rpouiller.monapplication".
Saisir le code suivant pour l'action.
package
com.developpez.rpouiller.monapplication;
import
java.util.Iterator;
import
java.util.LinkedList;
import
java.util.List;
import
javax.servlet.http.HttpServletRequest;
import
org.apache.commons.collections.Factory;
import
org.apache.commons.collections.list.LazyList;
import
org.apache.struts.Globals;
import
org.apache.struts.action.ActionErrors;
import
org.apache.struts.action.ActionMapping;
import
org.apache.struts.action.ActionMessage;
import
org.apache.struts.validator.DynaValidatorActionForm;
public
class
ModificationListeCoursesForm extends
DynaValidatorActionForm {
private
static
final
long
serialVersionUID =
-
8922507342446865665
L;
private
static
ModifElementCourseFactory FACTORY_INSTANCE =
new
ModifElementCourseFactory
(
);
private
static
class
ModifElementCourseFactory implements
Factory {
public
Object create
(
) {
return
new
ModifElementCourseBean
(
);
}
}
@Override
public
void
reset
(
ActionMapping pMapping, HttpServletRequest pRequete) {
super
.reset
(
pMapping, pRequete);
final
List<
ModifElementCourseBean>
lListeModification =
new
LinkedList<
ModifElementCourseBean>(
);
final
List<
ModifElementCourseBean>
lListeModificationLazy =
LazyList.decorate
(
lListeModification, FACTORY_INSTANCE);
set
(
"listeCourses"
, lListeModificationLazy);
}
@Override
public
ActionErrors validate
(
ActionMapping pMapping, HttpServletRequest pRequete) {
final
ActionErrors lActionErrors =
super
.validate
(
pMapping, pRequete);
final
List<
ModifElementCourseBean>
lListeModifElementsCourse =
(
List<
ModifElementCourseBean>
)get
(
"listeCourses"
);
final
Iterator<
ModifElementCourseBean>
lIteratorModifElementsCourse =
lListeModifElementsCourse.iterator
(
);
while
(
lIteratorModifElementsCourse.hasNext
(
)) {
final
ModifElementCourseBean lElementCourse =
lIteratorModifElementsCourse.next
(
);
final
Long lIdObjet =
lElementCourse.getIdObjet
(
);
final
String lQuantite =
lElementCourse.getQuantite
(
);
if
(
lQuantite ==
null
||
""
.equals
(
lQuantite)) {
final
ActionMessage lActionMessage =
new
ActionMessage
(
"modification.quantite.nonrenseigne.erreur"
, lIdObjet);
lActionErrors.add
(
Globals.ERROR_KEY, lActionMessage);
}
else
{
try
{
final
Integer lQuantiteInt =
new
Integer
(
lQuantite);
if
(
lQuantiteInt <=
0
) {
final
ActionMessage lActionMessage =
new
ActionMessage
(
"modification.quantite.nonpositif.erreur"
, lIdObjet);
lActionErrors.add
(
Globals.ERROR_KEY, lActionMessage);
}
}
catch
(
NumberFormatException e) {
final
ActionMessage lActionMessage =
new
ActionMessage
(
"modification.quantite.nonnumerique.erreur"
, lIdObjet);
lActionErrors.add
(
Globals.ERROR_KEY, lActionMessage);
}
}
}
return
lActionErrors;
}
}
VIII-A-5. Modification du fichier d'internationalisation▲
Ajouter les lignes suivantes dans le fichier "Resources.properties".
modification.quantite.nonrenseigne.erreur
=La quantité de l'objet avec l'id {0}
n'est pas renseigné.
modification.quantite.nonnumerique.erreur
=La quantité de l'objet avec l'id {0}
n'est pas au format numérique.
modification.quantite.nonpositif.erreur
=La quantité de l'objet avec l'id {0}
n'est pas strictement positif.
VIII-A-6. Création de la classe Action d'affichage▲
Créer une classe "AfficherModificationListeCoursesAction" dans le package "com.developpez.rpouiller.monapplication".
Saisir le code suivant pour l'action.
package
com.developpez.rpouiller.monapplication;
import
java.util.LinkedList;
import
java.util.List;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.apache.struts.Globals;
import
org.apache.struts.action.Action;
import
org.apache.struts.action.ActionForm;
import
org.apache.struts.action.ActionForward;
import
org.apache.struts.action.ActionMapping;
import
org.apache.struts.action.ActionMessage;
import
org.apache.struts.action.ActionMessages;
public
class
AfficherModificationListeCoursesAction extends
Action {
public
ActionForward execute
(
final
ActionMapping pMapping,
ActionForm pForm, final
HttpServletRequest pRequete,
final
HttpServletResponse pReponse) {
// Récupère les informations dans la base
final
ListeCoursesDAO lListeCoursesDAO =
new
ListeCoursesDAO
(
);
final
RetourRechercherBean lRetourRechercher =
lListeCoursesDAO.rechercherElementsCourses
(
);
// Transforme la liste de bean ElementCourseBean en ModifElementCourseBean
final
List<
ModifElementCourseBean>
lListeCoursesConvertie =
new
LinkedList<
ModifElementCourseBean>(
);
for
(
final
ElementCourseBean lElementCourse : lRetourRechercher.getListeCourses
(
)) {
final
ModifElementCourseBean lModifElementCourse =
new
ModifElementCourseBean
(
);
lModifElementCourse.setIdObjet
(
lElementCourse.getIdObjet
(
));
lModifElementCourse.setLibelle
(
lElementCourse.getLibelle
(
));
lModifElementCourse.setQuantite
(
lElementCourse.getQuantite
(
).toString
(
));
lListeCoursesConvertie.add
(
lModifElementCourse);
}
// Stocke les informations dans le formulaire
final
ModificationListeCoursesForm lForm =
(
ModificationListeCoursesForm)pForm;
lForm.set
(
"listeCourses"
, lListeCoursesConvertie);
if
(
lRetourRechercher.getErreur
(
) ==
null
) {
// S'il n'y a pas d'erreurs, on retourne le forward "succes"
return
pMapping.findForward
(
"succes"
);
}
else
{
final
ActionMessages lErreurs =
getErrors
(
pRequete);
final
ActionMessage lActionMessage =
new
ActionMessage
(
lRetourRechercher.getErreur
(
), false
);
lErreurs.add
(
Globals.ERROR_KEY, lActionMessage);
saveErrors
(
pRequete, lErreurs);
// S'il y a des erreurs, on retourne le forward "erreur"
return
pMapping.findForward
(
"erreur"
);
}
}
}
VIII-A-7. Création de la classe Action de modification▲
Créer une classe "ModifierModificationListeCoursesAction" dans le package "com.developpez.rpouiller.monapplication".
Saisir le code suivant pour l'action.
package
com.developpez.rpouiller.monapplication;
import
java.util.List;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.apache.struts.Globals;
import
org.apache.struts.action.Action;
import
org.apache.struts.action.ActionForm;
import
org.apache.struts.action.ActionForward;
import
org.apache.struts.action.ActionMapping;
import
org.apache.struts.action.ActionMessage;
import
org.apache.struts.action.ActionMessages;
public
class
ModifierModificationListeCoursesAction extends
Action {
public
ActionForward execute
(
final
ActionMapping pMapping,
ActionForm pForm, final
HttpServletRequest pRequete,
final
HttpServletResponse pReponse) {
// Récupère les informations du formulaire
final
ModificationListeCoursesForm lForm =
(
ModificationListeCoursesForm)pForm;
final
List<
ModifElementCourseBean>
lListeCourses =
(
List<
ModifElementCourseBean>
)lForm.get
(
"listeCourses"
);
// Création en base du nouvel enregistrement
final
ListeCoursesDAO lListeCoursesDAO =
new
ListeCoursesDAO
(
);
final
String lErreur =
lListeCoursesDAO.modifierElementsCourse
(
lListeCourses);
if
(
lErreur ==
null
) {
// S'il n'y a pas d'erreurs, on retourne le forward "succes"
return
pMapping.findForward
(
"succes"
);
}
else
{
final
ActionMessages lErreurs =
getErrors
(
pRequete);
final
ActionMessage lActionMessage =
new
ActionMessage
(
lErreur, false
);
lErreurs.add
(
Globals.ERROR_KEY, lActionMessage);
saveErrors
(
pRequete, lErreurs);
// S'il y a des erreurs, on retourne le forward "erreur"
return
pMapping.findForward
(
"erreur"
);
}
}
}
VIII-A-8. Création du fichier d'internationalisation▲
Créer un nouveau fichier d'internationalisation dans le dossier "src"/"com"/"developpez"/"rpouiller"/"monapplication" sous le nom "ResourcesModification.properties".
Remplir le fichier "ResourcesModification.properties" avec :
titre.modification.elementcourses
=Modification d'élément de la liste de courses
VIII-A-9. Création du fichier de configuration "struts-config-modification.xml"▲
Créer un fichier XML "struts-config-modification.xml" dans "WebContent/WEB-INF".
Remplir le fichier "struts-config-modification.xml" avec :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd"
>
<struts-config>
<!-- ========== Formulaire ============================== -->
<form-beans>
<form-bean
name
=
"modificationForm"
type
=
"com.developpez.rpouiller.monapplication.ModificationListeCoursesForm"
>
<form-property
name
=
"listeCourses"
type
=
"java.util.List"
/>
</form-bean>
</form-beans>
<!-- ========== Mapping des actions ============================== -->
<action-mappings>
<action path
=
"/AfficherModificationListeCourses"
name
=
"modificationForm"
type
=
"com.developpez.rpouiller.monapplication.AfficherModificationListeCoursesAction"
scope
=
"request"
validate
=
"false"
attribute
=
"bean"
>
<forward
name
=
"succes"
path
=
"/pages/modification.jsp"
/>
<forward
name
=
"erreur"
path
=
"/pages/erreur.jsp"
/>
</action>
<action path
=
"/ModifierModificationListeCourses"
name
=
"modificationForm"
type
=
"com.developpez.rpouiller.monapplication.ModifierModificationListeCoursesAction"
scope
=
"request"
validate
=
"true"
attribute
=
"bean"
input
=
"/pages/modification.jsp"
>
<forward
name
=
"succes"
path
=
"/AfficherModificationListeCourses.do"
/>
<forward
name
=
"erreur"
path
=
"/pages/erreur.jsp"
/>
</action>
</action-mappings>
<!-- ========== Ressources de definitions de messages =========================== -->
<message-resources
parameter
=
"com.developpez.rpouiller.monapplication.ResourcesModification"
key
=
"modification"
/>
</struts-config>
VIII-A-10. Modification du fichier "web.xml"▲
Modidier la déclaration du paramétrage de la servlet "org.apache.struts.action.ActionServlet" dans le fichier "web.xml".
<!-- Configuration de l'action servlet -->
<servlet>
<servlet-name>
action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>
config</param-name>
<param-value>
/WEB-INF/struts-config.xml,
/WEB-INF/struts-config-creation.xml,
/WEB-INF/struts-config-suppression.xml,
/WEB-INF/struts-config-modification.xml
</param-value>
</init-param>
<load-on-startup>
1</load-on-startup>
</servlet>
VIII-A-11. Création de la JSP de modification▲
Créer une JSP "modification.jsp" dans "pages".
Remplir "modification.jsp" avec :
<%@
page
language
=
"java"
contentType
=
"text/html; charset=ISO-8859-1"
pageEncoding=
"ISO-8859-1"
%>
<%@
taglib
prefix
=
"html"
uri
=
"http://struts.apache.org/tags-html"
%>
<%@
taglib
prefix
=
"bean"
uri
=
"http://struts.apache.org/tags-bean"
%>
<%@
taglib
prefix
=
"logic"
uri
=
"http://struts.apache.org/tags-logic"
%>
<%@
taglib
prefix
=
"nested"
uri
=
"http://struts.apache.org/tags-nested"
%>
<html
:
html
>
<head>
<title><bean
:
message
key=
"titre.modification.elementcourses"
bundle=
"modification"
/></title>
</head>
<body>
<b><i><html
:
errors
/></i></b><br/>
<html
:
form
action=
"/ModifierModificationListeCourses.do"
>
<table border=
"1"
>
<thead>
<tr>
<th><bean
:
message
key=
"colonne.identifiant"
/></th>
<th><bean
:
message
key=
"colonne.libelle"
/></th>
<th><bean
:
message
key=
"colonne.quantite"
/></th>
</tr>
</thead>
<tbody>
<nested
:
iterate
id=
"elementCourse"
property=
"listeCourses"
type=
"com.developpez.rpouiller.monapplication.ModifElementCourseBean"
>
<tr>
<td>
<nested
:
write
property=
"idObjet"
/>
<nested
:
hidden
property=
"idObjet"
/>
</td>
<td>
<nested
:
write
property=
"libelle"
/>
<nested
:
hidden
property=
"libelle"
/>
</td>
<td>
<nested
:
text
property=
"quantite"
/>
</td>
</tr>
</nested
:
iterate
>
</tbody>
</table>
<html
:
submit
/>
</html
:
form
>
</body>
</html
:
html
>
VIII-A-12. Déploiement de l'application▲
Si le serveur est à l'état "Restart" (Il faut qu'il soit à l'état "Synchronized") : Sélectionner le serveur Tomcat dans la vue "Servers". Faire un clic droit sur le serveur Tomcat. Puis sélectionner "Restart".
Ouvrir un navigateur web à l'adresse : http://localhost:8080/MonApplication/AfficherModificationListeCourses.do.
VIII-A-13. Vérification▲
L'application doit vérifier que les champs "quantite" sont renseignés.
L'application doit vérifier que les champs "quantite" est bien numérique.
L'application doit vérifier que les champs "quantite" est bien strictement positifs.
L'application doit stocker les nouvelles quantités et l'afficher ensuite.
VIII-B. Fonctionnement de l'ensemble▲
Au démarrage de l'application, la modification du fichier "web.xml" indique que la servlet "org.apache.struts.action.ActionServlet" est initialisée par quatre fichiers de configuration.
Le fichier "struts-config-modification.xml" déclare deux actions (une d'affichage et une de modification) et un formulaire. Ces deux actions ont le même formulaire. Le formulaire correspond à une classe définie dans l'application.
Lors de l'appel "http://localhost:8080/MonApplication/AfficherModificationListeCourses.do", la servlet "org.apache.struts.action.ActionServlet" est exécutée (url terminée par ".do"). Elle utilise le mapping des actions contenues dans "struts-config-modification.xml", pour appeler l'action "com.developpez.rpouiller.monapplication.AfficherModificationListeCoursesAction".
L'action appelle la DAO afin d'obtenir la liste des enregistrements contenus en base. Elle modifie la liste : elle transforme les quantités d'un format numérique vers un format chaine de caratères. Elle stocke la liste modifiée des enregistrements dans le "formulaire". Si tout s'est bien passé, elle demande de forwarder vers le mapping "succes" ("/pages/modification.jsp"). Ou en cas d'erreur, elle demande de forwarder vers le mapping "erreur" ("/pages/erreur.jsp").
La DAO "ListeCoursesDAO" utilise la ressource JDBC pour accéder à la base. Elle fournit une méthode retournant les informations contenues dans la table "LISTECOURSES".
La JSP "/pages/modification.jsp" affiche un tableau avec les valeurs contenues dans le formulaire. Chaque ligne du tableau comporte un champ de saisie pour la quantité. L'identifiant et le libellé de chaque objet est conservé dans le formulaire grâce au tag "nested:hidden". Le tag "nested:write" permet d'afficher ces valeurs. Le tag "nested:text" permet de modifier la quantité de chaque objet.
La JSP "/pages/erreur.jsp" affiche les erreurs stockées dans la requête.
Lors du clic sur le bouton "Submit", le formulaire est soumis au serveur.
Le formulaire "com.developpez.rpouiller.monapplication.ModificationListeCoursesForm" initialise la liste avec une "LazyList" afin de recevoir les informations du formulaire HTML. Ensuite, le formulaire est validé grâce à la méthode de validation définie dans la classe.
En cas d'erreur dans la validation, les messages d'erreur sont stockés dans la requête et l'application forwarde vers l'action d'affichage.
En cas de validation réussie, l'action de modification "com.developpez.rpouiller.monapplication.ModifierModificationListeCoursesAction" est exécutée. Elle récupère la liste des éléments depuis le formulaire. Elle demande à la DAO de modifier les éléments. Si tout s'est bien passé, elle demande de forwarder vers le mapping "succes" (action d'affichage). Ou en cas d'erreur, elle demande de forwarder vers le mapping "erreur" ("/pages/erreur.jsp").
La méthode "modifierElementsCourse" de la DAO "ListeCoursesDAO" modifie les enregistrements dans la table "LISTECOURSES".