10. Esempio 08 - I tag associati agli elenchi
L'esempio seguente riguarda i tag che visualizzano gli elenchi. Li abbiamo già visti nell'esempio precedente: l'elenco a discesa, le caselle di controllo e i pulsanti di opzione. Il modulo di prova sarà il seguente:
![]() | ![]() |
10.1. Il progetto NetBeans
Il progetto NetBeans è il seguente:
![]() |
- in [1] l'azione e in [2] la vista associata.
Il file [example/example.xml] configura l'applicazione:
<?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>
Le righe 8-9 mostrano che una chiamata a URL [/example/Form.action] genera la vista [/example/Form.JSP]. L'azione [Form] si occuperà quindi di costruire il modello della vista [Form.JSP].
10.2. Il file dei messaggi internazionalizzati
Il file [messages.properties] contenente i messaggi internazionalizzati è il seguente:
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 vista [Form.JSP] utilizza questi messaggi.
10.3. La vista [Form.JSP]
La vista [Form.JSP] è la seguente:
<%@ 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>
Esaminiamo i diversi tag di inserimento del modulo:
- riga 27: il tag <s:select>:
<s:select name="select1" list="{'vert','jaune','rouge'}" size="1" key="Form.select1"/>
Questo tag genererà il seguente codice HTML:
Il valore dell'attributo list è un array di stringhe utilizzato per generare i valori e le etichette delle opzioni. Il modello associato è il campo select1 dell'azione [Form] seguente:
private String select1 = "jaune";
Questo campo è associato in lettura e scrittura al tag denominato select1. In scrittura, il valore dell’opzione selezionata verrà inserito nel campo select1. In lettura, il valore del campo select1 serve a determinare l’opzione selezionata. In questo caso, il valore jaune del campo select1 serve a selezionare l’opzione del tag select1 che ha il valore «giallo». Ecco perché, alla riga 3, l’opzione è selezionata.
- riga 28
<s:select name="select2" list="{'vert','jaune','rouge'}" size="3" key="Form.select2" multiple="true"/>
Non vi è alcuna differenza sostanziale rispetto al tag della riga 27, se non che in questo caso la selezione è multipla. Pertanto, il valore inviato è un array di valori, ovvero quelli delle opzioni selezionate. Il campo select2 dell’azione associata al modulo è il seguente:
private String[] select2 = new String[]{"vert", "rouge"};
Si tratta effettivamente di un array. Il suo valore iniziale serve a selezionare le opzioni i cui valori sono presenti nell’array.
- riga 29
<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"/>
In questo caso, il valore dell’attributo list è un dizionario le cui chiavi fungono da valori per le opzioni e i valori associati fungono da etichette per le opzioni. Il codice HTML generato è il seguente:
Il campo associato nell'azione è il seguente:
private String[] select3 = new String[]{"01", "03"};
Abbiamo nuovamente un array di valori poiché il tag associato è a scelta multipla. I valori iniziali dell'array spiegano perché le opzioni delle righe 2 e 4 sono inizialmente selezionate.
- riga 30
<s:select name="select4" list="dico" size="3" key="Form.select4" multiple="true"/>
In questo caso, le opzioni dell’elenco saranno fornite dal modello della vista, che in questo caso fa parte dell’azione [Form]:
private HashMap<String, String> dico = new HashMap<String, String>();
Le chiavi del dizionario dico saranno i valori delle opzioni. I valori del dizionario dico saranno le etichette delle opzioni. Il campo select4 dell’azione è il seguente:
private String[] select4 = new String[]{"1", "3"};
Si tratta di una tabella di valori che riceverà i valori inviati dal tag select4.
- riga 31
<s:select name="select5" list="couleurs" listKey="id" listValue="nom" size="3" key="Form.select5" multiple="true" />
L'elenco delle opzioni è generato dal campo couleurs definito dall'attributo list. Il campo couleurs dell'azione [Form] è definito come segue:
private Couleur[] couleurs;
La classe [Couleur] è definita come segue:
package example;
public class Couleur {
// campi
private String id;
private String nom;
// costruttore
public Couleur(){
}
// getter e setter
...
}
Presenta due campi denominati id e nom. Nel tag select5 si ha listKey="id" listValue="nom". Ciò significa che il campo id fungerà da valore per un’opzione, mentre il campo nom fungerà da etichetta. Si ricorda che sono i valori delle opzioni a essere registrati. Essi saranno registrati nel campo successivo select5:
private String[] select5 = new String[]{"1", "3"};
- riga 32
<s:checkboxlist name="checkboxlist1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.checkboxlist1"/>
Questo tag genererà il seguente codice HTML:
Tutte le caselle di selezione hanno il nome checkboxlist1. Poiché ciascuna di esse può essere selezionata, è possibile inviare più parametri checkboxlist1. Sarà quindi necessario che il campo checkboxlist1 del modello sia di tipo tabella. L'attributo list della riga 22 è un dizionario le cui chiavi generano gli attributi value delle caselle di selezione e i cui valori generano le etichette di queste stesse caselle. Il campo checkboxlist1 dell’azione [Form] è il seguente:
private String[] checkboxlist1 = new String[]{"01", "03"};
- riga 33
<s:checkboxlist name="checkboxlist2" list="dico" key="Form.checkboxlist2"/>
Questo tag funziona come il tag select4 esaminato in precedenza. Il campo associato nell'azione è il seguente:
private String[] checkboxlist2 = new String[]{"1", "3"};
- riga 34
<s:checkboxlist name="checkboxlist3" list="couleurs" listKey="id" listValue="nom" key="Form.checkboxlist3" />
Questo tag funziona come il tag select5 esaminato in precedenza. Il campo checkboxlist3 associato nell'azione è il seguente:
private String[] checkboxlist3 = new String[]{"1", "3"};
- riga 35
<s:radio name="radio1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.radio1"/>
Questo tag funziona in linea di principio come il tag select3 visto in precedenza. Il codice HTML generato è il seguente:
Tutti i tag hanno lo stesso nome: radio1. È possibile selezionare un solo pulsante di opzione. Viene quindi inviato un solo valore, quello del pulsante di opzione selezionato. Le chiavi del dizionario list servono a generare gli attributi value dei pulsanti di opzione, mentre i valori del dizionario servono a generare le etichette associate a tali pulsanti. Il campo radio1 associato nell’azione è il seguente:
private String radio1="01";
- riga 36
<s:radio name="radio2" list="dico" key="Form.radio2"/>
Questo tag funziona in linea di principio come il tag select4. Il campo radio2 associato nell'azione è il seguente:
private String radio2="1";
- riga 37
<s:radio name="radio3" list="couleurs" listKey="id" listValue="nom" key="Form.radio3" />
Questo tag funziona in linea di principio come il tag select5. Il campo radio3 associato nell'azione è il seguente:
private String radio3="1";
Questo per quanto riguarda la parte saisie del modulo. Esiste anche una parte confirmation analoga a quella del modulo dell’esempio precedente: conferma i valori inviati. Commenteremo solo le righe seguenti:
<tr>
<td><s:text name="Form.select2"/></td>
<td><s:property value="select2SelectedValues"/>
</tr>
che corrisponde visivamente a quanto segue:
Il testo nella cella di sinistra proviene dal file [messages.properties]:
Form.select2=2-select2 (multiple=true, size=3)
Il testo nella cella di destra è stato generato dal metodo getSelect2SelectedValues dell'azione [Form]:
// valori selezionati negli elenchi a discesa
public String getSelect2SelectedValues() {
return getArrayValue(select2);
}
// metodi di utilità
public String getArrayValue(String[] values) {
String result = "";
for (String value : values) {
result += " " + value;
}
return result;
}
Il metodo getSelect2SelectedValues converte i valori della tabella select2 in una stringa di caratteri.
10.4. L'azione [Form]
Nel commentare la vista [Form.JSP] abbiamo illustrato i campi dell'azione associata [Form]. Il codice dell'azione [Form] è il seguente:
package example;
import com.opensymphony.xwork2.ActionSupport;
import java.util.HashMap;
public class Form extends ActionSupport {
// campi del modulo
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;
// costruttore senza parametri
public Form() {
// inizializzazione del dizionario dei colori
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)");
// inizializzazione dell'array di oggetti Colore
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++;
}
}
// valori selezionati negli elenchi a discesa
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);
}
// metodi di utilità
public String getArrayValue(String[] values) {
String result = "";
for (String value : values) {
result += " " + value;
}
return result;
}
// getter e setter
...
}
In questa azione non è presente alcun metodo execute. Viene quindi eseguito il metodo execute della classe padre ActionSupport. Quest’ultimo non esegue alcuna operazione e si limita a restituire la chiave di navigazione SUCCESS.
10.5. I test
Il lettore è invitato a testare l’applicazione [exemple-08].


