0% ont trouvé ce document utile (0 vote)
23 vues68 pages

Slides MVC

Le document présente l'architecture logicielle MVC pour une application de vente de produits en ligne, en détaillant la séparation des préoccupations entre le modèle, la vue et le contrôleur. Il aborde les problèmes de l'architecture initiale, tels que la complexité du code et la difficulté de maintenance, et propose des solutions via l'architecture MVC. Enfin, il introduit le framework Struts pour faciliter le développement d'applications MVC en simplifiant la gestion des actions et des formulaires.

Transféré par

sef.epanya
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
23 vues68 pages

Slides MVC

Le document présente l'architecture logicielle MVC pour une application de vente de produits en ligne, en détaillant la séparation des préoccupations entre le modèle, la vue et le contrôleur. Il aborde les problèmes de l'architecture initiale, tels que la complexité du code et la difficulté de maintenance, et propose des solutions via l'architecture MVC. Enfin, il introduit le framework Struts pour faciliter le développement d'applications MVC en simplifiant la gestion des actions et des formulaires.

Transféré par

sef.epanya
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

A

Architecture logicielle MVC

TPI P. Reignier
Exemple d’application multi-présentation

• Vente de produits en ligne

– Panier

– Facture HTML

– Facture PDF

TPI P. Reignier

A.1
Architecture initiale

• Partie Facturation

• Pas de séparation Présentation-Contenu


– Une servlet pour la facture (aurait pu être une page JSP)
– Une servlet pour la facture PDF

TPI P. Reignier

A.2
Facture

HttpSession session = request.getSession(true) ;


Vector panier = (Vector) session.getAttribute("panier") ;
......
for (int i=0; i<panier.size(); i++) {
int refId = ((Integer) panier.get(i)).intValue() ;

ResultSet result = stmt.executeQuery("select * from produits where id="+refId) ;


result.next() ;

String description = result.getString(2) ;


int prix = result.getInt(3) ;

out.println("<tr>") ;
out.println("<td>&nbsp " + description +" &nbsp</td><td>" + prix + "</td>") ;
prixTotal += prix ;
out.println("</tr>") ;
}
....
out.println("<h3>Prix total : " + prixTotal + " Euros</h2>") ;

TPI P. Reignier

A.3
Facture PDF

HttpSession session = request.getSession(true) ;


Vector panier = (Vector) session.getAttribute("panier") ;

Paragraph titre = new Paragraph(...) ;


...
int prixTotal = 0 ;
PdfPTable table = new PdfPTable(2) ;

table.addCell(new Paragraph(...)) ;
.....
for (int i=0; i<panier.size(); i++) {
int refId = ((Integer) panier.get(i)).intValue() ;

ResultSet result = stmt.executeQuery("select * from produits where id="+refId) ;


result.next() ;

String description = result.getString(2) ;


int prix = result.getInt(3) ;

table.addCell(" " + description+" ") ;


table.addCell(" " + prix+ " Euros") ;
prixTotal += prix ;

TPI P. Reignier

A.4
Servlet (2)

• Mélange des trois aspects : analyse, calcul, présentation

• Complexité du code

• Duplication :
– des accès à la base de données
– de la logique (calcul de la somme totale).

• Difficulté de maintenance

• Peu de possibilités d’évolution (en particulier pour la présentation)

TPI P. Reignier

A.5
Architecture MVC

• Séparation des trois aspects en unités (classes ?) distinctes


– Pouvoir modifier un des aspects sans toucher aux autres

• Modèle, Vue, Contrôle :


– Contrôle :
∗ décodage du formulaire,
∗ mise en place du calcul.
∗ mise en place de la présentation.
– Modèle : calcul
– Vue : présentation du résultat.

TPI P. Reignier

A.6
Architecture MVC (2)

TPI P. Reignier

A.7
Contrôle
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
//----------------------------------------------------------------------
// Analyse de la requête HTTP
//----------------------------------------------------------------------
matiere = request.getParameter("matiere") ;
.....
//----------------------------------------------------------------------
// Construction du modèle
//----------------------------------------------------------------------
......
//----------------------------------------------------------------------
// Génération de la présentation
//----------------------------------------------------------------------
try {
getServletContext().
getRequestDispatcher("/tableau.jsp").forward(request, response);
} catch (Exception e)
{
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"erreur à la création de la présentation tableau") ;
return ;
}
}
TPI P. Reignier

A.8
Modèle

• Ensemble de classes Java :


– Encapsulent l’ensemble des traitements (accès BD . . . )
– Objets construits par le contrôle.
– Interrogés par la vue.

• Variable de session ou de requête

TPI P. Reignier

A.9
Exemple de modèle

Facture
-conn: Connection
-stmt: Statement
-produits = Vector
-prixTotal: int
-nbProduits: int
+Facture()
+setIds(panier:Vector)
+getNbProduits(): int
+getProduit(id:int): Produit
+getPrixTotal(): int

TPI P. Reignier

A.10
Construction du modèle (variable de session)

Facture facture = null ;


HttpSession session = request.getSession(true) ;
facture = (Facture) session.getAttribute("facture") ;
if (facture == null)
// on cree le modele et on l’enregistre dans la session courante
{
facture = new Facture() ;
session.setAttribute("facture", facture) ;
}

TPI P. Reignier

A.11
Construction du modèle (variable de requête)

Facture facture = new Facture() ;


request.setAttribute("facture", facture) ;

TPI P. Reignier

A.12
Construction du modèle (2)

try {
facture.setIds(panier) ;
} catch (SQLException e)
{
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
e.getMessage()) ;
}

TPI P. Reignier

A.13
Vue

<html>
<body>
<jsp:useBean id="facture" scope="session" class="model.Facture" />
....
<table border>
<tr><th>Produit</th><th>Prix</th></tr>
<% for (int i=0; i<facture.getNbProduits(); i++)
{ %>
<tr><td><%=facture.getProduit(i).getDescription()%></td>
<td><%=facture.getProduit(i).getPrix()%></td>
</tr>
<%}%>
</table>
</center>

<p>
Prix total : <%=facture.getPrixTotal()%>
</body>
</html>

TPI P. Reignier

A.14
Remarque

• Mélange de code et de balises HTML

• Rappel :
– JSP = écriture de balises
– Génération automatique du code java de la servlet
⇒ écrire le moins de code soi-même.
– Remarque : toute la partie traitement et SQL n’est déjà plus là.

TPI P. Reignier

A.15
Tags JSP

• Récupération du modèle depuis la session :

HttpSession session = request.getSession(true) ;


Facture facture = (Facture) session.getAttribute("facture") ;
Devient :

<jsp:useBean id="facture" class="model.Facture" scope="session"/>

TPI P. Reignier

A.16
Tags JSP (2)

• Récupération du modèle depuis la requête :

Facture facture = (Facture) request.getAttribute("facture") ;


Devient :

<jsp:useBean id="facture" class="model.Facture" scope="request"/>

TPI P. Reignier

A.17
Tags JSP (3)

• Utilisation des java beans


• Accès aux attributs de l’objet :

<%= facture.getNbProduits() %>


Devient :

<jsp:getProperty name="facture" property="nbProduits"/>

• Possibilité d’utiliser des bibliothèques de Tags.

TPI P. Reignier

A.18
Conclusion

• Séparation claire des rôles

• Comparaison avec XML - XSLT :


– XML : structure des données = structure du fichier XML
– MVC : structure des données = structure des classes Java

TPI P. Reignier

A.19
B
Struts

TPI P. Reignier
Motivations

• Développement d’une application MVC :

– Architecture nécessaire mais ”un peu” lourde

– Aide à la mise en oeuvre.

⇒ Support d’un Framework

TPI P. Reignier

B.1
Modèle

• Modèle : très fortement couplé aux données

• Fait très souvent appel à une base de données.

• Ensemble de classes Java reflètant la structure de données :


– Note, Etudiant, . . .

• Pont entre ces classes et leur représentation dans le base de données :


– NoteDAO, EtudiantDAO, . . .

• Framework de mapping Object ↔ Relationnel (Hibernate, iBatis etc)

TPI P. Reignier

B.2
Vue

• Utilisation de mécanismes communs à un grand nombre d’applications


– Accès à des variables de session ou de requête
– Accès aux attributs de ces variables
– Parcours de listes
– etc

⇒ Utilisation de bibliothèques de Tags :


– JSTL (JavaServer Pages Standard Tag Library)
– http://java.sun.com/products/jsp/jstl/index.jsp

TPI P. Reignier

B.3
Motivations (suite)

• Vérification des champs d’un formulaire

• Gestion des valeurs dans les zones de saisies


– Affichage d’un formulaire pour mise à jour de données.
– Ré-affichage d’un formulaire suite à une erreur de saisie.

⇒ Struts.

TPI P. Reignier

B.4
B1 - Concepts

TPI P. Reignier
Présentation générale

• Struts = Servlet :
– ensemble de jars à déposer dans WEB-INF/lib

• Prise en charge d’une partie des URLs (*.do)

• Laisse le container gérer les autres (6= Cocoon)

TPI P. Reignier

B.6
web.xml

</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</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

TPI P. Reignier

B.7
Concepts (suite)

• Deux grandes catégories de classes :


– Action : Contrôleur générique
– ActionForm : Représentation ”objet” :
∗ du contenu d’un formulaire.
∗ des paramètres d’une requête.

• Un fichier de configuration :
– Décrit l’enchaı̂nement des pages
– struts-config.xml

TPI P. Reignier

B.8
B2 - Actions

TPI P. Reignier
Première exemple : pas d’action

• Passage par le contrôleur de Struts

• Redirection vers une page JSP


• struts-config.xml :

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC


"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>
<action-mappings>
<action path="/test" forward="/hello.jsp"/>
</action-mappings>
</struts-config>

TPI P. Reignier

B.10
Première Action

• Association URL ⇔ Contrôleur

• Présentation en fonction de la valeur retournée par le Contrôleur

• Contrôleur :
– Dérive de la classe Action
– Redéfinit la méthode execute

TPI P. Reignier

B.11
MonControleur

public class MonControleur extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form,


HttpServletRequest request,
HttpServletResponse response)
throws Exception {

Date date = java.util.Calendar.getInstance().getTime() ;

if (date.getHours() < 12)


return mapping.findForward("matin") ;
else
return mapping.findForward("soir") ;
}
}

TPI P. Reignier

B.12
struts-config.xml

<struts-config>

<action-mappings>
<action path="/go" type="MonControleur">
<forward name="soir" path="/bonsoir.jsp"/>
<forward name="matin" path="/bonjour.jsp"/>
</action>
</action-mappings>

</struts-config>

TPI P. Reignier

B.13
Remarque

• Redéfinition de la méthode execute

⇒ un object par type d’action

• Exemple : gestion d’une boutique


– Ajout d’un article
– Suppression d’un article
– Modification du prix d’un article
⇒ trois classes : AddArticle, RemoveArticle, UpdateArticle

TPI P. Reignier

B.14
Remarque (suite)

• Eviter la multiplication des classes

• Une classe Article


– Une méthode par type d’action.
⇒ DispatchAction.

• Choix de la méthode :
– Un paramètre de l’URL.

TPI P. Reignier

B.15
Exemple

• Un contrôleur avec deux méthodes.

• Le contrôleur forward vers une seule JSP

• Transmission d’une chaı̂ne de caractère entre le controleur et la JSP :


– Permet d’identifier la méthode par laquelle on est passé.
– Transmission par la requête.

TPI P. Reignier

B.16
MonControleur

public class MonControleur extends DispatchAction {


public ActionForward methode1(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
{
String data = "Je suis passe par methode 1" ;
request.setAttribute("data", data) ;
return mapping.findForward("success") ;
}

public ActionForward methode2(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
{
String data = "Je suis passe par methode 2" ;
request.setAttribute("data", data) ;
return mapping.findForward("success") ;
}
}

TPI P. Reignier

B.17
La page JSP

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Affichage</title>
</head>
<body>

<h1>Resultat</h1>

<p>
<jsp:useBean id="data" scope="request" type="String"/>

Valeur transmise par la requete : <%= data %>


</body>
</html>

TPI P. Reignier

B.18
strut-config.xml

• Lien entre le Contrôleur et la JSP


<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC


"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>

<action-mappings>
<action path="/go" parameter="choix" type="MonControleur">
<forward name="success" path="/affichage.jsp"/>
</action>
</action-mappings>

</struts-config>

TPI P. Reignier

B.19
B3 - Présentation

TPI P. Reignier
Concepts

• Simplifier l’écriture des pages JSP

• Minimiser l’écriture de code Java

• Plusieurs aspects :
– Accès aux variables (session, requête)
– Parcours de listes
– Internationalisation
⇒ JSTL (ne fait pas partie de Struts)
– Gestion des formulaires (valeurs par défaut)
⇒ HTML (Struts)

TPI P. Reignier

B.21
i18n

• Principe :
– Code de langue : 2 lettres en minuscule (ex: fr, en)
– Ressources : un fichier par langue (suffixé par le code langue) con-
tenant des associations clé ⇔ texte correspondant

• Déclaration des ressources :


– web.xml :
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>MessageResources</param-value>
</context-param>

– struts-config.xml :
<message-resources parameter="MessageResources" null="false"/>

• Création des fichiers MessageResources_fr . . . à la racine des sources


TPI P. Reignier

B.22
Principe

• MessageRessource fr :

#-- titles --
title.welcome=Essai de I18N

#-- messages
message.welcome=Bonjour

• Balises JSP :
– <fmt:message key=".."/> : fournit le message
– <fmt:setLocale value=".."/> : fixe la langue par défaut si la
langue demandée n’est pas fournie.

TPI P. Reignier

B.23
Hello.jsp

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">

<fmt:setLocale value="en"/>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1 align="center"><fmt:message key="title.welcome"/></h1>
<fmt:message key="message.welcome"/>
</body>
</html>

TPI P. Reignier

B.24
Accès aux variables

• JSTL = ensemble de tag libs

• Possibilité d’utiliser des objets Java en paramètres de ces tags


– Objets transmis dans la session ou la requête
– Instances référencées par un nom symbolique.

• Accès par la notation ${nomDeLobjet}

• Accès aux attributs de l’objet (JavaBeans)


${objet.attribut}

TPI P. Reignier

B.25
Exemple de tags

<c:out value="${...}"/>

• affiche dans la page la valeur de la variable

<c:forEach var="..." items="${..}" />


.....
</c:forEach>

• Parcours la variable définit dans items (variable de type Collection).

• Les valeurs successives sont affectées à la variable définie dans var.

TPI P. Reignier

B.26
Exemple de tags (suite)

<c:url var=".." scope=".." value=".."/>


<c:param name=".." value=".."/>
......
</c:url>

• Crée un variable de type URL,


– var : nom de la variable
– scope : domaine de validité (page, request, session)
– value : valeur de l’url

• <c:param/> : permet de rajouter une requête à l’URL.

TPI P. Reignier

B.27
Exemple

• Faire une page affichant une liste de produits

• Un objet Produit (JavaBean)

• Un object d’accès à la BD (ProduitDAO)

• Un contrôleur pour construire la liste de produits

• Une page JSP pour afficher le vecteur

TPI P. Reignier

B.28
Produit (JavaBean)

public class Produit {


private String nom ;
private int prix ;

public String getNom() {


return nom;
}

public void setNom(String nom) {


this.nom = nom;
}

public int getPrix() {


return prix;
}

public void setPrix(int prix) {


this.prix = prix;
}
}

TPI P. Reignier

B.29
ProduitDAO

public class ProduitDAO {

protected DataSource dataSource ;


protected Connection conn = null ;
protected Statement stmt = null ;

public ProduitDAO() {
try {
Context init = new InitialContext();
Context ctx = (Context) init.lookup("java:comp/env");
dataSource = (DataSource) ctx.lookup("jdbc/magasin");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

TPI P. Reignier

B.30
ProduitDAO (suite)

public List getListOfProduits() throws SQLException {


conn = dataSource.getConnection();
stmt = conn.createStatement() ;
ResultSet resultSet = stmt.executeQuery("select * from article") ;
Vector resultat = new Vector() ;

while (resultSet.next()) {
Produit produit = new Produit() ;
produit.setNom(resultSet.getString(1)) ;
produit.setPrix(resultSet.getInt(2)) ;
resultat.add(produit) ;
}
conn.close() ;
return resultat ;
}
}

TPI P. Reignier

B.31
Contrôleur

public class ProduitsAction extends DispatchAction {

public ActionForward getProduits(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception
{
ProduitDAO produitDAO = new ProduitDAO() ;
List produits = produitDAO.getListOfProduits() ;

request.setAttribute("listOfProduits", produits) ;

return mapping.findForward("success") ;
}
}

TPI P. Reignier

B.32
Présentation

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>
<body>

<h1>Liste de produits</h1>

<table border=1>
<tr><th>Nom</th><th>Prix</th></tr>

<c:forEach var="produit" items="${listOfProduits}">


<tr>
<td><c:out value="${produit.nom}"/></td>
<td><c:out value="${produit.prix}"/></td>
</tr>
</c:forEach>

</table>
</body>
</html>

TPI P. Reignier

B.33
Taglib : HTML

• Redéfinir sous forme de Tag Lib tous les tags HTML (formulaire)

• Objectif :
– Contrôler facilement les valeurs par défaut (section suivante)
• Exemples :
<form action="..." method=".."/> <html:form action=".." method=".."/>
<input type=text name="x"> <html:text property="x"/>
<input type="submit" value="envoyer"> <html:submit>envoyer</html:submit>
... ...

TPI P. Reignier

B.34
B4 - Validation de formulaires

TPI P. Reignier
Problème

• Contrôleur :
– Accéder aux valeurs d’un formulaire
– Accéder aux paramètres d’une URL

• Formulaire :
– Pré-remplir les champs avec des valeurs fournies par le contrôleur

TPI P. Reignier

B.36
ActionForm

• Mise en place d’un objet (JavaBean):


– Reflet ”objet” du formulaire
– Reflet ”objet” des paramètres d’une URL
– Remarque : tous les champs peuvent ne pas être présents dans le
formulaire ou l’URL

• Attention :
– Formulaire : champs de type chaine de caractères
⇒ les attributs du JavaBean sont de type String

• JavaBean : dérive d’ActionForm

TPI P. Reignier

B.37
ActionForm

public class ProduitForm extends ActionForm {

private String nom ;


private String prix ;

public String getNom() {


return nom;
}

public void setNom(String nom) {


this.nom = nom;
}

public String getPrix() {


return prix;
}

public void setPrix(String prix) {


this.prix = prix;
}
}

TPI P. Reignier

B.38
produitForm.jsp

<html>
<body>

<h1>Produit</h1>

<c:url var="url" scope="page" value="addProduit.do">


<<c:param name="action" value="addProduit"/>
</c:url>

<html:form action="${url}">

<table>
<tr><td>Nom</td><td><html:text property="nom"/></td>
<tr><td>Prix</td><td><html:text property="prix"/></td>
</table>

<p>
<html:submit>Ajouter</html:submit>

</html:form>
</body>
</html>

TPI P. Reignier

B.39
ProduitsAction

public ActionForward addProduit(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception
{
ProduitForm produitForm = (ProduitForm) form ;
Produit produit = new Produit() ;

BeanUtils.copyProperties(produit, produitForm) ;

.............
return mapping.findForward("success") ;
}

TPI P. Reignier

B.40
Struts-config.xml

<struts-config>
<form-beans>
<form-bean name="produitForm" type="form.ProduitForm"/>
</form-beans>

<action-mappings>
<action path="/enterProduit" forward="/produitForm.jsp"/>

<action path="/addProduit" validate="false" name="produitForm" parameter="action"


type="action.ProduitsAction">
<forward name="success" path="/success.jsp"/>
<forward name="fail" path="/error.jsp"/>
</action>

<action path="/showProduits" parameter="action" type="action.ProduitsAction">


<forward name="success" path="/showProduits.jsp"/>
</action>
</action-mappings>

<message-resources parameter="MessageResources" null="false"/>


</struts-config>

TPI P. Reignier

B.41
Struts-config.xml

• envoie du formulaire = appel d’une URL :

– Déclenchant la méthode addProduit de ProduitAction

– Association du Java Bean au contrôleur

TPI P. Reignier

B.42
Passage de données du contrôleur vers le formulaire

• Contrôleur :

public ActionForward setUpProduit(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
ProduitForm produitForm = (ProduitForm) form ;

Produit produit = new Produit() ;


produit.setNom("Livre") ;
produit.setPrix(40) ;

BeanUtils.copyProperties(produitForm, produit) ;

return mapping.findForward("success") ;
}

• struts-config.xml :

<action path="/modifyProduit" name="produitForm" validate="false"


parameter="action" type="action.ProduitsAction">
<forward name="success" path="/produitForm.jsp"/>
</action>
TPI P. Reignier

B.43
Validation des données

• Deux aspects :
– Vérification des champs (champs obligatoires, type des données etc)
– Communication des erreurs à l’utilisateur
– Prise en charge (optionnelle) par Struts

• Vérification des champs :


– Redéfinir la méthode validate de l’ActionForm.
– Renvoie null ou une liste vide si il n’y a pas d’erreur
– La liste des messages d’erreur sinon

• Communication avec l’utilisateur


– Par la liste des messages d’erreur
– Struts boucle automatiquement tant qu’il reste des erreurs

TPI P. Reignier

B.44
validate (dans ActionForm)

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request ) {


ActionErrors errors = new ActionErrors() ;
if (getNom().equals(""))
errors.add("nom", new ActionMessage("errors.required", "name")) ;

try {
Integer.parseInt(getPrix()) ;
} catch (NumberFormatException e) {
errors.add("prix", new ActionMessage("errors.integer", "price")) ;
}

return errors ;
}

• Méthode add
– Association d’une clé à un message
– Permet d’accéder aux messages depuis le formulaire

TPI P. Reignier

B.45
ActionMessage

• Définition d’un message à partir :


– D’une clé provenant du fichier de ressources
– De 1, 2, 3, ou 4 éléments à remplacer dans le texte associé.

• Exemple :
– new ActionMessage("errors.required", "name")) ;
– errors.required : {0} is required.
– Résultat final : name is required.

TPI P. Reignier

B.46
Struts-config.xml

<struts-config>
<form-beans>
<form-bean name="produitForm" type="form.ProduitForm"/>
</form-beans>

<action-mappings>
<action path="/enterProduit" validate="false" name="produitForm"
forward="/produitForm.jsp"/>

<action path="/addProduit" validate="true" input="/produitForm.jsp"


name="produitForm" parameter="action" type="action.ProduitsAction">
<forward name="success" path="/success.jsp"/>
<forward name="fail" path="/error.jsp"/>
</action>

<message-resources parameter="MessageResources" null="false"/>

</struts-config>

TPI P. Reignier

B.47

Vous aimerez peut-être aussi