6. Moduli HTML
Finora abbiamo utilizzato un unico modulo contenente solo due campi di immissione. Qui proponiamo di creare ed elaborare un modulo utilizzando componenti grafici standard (pulsanti di opzione, caselle di controllo, campi di immissione, caselle combinate, elenchi).
6.1. Le viste dell'applicazione
L'applicazione avrà solo due viste. La prima visualizza un modulo vuoto:
VISTA 1 - modulo

Questa prima vista, denominata form.jsp, ci consentirà di implementare vari tag della libreria struts-html. L'utente compila il modulo:

Il pulsante [Invia] conferma i valori inseriti. Questa sarà la seconda vista:

Questa seconda vista ci consentirà di utilizzare altre due librerie di tag: struts-bean e struts-logic. Il link [Torna al modulo] ci permette di tornare al modulo così come lo abbiamo compilato. Verremo quindi riportati alla prima vista.
6.2. L'architettura dell'applicazione
![]() |
- Il modulo (vista 1) sarà rappresentato da un oggetto Struts dinamico denominato dynaFormulaire, una sottoclasse di DynaActionForm. Verrà visualizzato dalla vista form.jsp.
- L'azione Struts InitFormulaireAction sarà responsabile del recupero dei dati necessari per visualizzare il modulo
- Il modulo compilato verrà elaborato da una ForwardAction, che si limiterà a reindirizzare la richiesta alla seconda vista, confirmation.jsp. Questa vista sarà responsabile della visualizzazione dei valori del modulo.
6.3. Configurazione dell'applicazione
6.3.1. Il file server.xml
Il contesto dell'applicazione sarà denominato /formulaire2. Aggiungeremo quindi la seguente riga al file server.xml di Tomcat:
Una volta fatto ciò, potrebbe essere necessario riavviare Tomcat affinché riconosca il nuovo contesto. Possiamo verificarne la validità richiedendo l'URL http://localhost:8080/formulaire2:

6.3.2. Il file web.xml
Il file di configurazione web.xml dell'applicazione sarà il seguente:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<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>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
Rispetto ai file di configurazione web.xml che abbiamo già visto, stiamo apportando alcune modifiche:
- Introduciamo due nuove librerie di tag: struts-bean e struts-logic. Queste verranno utilizzate nella vista confirmation.jsp. La vista formulaire.jsp, invece, utilizzerà la libreria struts-html.
6.3.3. Il file struts-config.xml
Il file struts-config.xml sarà il seguente:
<?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_1.dtd">
<struts-config>
<form-beans>
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
</form-beans>
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
<message-resources
parameter="ApplicationResources"
null="false"/>
</struts-config>
Contiene tre sezioni principali:
- la dichiarazione dei moduli nella sezione <form-beans>
- la dichiarazione delle azioni nella sezione <action-mappings>
- la dichiarazione del file delle risorse nella sezione <message-resources>
6.3.4. Gli oggetti modulo (bean) dell'applicazione
Gli oggetti utilizzati per rappresentare i moduli HTML dell'applicazione sono di tipo ActionForm o di un tipo derivato (DynaActionForm, DynaValidatorForm, ecc.). Sono chiamati bean perché la loro costruzione segue le regole dei JavaBeans. Nella nostra applicazione c'è un solo bean di modulo, chiamato dynaFormulaire e derivato da DynaActionForm. Verrà utilizzato nelle seguenti situazioni:
- per contenere i dati necessari alla visualizzazione della vista n. 1
- recuperare i valori dal modulo nella vista n. 1 quando l'utente lo invia
- per contenere i dati necessari per visualizzare la vista n. 2
La struttura del bean dynaFormulaire è strettamente legata al modulo nella vista n. 1. Esaminiamola:
![]() |
N. | Tipo HTML | Ruolo |
<input name="opt" type="radio" value="yes"> <input name="opt" type="radio" value="no"> | gruppo di pulsanti di opzione collegati tra loro (stesso nome) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | gruppi di caselle di controllo (non è lo stesso nome) | |
<input type="text" name="inputField"> | un campo di testo | |
<input type="password" name="password"> | un campo password | |
<textarea name="inputBox">...</textarea> | un campo di immissione multilinea | |
<select name="combo" size="1">..</select> | un menu a tendina | |
<select name="simpleList" size="3">..</select> | un elenco a selezione singola | |
<select name="listeMultiple" size="3" multiple>..</select> | un elenco a selezione multipla | |
<input type="button" value="Cancella" onclick='clearList("singleList")'> | pulsante per deselezionare gli elementi selezionati in simpleList (7) | |
<input type="button" value="Cancella" onclick='clearList("multipleList")'> | pulsante per deselezionare gli elementi selezionati in multipleList (8) | |
<input type="submit" value="Invia"> | pulsante di invio del modulo | |
<input type="hidden" name="secret" value="..."> | un campo nascosto |
Consideriamo diversi casi:
- L'oggetto dynaFormulaire viene utilizzato per contenere i valori del modulo HTML sopra riportato, che verranno inviati tramite il pulsante [Invia]. Deve quindi avere gli stessi campi del modulo HTML. Il tipo di campo è determinato dalla seguente regola:
- se il campo HTML fornisce un solo valore, il campo dynaFormulaire sarà di tipo java.lang.String
- se il campo HTML fornisce più valori, il campo dynaFormulaire sarà di tipo java.lang.String[]
Nel modulo HTML sopra riportato, solo il campo listeMultiple può essere associato a più valori (quelli selezionati dall'utente). Pertanto, una definizione iniziale dell'oggetto **dynaFormulaire** sarebbe la seguente:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
</form-bean>
In che modo dynaFormulaire verrà popolato con i valori del modulo HTML inviati dal client web?
Il campo opt riceverà il valore "yes" se è stato selezionato il campo HTML <input type="radio" name="opt" value="yes">, e il valore "no" se è stato selezionato il campo <input type="radio" name="opt" value="no">. | |
Il campo chk1 riceverà il valore "on" se è stato selezionato il campo HTML <input name="chk1" type="radio" value="1">; in caso contrario, non riceverà nulla. In quest'ultimo caso, il campo chk1 manterrà il suo valore precedente. | |
stesso | |
uguale | |
Il campo `champSaisie` riceverà il testo inserito dall'utente nel campo HTML `<input type="text" name="champSaisie">`. Questo testo può essere una stringa vuota. | |
Il campo mdp riceverà il testo inserito dall'utente nel campo HTML <input type="password" name="mdp">. Questo testo può essere una stringa vuota. | |
Il campo inputBox riceverà il testo inserito dall'utente nel campo HTML <textarea name="inputBox">...</textarea>. Questo testo forma una singola stringa, costituita dalle righe digitate dall'utente separate l'una dall'altra dalla sequenza di caratteri "\r\n". Il testo risultante può essere, facoltativamente, una stringa vuota. | |
Il campo combo riceverà l'opzione selezionata dall'utente nel campo HTML <select name="combo" size="1">..</select>. L'opzione selezionata è quella che appare nella casella combinata. Se l'opzione HTML selezionata è del tipo <option value="XX">YY</option>, il campo combo riceverà il valore "XX". Se l'opzione HTML selezionata è del tipo <option>YY</option>, il campo combo riceverà il valore "YY". | |
Il campo simpleList riceverà l'opzione selezionata dall'utente nel campo HTML <select name="simpleList" size="..">..</select> se presente. Se non ce n'è nessuna, il campo simpleList non riceverà alcun valore e manterrà il suo valore precedente. Il valore effettivamente assegnato al campo simpleList segue le regole specificate per la casella combinata. | |
Il campo listeMultiple di tipo String[] riceverà le opzioni selezionate dall'utente nel campo HTML <select name="listeMultiple" size=".." multiple>..</select>, se presenti. In assenza di opzioni, l'array listeMultiple non riceverà alcun valore e il suo contenuto rimarrà invariato. I valori effettivamente assegnati all'array listeMultiple seguono le regole specificate per la casella combinata. | |
Il campo secret riceverà il valore XX dal campo HTML <input type="hidden" name="secret" value="XX">. Questo testo può essere facoltativamente una stringa vuota. |
- L'oggetto dynaFormulaire viene utilizzato per fornire il contenuto iniziale della vista n. 1. I valori dei campi precedenti saranno utilizzati per i seguenti scopi:
deve avere il valore "yes" o "no" in modo che il browser sappia quale pulsante di opzione selezionare | |
Se chk1 ha il valore "on", la casella di controllo sarà selezionata; altrimenti, non lo sarà | |
idem | |
uguale | |
il valore del campo verrà visualizzato nel campo di immissione fieldInput | |
il valore del campo verrà visualizzato nel campo di immissione mdp | |
il valore del campo verrà visualizzato nella casella di immissione inputBox | |
Il valore di questo campo indica quale voce della casella combinata deve essere selezionata quando viene visualizzato il modulo | |
same | |
I valori nell'array multipleList indicano quali elementi dell'elenco multiplo devono essere selezionati quando viene visualizzato il modulo | |
Il valore del campo verrà assegnato all'attributo value del campo HTML secret. |
La vista n. 1 richiede ulteriori informazioni:
- l'elenco dei valori da visualizzare nell'elenco a discesa
- l'elenco dei valori da visualizzare nell'elenco `listeSimple`
- l'elenco dei valori da visualizzare nell'elenco multipleList
Esistono diversi modi per fornire queste informazioni alla vista. Ad esempio, funzionerebbero gli array inseriti nella richiesta passata alla vista. In questo caso, inseriamo questi array nel bean dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Il modulo dynaFormulaire verrà inizializzato dall'azione /init, che richiamerà un oggetto derivato da Action denominato InitFormulaireAction. Questo oggetto avrà il compito di creare i tre array necessari per visualizzare i tre elenchi e di inserirli nel bean dynaFormulaire. Il file di configurazione imposta l'ambito di questo bean su session. Di conseguenza, il controller Struts inserirà questo bean nella sessione. Non sarà quindi necessario rigenerarlo tra i cicli richiesta-risposta. Di conseguenza, l'azione /init verrà chiamata una sola volta.
- L'oggetto dynaFormulaire viene utilizzato anche per popolare la vista n. 2. Questa vista si limita a visualizzare i valori.
6.3.5. Azioni dell'applicazione
Le azioni sono gestite da oggetti di tipo Action o tipi derivati. La configurazione delle azioni viene effettuata all'interno dei tag <action-mappings>:
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
Si noti che non sempre a un'azione è associato un modulo. È il caso, nell'esempio sopra riportato, dell'azione /affiche. Prima di descrivere in dettaglio ciascuna azione, rivediamo come funziona la coppia azione-modulo all'interno di un tag <action>:
- Un'azione inizia con una richiesta proveniente da un client web e termina con l'invio di una pagina di risposta. Questo è il ciclo client-server di richiesta-risposta web. La richiesta viene ricevuta dal controller Struts di tipo ActionServlet o da una classe derivata. Questo controller invia anche la risposta.
- Il bean del modulo di tipo ActionForm o una classe derivata viene creato se non esiste già. Il controller verifica se riesce a trovare un oggetto denominato name nell'ambito specificato da scope. In caso affermativo, lo utilizza. In caso contrario, lo crea e lo inserisce nell'ambito specificato da scope, associato all'attributo specificato da name.
Nell'esempio dell'azione /init, ad esempio, il controller chiamerà request.getSession().getAttribute("dynaFormulaire") per determinare se dynaFormulaire è già stato creato o meno. In caso contrario, lo creerà e lo aggiungerà alla sessione utilizzando un'istruzione come request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- Il controller cercherà anche un oggetto Action del tipo specificato dall'attributo type. Se non ne trova uno, lo crea; altrimenti, lo utilizza.
- Verrà chiamato il metodo reset del bean del modulo. Questo bean, tranne che durante la sua creazione iniziale, viene riutilizzato. Contiene quindi dati che potresti voler "ripulire". Ciò viene fatto nel metodo reset del bean ActionForm o di una classe derivata.
- Se l'azione è la destinazione di un modulo inviato, i valori del modulo presenti nella richiesta del client vengono copiati nei campi con lo stesso nome nel bean del modulo. Si noti che il metodo reset è stato chiamato prima di questa copia.
- Se la configurazione specifica l'attributo validate="true", verrà chiamato il metodo validate del bean del modulo. Questo metodo deve quindi convalidare i dati nel bean. Questa convalida avviene in genere solo quando il modulo ha appena ricevuto nuovi dati tramite un modulo inviato e si desidera verificare la validità di tali dati. Questo metodo restituisce un elenco di errori al controller in un oggetto ActionErrors.
- Se l'oggetto ActionErrors non è vuoto, il controller visualizza la vista specificata dall'attributo input dell'azione.
- Se la convalida dei dati non è richiesta o se ha avuto esito positivo, il controller chiama il metodo `execute` dell'oggetto `Action` (o di una classe derivata) associato all'azione corrente. È all'interno di questo metodo che viene elaborata la richiesta del client web. Il metodo `execute` restituisce un oggetto `ActionForward` indicizzato da chiavi stringa. Queste chiavi sono quelle dichiarate dai tag `forward` dell'azione configurata. Nel nostro esempio, l'azione `/init` ha un unico tag `forward`. Esso associa la chiave "displayForm" alla vista `form.jsp`.
- Il controller visualizza la vista associata alla chiave ricevuta. Questa vista può essere a sua volta un'azione, nel qual caso il processo precedente viene ripetuto.
L'azione /init
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
- L'azione /init si verifica normalmente una volta durante il primo ciclo richiesta-risposta quando l'utente richiede l'URL http://localhost:8080/formulaire2/init.do
- L'oggetto dynaForm viene creato o riciclato. Viene recuperato (riciclaggio) o inserito (creazione) nella sessione come specificato dall'attributo scope.
- Viene chiamato il suo metodo reset. Cosa dovrebbe fare? Normalmente, i campi dell'oggetto ActionForm vengono reimpostati ai valori predefiniti. Tuttavia, in questo caso, non lo faremo, perché l'oggetto dynaFormulaire viene inserito nella sessione (scope="session"). I campi di dynaFormulaire devono quindi mantenere i loro valori. Quali sono questi valori durante la creazione iniziale dell'oggetto dynaFormulaire? Ci sono due casi:
- il campo ha un valore iniziale specificato nel file di configurazione:
In questo caso, il controller Struts creerà questo campo con questo valore iniziale.
- il campo non ha un valore iniziale specificato nella configurazione: si applicano le regole di inizializzazione di Java. In generale, i campi numerici avranno il valore zero, le stringhe avranno la stringa vuota e gli altri oggetti avranno il valore null.
Diamo un'occhiata alla configurazione iniziale di dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
I valori iniziali dei campi dynaFormulaire dopo la creazione saranno i seguenti:
Campo | Valore iniziale |
"no" | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
array di stringhe vuote | |
"xxx" | |
array di stringhe vuote |
- Si potrebbe immaginare che il metodo reset di dynaFormulaire assegni valori ai tre array che popolano le tre liste nella vista formulaire.jsp. Ciò sarebbe possibile in questo caso poiché i dati in questi tre array vengono generati in modo arbitrario. Tuttavia, lo scenario più comune è che questi dati provengano dal modello dell'applicazione, la M in MVC. Qui, per mantenere l'esempio semplice, adotteremo una via di mezzo, facendo generare questi valori dall'azione InitFormulaireAction, ovvero dalla C in MVC.
- Non è necessario scrivere un metodo reset in dynaFormulaire, poiché la classe ActionForm da cui deriva dispone già di un metodo di questo tipo che non esegue alcuna operazione (nessuna inizializzazione).
- Una volta chiamato il metodo reset di dynaFormulaire, il controller controlla l'attributo validate dell'azione. In questo caso, ha il valore "false". Il metodo validate di dynaFormulaire non verrà chiamato.
- L'oggetto InitFormulaireAction viene creato o riutilizzato se già esisteva, e viene chiamato il suo metodo execute. Questo metodo assegna valori arbitrari ai tre array di dynaFormulaire: valeursCombo, valeursListeSimple e valeursListeMultiple. Il metodo restituisce un ActionForward con la chiave "afficherFormulaire".
- Il controller visualizza la vista /vues/formulaire.jsp, che è stata associata alla chiave "afficherFormulaire" tramite un tag forward dall'azione /init.
L'azione /confirmation
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- L'azione /confirmation si verifica quando l'utente fa clic sul pulsante [Invia] nella vista n. 1. Il browser quindi "invia" il modulo compilato dall'utente al controller Struts.
- L'oggetto dynaFormulaire viene recuperato dalla sessione
- viene chiamato il suo metodo reset. Una volta chiamato, il controller Struts copierà i valori dei campi del modulo inviati dal client nei campi con lo stesso nome in dynaFormulaire. Esaminiamo l'elenco dei campi in dynaFormulaire e vediamo come funziona questa copia:
Campo | Codice HTML associato | Valore del campo dopo la copia dei valori del modulo |
<input type="radio" name="opt" value="yes">Sì <input type="radio" name="opt" value="no" checked="checked">No | - "sì" o "no" a seconda del pulsante di opzione selezionato | |
<input type="checkbox" name="chk1" value="on"> | - "on" se la casella di controllo chk1 è stata selezionata - mantiene il valore precedente se la casella di controllo chk1 non è stata selezionata | |
<input type="checkbox" name="chk2" value="on"> | - "on" se la casella di controllo chk2 è stata selezionata - mantiene il valore precedente se la casella di controllo chk2 non è stata selezionata | |
<input type="checkbox" name="chk2" value="on"> | - "on" se la casella di controllo chk3 è stata selezionata - mantiene il valore precedente se la casella di controllo chk3 non è stata selezionata | |
<input type="text" name="inputField" value=""> | - valore inserito dall'utente in inputField | |
<input type="password" name="password" value=""> | - valore inserito dall'utente nel campo password | |
<textarea name="inputBox"></textarea> | - valore inserito dall'utente nella casella di testo | |
<select name="combo">...</select> | - valore selezionato dall'utente nel menu a tendina | |
<select name="simpleList" size="3">...</select> | - valore selezionato dall'utente in simpleList | |
<select name="listeMultiple" multiple="multiple" size="5"> | - array di stringhe contenente i valori selezionati dall'utente in multipleList | |
<input type="hidden" name="secret" value="xxx"> | - "xxx". |
Si verifica un problema con i campi che non ricevono necessariamente un valore nella richiesta inviata dal browser. Ciò vale per le caselle di controllo da chk1 a chk3 e per i due elenchi listeSimple e listeMultiple. In questo caso, questi campi mantengono i valori precedenti, ovvero quelli acquisiti durante il ciclo di richiesta-risposta precedente.
Prendiamo ad esempio la casella di controllo chk1 e supponiamo che, nel ciclo di richiesta-risposta precedente, l'utente l'abbia selezionata. Il browser ha quindi inviato l'informazione chk1="on" nella stringa dei parametri della sua richiesta. Il costruttore ha quindi assegnato il valore "on" al campo chk1 di dynaFormulaire. Supponiamo ora che, nel ciclo corrente, l'utente non selezioni la casella di controllo chk1. In questo caso, nella stringa dei parametri della nuova richiesta, il browser non invia qualcosa come chk1="off", ma non invia nulla. Di conseguenza, il campo chk1 in dynaFormulaire manterrà il suo valore "on" e avrà quindi un valore che non riflette quello del modulo convalidato dall'utente. Useremo il metodo reset di dynaFormulaire per risolvere questo problema. In questo metodo, imposteremo i tre campi chk1, chk2 e chk3 su "off". Nel nostro esempio chk1, l'utente:
- selezionerà la casella di controllo chk1. In questo caso, il browser invierà l'informazione chk1="on" e il campo chk1 in dynaFormulaire passerà a "on"
- non seleziona la casella di controllo chk1. In questo caso, il browser non invia alcun valore per il campo chk1, che manterrà il suo valore precedente "off". In entrambi i casi, il valore memorizzato nel campo chk1 di dynaFormulaire è corretto.
Il problema è simile sia per l'elenco simpleList che per quello multiList. Se in questi elenchi non è stata selezionata alcuna opzione, essi non saranno presenti nei parametri della richiesta e manterranno quindi i loro valori precedenti. Nel metodo reset di dynaFormulaire, reimposteremo simpleList con una stringa vuota e multiList con un array di stringhe di lunghezza 0.
- Una volta chiamato il metodo reset di dynaFormulaire, il controller ricopia le informazioni che gli sono state inviate nella richiesta del client nei campi di dynaFormulaire
- Viene creato o riutilizzato un oggetto ForwardAction e viene chiamato il suo metodo execute. ForwardAction è una classe predefinita che restituisce un oggetto ActionForward che punta alla vista definita dall’attributo “parameter” dell’azione, in questo caso /vues/confirmation.jsp.
- Il controller invia questa vista. Il ciclo è completo.
Il /display
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- L'azione /display viene attivata cliccando sul link [Torna al modulo] nella vista n. 2.
- In questo caso, non vi è alcun modulo associato all'azione. Si procede quindi direttamente all'esecuzione del metodo `execute` di un oggetto `ForwardAction`, che restituirà un oggetto `ActionForward` puntante alla vista `/vues/formulaire.jsp`.
6.3.6. Il file dei messaggi dell'applicazione
La terza sezione del file struts-config.xml è il file dei messaggi:
Il file ApplicationResources.properties si trova in WEB-INF/classes. Sarà vuoto. Anche se è vuoto, deve comunque essere dichiarato nel file di configurazione; altrimenti, la libreria di tag struts-bean, di cui parleremo più avanti, genererà un errore. Questa libreria viene utilizzata dalla vista confirmation.jsp.
6.4. Il codice della vista
6.4.1. La vista formulaire.jsp
Ricordate che questa vista viene visualizzata in due casi:
- quando viene chiamata l'azione /init durante il primo ciclo richiesta-risposta
- quando viene chiamata l'azione /affiche durante i cicli successivi
Il codice della vista formulaire.jsp è il seguente:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
<title>formulaire</title>
</head>
<body background='<html:rewrite page="/images/standard.jpg"/>'>
<h3>Formulaire Struts</h3>
<hr>
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<table border="0">
<tr>
<td>bouton radio</td>
<td>
<html:radio name="dynaFormulaire" property="opt" value="oui">Oui</html:radio>
<html:radio name="dynaFormulaire" property="opt" value="non">Non</html:radio>
</td>
</tr>
<tr>
<td>Cases à cocher</td>
<td>
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk3">3</html:checkbox>
</td>
</tr>
<tr>
<td>Champ de saisie</td>
<td>
<html:text name="dynaFormulaire" property="champSaisie" />
</td>
</tr>
<tr>
<td>Mot de passe</td>
<td>
<html:password name="dynaFormulaire" property="mdp" />
</td>
</tr>
<tr>
<td>Boîte de saisie multilignes</td>
<td>
<html:textarea name="dynaFormulaire" property="boiteSaisie" />
</td>
</tr>
<tr>
<td>Combo</td>
<td>
<html:select name="dynaFormulaire" property="combo">
<html:options name="dynaFormulaire" property="valeursCombo"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection unique</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
</td>
</tr>
</table>
<td>
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection multiple</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
</td>
</tr>
</table>
</td>
<td>
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
</td>
</tr>
</table>
<html:hidden name="dynaFormulaire" property="secret"/>
<br>
<hr>
<html:submit>Envoyer</html:submit>
</html:form>
</body>
</html>
Questa pagina JSP utilizza i tag della libreria struts-html. Ricorda che per utilizzare una libreria di tag devi:
- dichiararla nel file web.xml dell'applicazione utilizzando un tag <tag-lib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- Inserisci il codice di questa libreria in una posizione qualsiasi all'interno dell'albero delle directory dell'applicazione, in questo caso WEB-INF/struts-html.tld
- Dichiarare l'uso di questa libreria all'inizio delle pagine JSP che la utilizzano:
La vista formulaire.jsp utilizza tag che spiegheremo ora:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
Il tag html:rewrite consente di omettere il nome dell'applicazione dagli URL. Ha un solo attributo:
Quindi, nell'esempio sopra riportato, se si decide di chiamare l'applicazione "form3", non è necessario riscrivere il codice dell'attributo background. Il tag `html:rewrite` genererà il nuovo codice HTML background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
Il tag html:form genera il tag HTML form. Ha diversi attributi:
Possiamo notare che, per impostazione predefinita, il codice HTML generato utilizza il metodo POST. Nello stesso codice HTML, l'URL dell'azione è stato riscritto in modo da essere preceduto dal nome dell'applicazione e seguito dal suffisso .do. |
<html:radio name="dynaFormulaire" property="opt" value="yes">Sì</html:radio> | |||||||
Il tag html:radio viene utilizzato per generare il tag HTML <input type="radio" ...>. Supporta vari attributi:
Il testo tra i tag di inizio e fine è il testo che verrà visualizzato accanto al pulsante di opzione. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
Il tag html:checkbox viene utilizzato per generare il tag HTML <input type="checkbox" ...>. Supporta vari attributi:
Il testo tra i tag di inizio e fine è il testo che verrà visualizzato accanto alla casella di controllo. |
<html:text name="dynaFormulaire" property="inputField" /> | |||||||
Il tag html:text viene utilizzato per generare il tag HTML <input type="text" ...>. Supporta vari attributi:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
Il tag html:password viene utilizzato per generare il tag HTML <input type="password" ...>. Supporta vari attributi: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
Il tag HTML:textarea viene utilizzato per generare il tag HTML <textarea>...</textarea>. Supporta vari attributi:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
Il tag HTML:select viene utilizzato per generare il tag HTML <select>...</select>. Supporta vari attributi:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="comboValues"/> </html:select> | |||||
Il tag HTML:options viene utilizzato per generare i tag HTML <option>...</option> all'interno di un tag HTML <select>. Esistono vari modi per specificare come trovare i valori con cui popolare l'elemento select. In questo caso, abbiamo utilizzato gli attributi name e property:
|
Gli altri due elenchi vengono generati in modo simile al precedente:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
Sopra, specifichiamo un attributo size diverso da 1 per creare un elenco anziché una casella combinata.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
Sopra, specifichiamo l'attributo multiple="true" per creare un elenco con selezioni multiple.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
Il tag html:hidden viene utilizzato per generare il tag HTML <input type="hidden" ...>.
|
Per comprendere appieno la relazione tra la vista formulaire.jsp** e il bean dynaFormulaire che la rappresenta in memoria, è importante ricordare che il bean dynaFormulaire** viene utilizzato sia per la lettura che per la scrittura:
![]() |
La richiesta avviene quando l'utente clicca sul pulsante [Invia] nel modulo. Il browser quindi "invia" il modulo HTML all'azione /confirmation. Abbiamo già spiegato cosa succede in seguito, e in particolare che i campi dynaFormulaire riceveranno i valori dei campi con lo stesso nome nel modulo HTML.
Cosa succede quando il controller richiede la visualizzazione della pagina formulaire.jsp in risposta a una richiesta? Diamo un'occhiata più da vicino ai tag uno per uno:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
genera il codice HTML |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
genera il codice HTML |
<html:radio name="dynaFormulaire" property="opt" value="yes">Sì</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">No</html:radio> | |
Se il campo opt di dynaFormulaire è "yes", genera il codice HTML |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> <html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox> <html:checkbox name="dynaForm" property="chk3">3</html:checkbox> | |
Se i campi chk1 e chk3 di dynaFormulaire sono "on" e il campo chk2 è "off", generare il codice HTML |
<html:text name="dynaFormulaire" property="inputField" /> | |
se il campo di immissione è impostato su "this is a test", genera il codice HTML |
<html:password name="dynaFormulaire" property="password" /> | |
se il campo della password è "azerty", genera il codice HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
Se il campo "mdp" è "azerty", genera il codice HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
Se il campo "mdp" è "azerty", genera il codice HTML |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="comboValues"/> </html:select> | |
se il campo a discesa è "combo2", genera il codice HTML |
<html:select name="dynaFormulaire" property="simpleList" size="3"> <html:options name="dynaFormulaire" property="simpleListValues"/> </html:select> | |
se il campo simpleList è "simple1", genera il codice HTML |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="multipleListValues"/> </html:select> | |
Se il campo listeMultiple è l'array {"multiple0", "multiple2"}, genera il codice HTML |
<html:hidden name="dynaFormulaire" property="secret"/> | |
se il campo segreto ha il valore "xxx", genera il codice HTML |
<html:submit>Invia</html:submit> | |
genera il codice HTML |
L'ultima cosa da spiegare è il codice JavaScript incluso nella pagina JSP e associato ai due pulsanti [Clear] che deselezionano gli elementi selezionati nelle liste simpleList e multipleList:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Il tag
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
genera il seguente codice HTML:
Per comprendere il codice JavaScript associato ai pulsanti [Cancella], rivediamo come i vari elementi di un documento web vengono referenziati all'interno del codice JavaScript che utilizza quel documento:
Dati | Significato |
si riferisce all'intero documento web | |
si riferisce all'insieme dei moduli definiti nel documento | |
si riferisce al modulo numero i nel documento | |
si riferisce al modulo <form> con l'attributo name impostato su "formName" | |
si riferisce al modulo <form> con l'attributo name uguale a "formName" | |
si riferisce alla raccolta di elementi appartenenti al modulo designato dall'espressione [form]. Questa raccolta include tutti i tag <input>, <textarea> e <select> nel modulo designato. | |
si riferisce all'elemento numero i di [form] | |
si riferisce all'elemento in [form] il cui attributo name è uguale a componentName | |
si riferisce all'elemento nel [form] il cui attributo name è uguale a componentName | |
si riferisce al valore del componente [component] del modulo [form] quando il suo codice HTML può avere un attributo value (<input>, <textarea>) | |
si riferisce all'indice dell'opzione selezionata in un elenco. Può essere utilizzato sia per la lettura che per la scrittura. Impostando questa proprietà su -1 si deseleziona tutti gli elementi dell'elenco. | |
si riferisce all'array di opzioni associate a un tag <select> | |
si riferisce all'opzione numero i del tag <select> specificato | |
Un valore booleano che indica se l'opzione n. i dell'elemento [select] specificato è selezionata (true) o meno. Può essere utilizzato sia per la lettura che per la scrittura |
Rivediamo il codice JavaScript per i due pulsanti:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Quando si clicca sul pulsante, viene eseguito il codice associato all'attributo "onclick". In questo caso, si tratta di codice inline. Molto spesso, scriviamo onclick="function(...)", dove function è una funzione definita all'interno di un tag <script language="javascript">...</script>. Cosa fa il codice sopra riportato? Analizziamo il codice del primo pulsante:
si riferisce al documento web in cui si trova il pulsante | |
si riferisce al modulo in cui si trova il pulsante | |
si riferisce al componente simpleList del modulo | |
si riferisce all'indice dell'opzione selezionata in listeSimple. Impostando questa proprietà su -1 si deselezionano tutte le opzioni. |
6.4.2. La vista confirmation.jsp
Ricordiamo che questa vista viene visualizzata dopo l'azione /confirmation, ovvero dopo che il modulo contenuto nella vista formulaire.jsp è stato inviato dal client web. Il suo unico scopo è quello di visualizzare i valori inseriti dall'utente. Il suo codice è il seguente:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
<title>Confirmation</title>
</head>
<body background="<html:rewrite page="/images/standard.jpg"/>">
<h3>Confirmation des valeurs saisies</h3>
<hr/>
<table border="1">
<tr>
<td>Bouton radio</td>
<td><bean:write name="dynaFormulaire" scope="session" property="opt"/></td>
</tr>
<tr>
<td>Case à cocher chk1</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk1"/></td>
</tr>
<tr>
<td>Case à cocher chk2</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk2"/></td>
</tr>
<tr>
<td>Case à cocher chk3</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk3"/></td>
</tr>
<tr>
<td>Champ de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="champSaisie"/></td>
</tr>
<tr>
<td>Mot de passe</td>
<td><bean:write name="dynaFormulaire" scope="session" property="mdp"/></td>
</tr>
<tr>
<td>Boîte de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="boiteSaisie"/></td>
</tr>
<tr>
<td>combo</td>
<td><bean:write name="dynaFormulaire" scope="session" property="combo"/></td>
</tr>
<tr>
<td>liste simple</td>
<td><bean:write name="dynaFormulaire" scope="session" property="listeSimple"/></td>
</tr>
<logic:iterate id="choix" indexId="index" name="dynaFormulaire" property="listeMultiple">
<tr>
<td>liste multiple[<bean:write name="index"/>]</td>
<td><bean:write name="choix"/></td>
</tr>
</logic:iterate>
</table>
<br>
<html:link page="/affiche.do">
Retour au formulaire
</html:link>
</body>
</html>
Qui introduciamo due nuove librerie di tag: struts-bean e struts-logic. La libreria struts-bean fornisce l'accesso agli oggetti nel contesto della richiesta, della sessione o dell'applicazione. La libreria struts-logic consente di implementare la logica di esecuzione utilizzando i tag. Nessuna di queste librerie è strettamente necessaria. Come abbiamo visto, una pagina JSP può:
- recuperare oggetti dalla richiesta (request.getAttribute(...)), dalla sessione (session.getAttribute(...)) o dal contesto dell'applicazione
- includere elementi dinamici nel codice HTML utilizzando variabili <%= variabile %>
- contenere codice Java <% codice Java %>
L'inclusione di codice Java nelle pagine JSP infastidisce coloro che preferiscono una separazione rigorosa tra la logica dell'applicazione (codice Java) e la presentazione (uso dei tag). Ecco perché sono state create le librerie di tag.
Procederemo come abbiamo fatto per la vista formulaire.jsp** e spiegheremo ciascuno dei tag presenti nel codice di confirmation.jsp,** qualora non fossero già stati menzionati nella vista **formulaire.jsp**. Innanzitutto, si noti che la pagina inizia dichiarando le tre librerie di tag che utilizzerà:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
Si noti inoltre che queste tre librerie devono essere dichiarate nel file web.xml dell'applicazione. Commenteremo ora i tag nel documento formulaire.jsp:
scrive un valore nel flusso HTML corrente. Il tag bean:write supporta i seguenti attributi: name: nome dell'oggetto da utilizzare scope: ambito (request, session, context) in cui cercare questo oggetto property: campo dell'oggetto designato da name la cui proprietà deve essere scritta. Questo campo può essere un oggetto di qualsiasi tipo. Verrà utilizzato il metodo toString dell'oggetto. Qui viene scritto il valore del campo opt in dynaFormulaire. Il risultato sarà "yes" se l'utente ha selezionato il pulsante di opzione con l'attributo value="yes", oppure "no" se ha selezionato il pulsante di opzione con l'attributo value="no" |
scrive il valore del campo chk1 in dynaFormulaire. Il risultato sarà "on" se l'utente ha selezionato la casella, oppure "off" in caso contrario. Lo stesso vale per chk2 e chk3. |
scrive il valore del campo champSaisie in dynaFormulaire, ovvero il testo digitato dall'utente in quel campo. Lo stesso vale per mdp e boiteSaisie. |
scrive il valore del campo a discesa in dynaFormulaire. Questo sarà l'attributo value dell'elemento <option> selezionato dall'utente. |
scrive il valore del campo simpleList in dynaForm. Conterrà l'attributo "value" dell'elemento <option> selezionato dall'utente, se ne è stato selezionato uno. In caso contrario, sarà una stringa vuota. |
Qui introduciamo i tag logici. Abbiamo a che fare con un elenco a scelta multipla. Il valore del campo listeMultiple dell'oggetto dynaFormulaire è un array di stringhe. In Java, scriveremmo un ciclo. Il tag logic:iterate ci permette di eseguire lo stesso ciclo senza scrivere codice Java. In questo esempio, il tag logic:iterate ha i seguenti attributi: name="dynaFormulaire": nome dell'oggetto da utilizzare property="listeMultiple": nome della proprietà nell'oggetto specificato da name che contiene la collezione su cui eseguire l'iterazione nel ciclo. In questo caso, questa collezione è l'array di valori selezionati in listeMultiple. Questo array può essere vuoto. id="choix": identificatore che designa l'elemento corrente dell'array ad ogni iterazione. Durante la prima iterazione, choix rappresenterà listeMultiple[0], durante la seconda listeMultiple[1] e così via. indexID="index": identificatore che designa l'indice dell'elemento corrente dell'array ad ogni iterazione del ciclo. Durante la prima iterazione, index avrà il valore 0; durante la seconda, il valore 1; e così via. Il codice HTML contenuto tra i tag <logic:iterate ...> e </logic:iterate> viene ripetuto per ciascun elemento della collezione designata dalla coppia (nome,proprietà). La parte dinamica di questo codice è la seguente:
In base a quanto detto in precedenza, all'iterazione numero i (i>=0), il codice HTML generato è equivalente al seguente: |
genera un link relativo al contesto dell'applicazione, il che elimina la necessità di conoscere il contesto. Il codice HTML generato da questo tag è il seguente: |
6.5. Le classi Java
Il file di configurazione struts-config.xml fa riferimento a due classi Java:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
La classe DynaFormulaire è la classe che conterrà i valori della vista n. 1, formulaire.jsp. La classe InitFormulaireAction è la classe che elaborerà i valori del modulo inviati tramite il pulsante [Invia] su formulaire.jsp.
6.5.1. La classe DynaFormulaire
Per contenere i valori di un modulo, è sufficiente un oggetto di tipo DynaActionForm, a meno che non sia necessario sovrascrivere uno dei metodi reset o validate di questa classe. In questo caso, non è necessario sovrascrivere il metodo validate poiché non viene eseguita alcuna convalida dei dati. Tuttavia, è necessario sovrascrivere il metodo reset. Questo perché i campi dell'oggetto DynaFormulaire riceveranno i loro valori dal modulo inviato dal client web. Tuttavia, alcuni campi potrebbero non ricevere un valore se non sono presenti nella richiesta. Ciò si verifica nei seguenti casi:
- una casella di controllo che non è stata selezionata dall'utente
- un elenco con più di un'opzione in cui nessuna è stata selezionata
Per i moduli contenenti questo tipo di componente, il metodo reset deve
- impostare il valore "off" per il campo associato alla casella di controllo
- impostare la stringa vuota nel campo associato a un elenco a selezione singola
- assegnare un array vuoto di stringhe al campo associato a un elenco a selezione multipla
Pertanto, se questi campi non ricevono un valore dalla query, mantengono il valore assegnato dal reset, che corrisponde allo stato del componente nel modulo convalidato dall'utente (casella di controllo deselezionata, elenco senza elementi selezionati).
Il codice per la classe DynaFormulaire, una sottoclasse di DynaActionForm, è il seguente:
package istia.st.struts.formulaire;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
public class DynaFormulaire extends DynaActionForm {
public void reset(ActionMapping mapping, HttpServletRequest request){
// reset checkboxes - value off
set("chk1","off");
set("chk2","off");
set("chk2","off");
// reset listeSimple - empty string
set("listeSimple","");
// reset listeMultiple - empty table
set("listeMultiple",new String[]{});
}
}
6.5.2. La classe InitFormAction
La classe InitFormAction è associata all'azione /init nel file struts-config.xml:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
L'azione /init viene utilizzata una sola volta durante la creazione iniziale dell'oggetto DynaForm. Il suo scopo è quello di fornire il contenuto per i tre elenchi a discesa del modulo: simpleList, multipleList e dropdownList. Questo contenuto viene fornito sotto forma di tre array, che sono proprietà dell'oggetto dynaForm:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Una volta che gli array valuesCombo, valuesSingleList e valuesMultipleList sono stati inizializzati da InitFormAction, non è più necessario inizializzarli. Questo perché l'oggetto dynaForm viene inserito nella sessione e quindi mantiene il proprio valore attraverso i cicli richiesta-risposta. Ecco perché l'azione /init viene eseguita una sola volta. Il codice per InitFormAction è il seguente:
package istia.st.struts.formulaire;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class InitFormulaireAction
extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// prepares the form to be displayed
// we put the information needed for the form in its bean
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
// we give back
return mapping.findForward("afficherFormulaire");
} //execute
// list of combo values
private String[] getValeurs(int taille, String label) {
String[] valeurs = new String[taille];
for (int i = 0; i < taille; i++) {
valeurs[i] = label + i;
}
return valeurs;
}
}
- La classe estende la classe Action. Questo è obbligatorio.
- Il controller Struts utilizza un oggetto Action tramite il suo metodo execute. Questo è quindi il metodo che deve essere ridefinito. Questo metodo riceve i seguenti parametri:
- ActionMapping mapping: un oggetto che rappresenta la configurazione dell'applicazione in struts-config.xml
- ActionForm form: il modulo associato all’azione, se ne è stato definito uno nella configurazione dell’azione (l’attributo name dell’azione).
- HttpServletRequest request: la richiesta del client
- HttpServletResponse: la risposta al client
- La classe InitFormulaireAction deve inizializzare il modulo dynaFormulaire. Questo viene passato al metodo execute come parametro del modulo ActionForm. Ricordiamo che dynaFormulaire è di tipo DynaFormulaire, una classe derivata dalla classe DynaActionForm, che a sua volta deriva dalla classe ActionForm.
- Nel metodo execute, i valori vengono assegnati ai tre campi valeursCombo, valeursListeSimple e valeursListeMultiple utilizzando il metodo set della classe DynaActionForm. Per semplicità, questi valori sono array arbitrari. Si noti che il metodo set assegna un valore a un campo esistente. Non può essere utilizzato per creare nuovi campi. Questo è il motivo per cui è necessario definire i tre campi valeursCombo, valeursListeSimple e valeursListeMultiple nella definizione dell'oggetto dynaFormulaire in struts-config.xml.
- Il metodo execute termina restituendo al controller la chiave della vista da visualizzare come risposta al client. In questo caso si tratta della chiave afficherFormulaire, che nel file struts-config.xml è stata associata alla vista /vues/formulaire.jsp.
6.6. Distribuzione
La struttura delle directory dell'applicazione è la seguente:
![]() | ![]() |
![]() | ![]() |


Si noti che il file ApplicationResources.properties sopra riportato è richiesto dalla libreria di tag struts-bean. Sappiamo che questo file contiene i messaggi dell'applicazione, ai quali la libreria struts-bean può accedere. In questo caso, la nostra applicazione non definisce alcun messaggio; pertanto, il file ApplicationResources.properties esiste ma è vuoto.
6.7. Conclusione
In questa lezione abbiamo illustrato in dettaglio come gestire i vari componenti di un modulo HTML. Ora possiamo utilizzare moduli complessi nelle nostre applicazioni Struts.






