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 = 58409687792501803L;
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 = -8922507342446865665L;
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 coursesVIII-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".











