Introduction à STRUTS2 par l'exemple


précédentsommairesuivant

X. Exemple 08 - Les balises associées à des listes

L'exemple suivant s'intéresse aux balises qui affichent des listes. Nous les avons déjà rencontrées dans l'exemple précédent : la liste déroulante, les cases à cocher et les boutons radio. Le formulaire de test sera le suivant :

Image non disponible

X-A. Le projet Netbeans

Le projet Netbeans est le suivant :

Image non disponible

  • en [1] l'action et en [2] la vue associée.

Le fichier [example/example.xml] configure l'application :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <package name="example" namespace="/example" extends="struts-default">
    <action name="Form" class="example.Form">
      <result name="success">/example/Form.jsp</result>
    </action>
  </package>
</struts>

Les lignes 8-9 montrent qu'un appel à l'Url [/example/Form.action] génère la vue [/example/Form.jsp]. L'action [Form] se chargera donc de construire le modèle de la vue [Form.jsp].

X-B. Le fichier des messages internationalisés

Le fichier [messages.properties] des messages internationalisés est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
Form.francais=Fran\u00E7ais
Form.anglais=Anglais
Form.titre=Struts 2 - les tags \u00E0 valeurs multiples
Form.message=Struts 2 - les tags \u00E0 valeurs multiples
Form.langues=langues
Form.select1=1-select1 (multiple=false, size=1)
Form.select2=2-select2 (multiple=true, size=3)
Form.select3=3-select3 (multiple=true, size=3)
Form.select4=4-select4 (multiple=true, size=3)
Form.select5=5-select5 (multiple=true, size=3)
Form.checkboxlist1=6-checkboxlist1
Form.checkboxlist2=7-checkboxlist2
Form.checkboxlist3=8-checkboxlist3
Form.radio1=9-radio1
Form.radio2=10-radio2
Form.radio3=11-radio3
Form.submitText=Valider
Confirmation.message=Confirmation des valeurs saisies
Confirmation.champ=champ
Confirmation.valeur=valeur
Confirmation.select1=1-select1 (multiple=false, size=1)
Confirmation.select2=2-select2 (multiple=false, size=3)
Confirmation.select3=3-select3 (multiple=true, size=3)
Confirmation.select4=4-select4 (multiple=true, size=3)
Confirmation.select5=5-select5 (multiple=true, size=3)
Confirmation.checkboxlist1=6-checkboxlist1
Confirmation.checkboxlist2=7-checkboxlist2
Confirmation.checkboxlist3=8-checkboxlist3
Confirmation.radio1=9-radio1
Confirmation.radio2=10-radio2
Confirmation.radio3=11-radio3

La vue [Form.jsp] utilise ces messages.

X-C. La vue [Form.jsp]

La vue [Form.jsp] est la suivante :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Form.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Form.message"/></h2>
    <h3><s:text name="Form.langues"/></h3>
    <ul>
      <li>
        <s:url id="url" action="Form">
          <s:param name="request_locale">en</s:param>
        </s:url>
        <s:a href="%{url}"><s:text name="Form.anglais"/></s:a>
        </li>
        <li>
        <s:url id="url" action="Form">
          <s:param name="request_locale">fr</s:param>
        </s:url>
        <s:a href="%{url}"><s:text name="Form.francais"/></s:a>
        </li>
      </ul>
    <s:form name="formulaire">
      <s:select name="select1" list="{'vert','jaune','rouge'}" size="1" key="Form.select1"/>
      <s:select name="select2" list="{'vert','jaune','rouge'}" size="3" key="Form.select2" multiple="true"/>
      <s:select name="select3" list="#{'01':'vert(01)','02':'jaune(02)', '03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" size="3" key="Form.select3" multiple="true"/>
      <s:select name="select4" list="dico" size="3" key="Form.select4" multiple="true"/>
      <s:select name="select5" list="couleurs" listKey="id" listValue="nom" size="3"   key="Form.select5" multiple="true" />
      <s:checkboxlist name="checkboxlist1" list="#{'01':'vert(01)','02':'jaune(02)', '03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.checkboxlist1"/>
      <s:checkboxlist name="checkboxlist2" list="dico" key="Form.checkboxlist2"/>
      <s:checkboxlist name="checkboxlist3" list="couleurs" listKey="id" listValue="nom" key="Form.checkboxlist3" />
      <s:radio name="radio1" list="#{'01':'vert(01)','02':'jaune(02)', '03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.radio1"/>
      <s:radio name="radio2" list="dico" key="Form.radio2"/>
      <s:radio name="radio3" list="couleurs" listKey="id" listValue="nom" key="Form.radio3" />
      <s:submit key="Form.submitText" name="submitText"/>
    </s:form>
    <hr/>
    <h2><s:text name="Confirmation.message"/></h2>
    <table border="1">
      <tr>
        <th><s:text name="Confirmation.champ"/></th>
        <th><s:text name="Confirmation.valeur"/></th>
      </tr>
      <tr>
        <td><s:text name="Form.select1"/></td>
        <td><s:property value="select1"/>
      </tr>
      <tr>
        <td><s:text name="Form.select2"/></td>
        <td><s:property value="select2SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.select3"/></td>
        <td><s:property value="select3SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.select4"/></td>
        <td><s:property value="select4SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.select5"/></td>
        <td><s:property value="select5SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkboxlist1"/></td>
        <td><s:property value="checkboxlist1SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkboxlist2"/></td>
        <td><s:property value="checkboxlist2SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkboxlist3"/></td>
        <td><s:property value="checkboxlist3SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.radio1"/></td>
        <td><s:property value="radio1"/>
      </tr>
      <tr>
        <td><s:text name="Form.radio2"/></td>
        <td><s:property value="radio2"/>
      </tr>
      <tr>
        <td><s:text name="Form.radio3"/></td>
        <td><s:property value="radio3"/>
      </tr>
    </table>
  </body>
</html>

Examinons les différentes balises de saisie du formulaire :

  • ligne 27 : la balise <s:select> :
 
Sélectionnez
      <s:select name="select1" list="{'vert','jaune','rouge'}" size="1" key="Form.select1"/>

Cette balise génèrera le code Html suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
<select name="select1" size="1" id="Form_select1">
    <option value="vert">vert</option>
    <option value="jaune" selected="selected">jaune</option>
    <option value="rouge">rouge</option>
</select>

La valeur de l'attribut list est un tableau de chaînes de caractères utilisé pour générer les valeurs et les libellés des options. Le modèle associé est le champ select1 de l'action [Form] suivant :

 
Sélectionnez
  private String select1 = "jaune";

Ce champ est associé en lecture et écriture à la balise nommée select1. En écriture, la valeur de l'option sélectionnée sera injectée dans le champ select1. En lecture, la valeur du champ select1 sert à déterminer l'option sélectionnée. Ici, la valeur jaune du champ select1 sert à sélectionner l'option de la balise select1 qui a la valeur jaune. C'est pourquoi, ligne 3, l'option est sélectionnée.

  • ligne 28
 
Sélectionnez
<s:select name="select2" list="{'vert','jaune','rouge'}" size="3" key="Form.select2" multiple="true"/>

Il n'y a pas de différence fondamentale avec la balise de la ligne 27, si ce n'est que la sélection est ici multiple. Donc la valeur postée est un tableau de valeurs, celles des options sélectionnées. Le champ select2 de l'action associée au formulaire est le suivant :

 
Sélectionnez
  private String[] select2 = new String[]{"vert", "rouge"};

C'est bien un tableau. Sa valeur initiale sert à sélectionner les options dont les valeurs sont présentes dans le tableau.

  • ligne 29
 
Sélectionnez
      <s:select name="select3" list="#{'01':'vert(01)','02':'jaune(02)',
                '03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" size="3" key="Form.select3" multiple="true"/>

Ici, la valeur de l'attribut list est un dictionnaire dont les clés servent de valeurs aux options et les valeurs associées servent de libellés aux options. Le code Html généré est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
<select name="select3" size="3" id="Form_select3" multiple="multiple">
    <option value="01" selected="selected">vert(01)</option>
    <option value="02">jaune(02)</option>
    <option value="03" selected="selected">rouge(03)</option>
    <option value="04">blanc(04)</option>
    <option value="05">noir(05)</option>
</select>

Le champ associé dans l'action est le suivant :

 
Sélectionnez
  private String[] select3 = new String[]{"01", "03"};

On a de nouveau un tableau de valeurs car la balise associée est à choix multiple. Les valeurs initiales du tableau expliquent pourquoi les options des lignes 2 et 4 sont initialement sélectionnées.

  • ligne 30
 
Sélectionnez
      <s:select name="select4" list="dico" size="3" key="Form.select4" multiple="true"/>

Ici, les options de la liste vont être fournies par le modèle de la vue, modèle qui fait ici partie de l'action [Form] :

 
Sélectionnez
private HashMap<String, String> dico = new HashMap<String, String>();

Les clés du dictionnaire dico seront les valeurs des options. Les valeurs du dictionnaire dico seront les libellés des options. Le champ select4 de l'action est le suivant :

 
Sélectionnez
  private String[] select4 = new String[]{"1", "3"};

C'est un tableau de valeurs qui recevra les valeurs postées par la balise select4 .

  • ligne 31
 
Sélectionnez
<s:select name="select5" list="couleurs" listKey="id" listValue="nom" size="3" key="Form.select5" multiple="true" />

La liste des options est générée par le champ couleurs défini par l'attribut list. Le champ couleurs de l'action [Form] est définie comme suit :

 
Sélectionnez
private Couleur[] couleurs;

La classe [Couleur] est définie comme suit :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
package example;

public class Couleur {

  // champs
  private String id;
  private String nom;

  // constructeur
  public Couleur(){
  }

  // getters et setters
...  
}

Elle a deux champs nommés id et nom. Dans la balise select5 on a listKey="id" listValue="nom". Cela signifie que le champ id servira de valeur à une option et le champ nom servira de libellé. On rappelle que ce sont les valeurs des options qui sont postées. Elles seront postées au champ select5 suivant :

 
Sélectionnez
  private String[] select5 = new String[]{"1", "3"};
  • ligne 32
 
Sélectionnez
<s:checkboxlist name="checkboxlist1" list="#{'01':'vert(01)','02':'jaune(02)',
                '03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.checkboxlist1"/>

Cette balise va générer le code Html suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<input type="checkbox" name="checkboxlist1" value="01" id="checkboxlist1-1" checked="checked"/>
<label for="checkboxlist1-1" class="checkboxLabel">vert(01)</label>
<input type="checkbox" name="checkboxlist1" value="02" id="checkboxlist1-2"/>
<label for="checkboxlist1-2" class="checkboxLabel">jaune(02)</label>
<input type="checkbox" name="checkboxlist1" value="03" id="checkboxlist1-3" checked="checked"/>
<label for="checkboxlist1-3" class="checkboxLabel">rouge(03)</label>
<input type="checkbox" name="checkboxlist1" value="04" id="checkboxlist1-4"/>
<label for="checkboxlist1-4" class="checkboxLabel">blanc(04)</label>
<input type="checkbox" name="checkboxlist1" value="05" id="checkboxlist1-5"/>
<label for="checkboxlist1-5" class="checkboxLabel">noir(05)</label>

Toutes les cases à cocher portent le nom checkboxlist1. Comme chacune d'elles peut être cochée, plusieurs paramètres checkboxlist1 peuvent être postés. Il faudra donc que le champ checkboxlist1 du modèle soit de type tableau. L'attribut list de la ligne 22 est un dictionnaire dont les clés génèrent les attributs value des cases à cocher et les valeurs les libellés de ces mêmes cases. Le champ checkboxlist1 de l'action [Form] est le suivant :

 
Sélectionnez
private String[] checkboxlist1 = new String[]{"01", "03"};
  • ligne 33
 
Sélectionnez
      <s:checkboxlist name="checkboxlist2" list="dico" key="Form.checkboxlist2"/>

Cette balise fonctionne comme la balise select4 étudiée précédemment. Le champ associé dans l'action est le suivant :

 
Sélectionnez
  private String[] checkboxlist2 = new String[]{"1", "3"};
  • ligne 34
 
Sélectionnez
      <s:checkboxlist name="checkboxlist3" list="couleurs" listKey="id" listValue="nom" key="Form.checkboxlist3" />

Cette balise fonctionne comme la balise select5 étudiée précédemment. Le champ checkboxlist3 associé dans l'action est le suivant :

 
Sélectionnez
  private String[] checkboxlist3 = new String[]{"1", "3"};
  • ligne 35
 
Sélectionnez
      <s:radio name="radio1" list="#{'01':'vert(01)','02':'jaune(02)',
                '03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.radio1"/>

Cette balise fonctionne dans son principe comme la balise select3 vue précédemment. Le code Html généré est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
<input type="radio" name="radio1" id="Form_radio101" checked="checked" value="01"/><label for="Form_radio101">vert(01)</label>
<input type="radio" name="radio1" id="Form_radio102" value="02"/><label for="Form_radio102">jaune(02)</label>
<input type="radio" name="radio1" id="Form_radio103" value="03"/><label for="Form_radio103">rouge(03)</label>
<input type="radio" name="radio1" id="Form_radio104" value="04"/><label for="Form_radio104">blanc(04)</label>
<input type="radio" name="radio1" id="Form_radio105" value="05"/><label for="Form_radio105">noir(05)</label>

Toutes les balises ont le même nom radio1. Un seul bouton radio peut être coché. Il n'y a donc qu'une valeur postée, celle du bouton radio coché. Les clés du dictionnaire list servent à générer les attributs value des boutons radio alors que les valeurs du dictionaire servent à générer les libellés associés à ces boutons. Le champ radio1 associé dans l'action est le suivant :

 
Sélectionnez
  private String radio1="01";
  • ligne 36
 
Sélectionnez
      <s:radio name="radio2" list="dico" key="Form.radio2"/>

Cette balise fonctionne dans son principe comme la balise select4. Le champ radio2 associé dans l'action est le suivant :

 
Sélectionnez
  private String radio2="1";
  • ligne 37
 
Sélectionnez
      <s:radio name="radio3" list="couleurs" listKey="id" listValue="nom" key="Form.radio3" />

Cette balise fonctionne dans son principe comme la balise select5. Le champ radio3 associé dans l'action est le suivant :

 
Sélectionnez
  private String radio3="1";

Voilà pour la partie saisie du formulaire. Il y a également une partie confirmation qui est analogue à celle du formulaire de l'exemple précédent : elle confirme les valeurs postées. Nous ne commenterons que les lignes suivantes :

 
Sélectionnez
1.
2.
3.
4.
<tr>
        <td><s:text name="Form.select2"/></td>
        <td><s:property value="select2SelectedValues"/>
</tr>

qui correspond visuellement à ce qui suit :

Image non disponible

Le texte dans la cellule de gauche vient du fichier [messages.properties] :

 
Sélectionnez
Form.select2=2-select2 (multiple=true, size=3)

Le texte dans la cellule de droite a été généré par la méthode getSelect2SelectedValues de l'action [Form] :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
// valeurs sélectionnées dans listes déroulantes
  public String getSelect2SelectedValues() {
    return getArrayValue(select2);
  }

  // méthodes utilitaires
  public String getArrayValue(String[] values) {
    String result = "";
    for (String value : values) {
      result += " " + value;
    }
    return result;
  }

La méthode getSelect2SelectedValues rend les valeurs du tableau select2 sous la forme d'une chaîne de caractères.

X-D. L'action [Form]

En commentant la vue [Form.jsp] nous avons présenté les champs de l'action [Form] associée. Le code de l'action [Form] est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
package example;

import com.opensymphony.xwork2.ActionSupport;
import java.util.HashMap;

public class Form extends ActionSupport {

  // champs du formulaire
  private String select1 = "jaune";
  private String[] select2 = new String[]{"vert", "rouge"};
  private String[] select3 = new String[]{"01", "03"};
  private String[] select4 = new String[]{"1", "3"};
  private String[] select5 = new String[]{"1", "3"};
  private HashMap<String, String> dico = new HashMap<String, String>();
  private Couleur[] couleurs;
  private String[] checkboxlist1 = new String[]{"01", "03"};
  private String[] checkboxlist2 = new String[]{"1", "3"};
  private String[] checkboxlist3 = new String[]{"1", "3"};
  private String radio1="01";
  private String radio2="1";
  private String radio3="1";

  private String submitText;

  // constructeur sans paramètre
  public Form() {
    // init dictionnaire de couleurs
    dico.put("1", "vert(1)");
    dico.put("2", "jaune(2)");
    dico.put("3", "bleu(3)");
    dico.put("4", "rouge(4)");
    dico.put("5", "blanc(5)");

    // init tableau d'objets Couleur
    couleurs = new Couleur[dico.size()];
    int i = 0;
    for (String key : dico.keySet()) {
      couleurs[i] = new Couleur();
      couleurs[i].setId(key);
      couleurs[i].setNom(dico.get(key));
      i++;
    }
  }

  // valeurs sélectionnées dans listes déroulantes
  public String getSelect2SelectedValues() {
    return getArrayValue(select2);
  }

  public String getSelect3SelectedValues() {
    return getArrayValue(select3);
  }

  public String getSelect4SelectedValues() {
    return getArrayValue(select4);
  }

  public String getSelect5SelectedValues() {
    return getArrayValue(select5);
  }

  public String getCheckboxlist1SelectedValues() {
    return getArrayValue(checkboxlist1);
  }

  public String getCheckboxlist2SelectedValues() {
    return getArrayValue(checkboxlist2);
  }
  public String getCheckboxlist3SelectedValues() {
    return getArrayValue(checkboxlist3);
  }

  // méthodes utilitaires
  public String getArrayValue(String[] values) {
    String result = "";
    for (String value : values) {
      result += " " + value;
    }
    return result;
  }

  // getters et setters
   ...
}

On ne trouve pas de méthode execute dans cette action. C'est donc la méthode execute de la classe parent ActionSupport qui est exécutée. Celle-ci ne fait rien et se contente de rendre la clé de navigation SUCCESS .

X-E. Les tests

Le lecteur est invité à tester l'application [exemple-08].


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Serge Tahe. 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.