6. Moduli HTML
Finora abbiamo utilizzato un unico modulo composto da soli due campi di immissione dati. In questa sede ci proponiamo di creare e gestire un modulo utilizzando i componenti grafici più comuni (pulsanti di opzione, caselle di controllo, campi di immissione dati, caselle a discesa, elenchi).
6.1. Le viste dell’applicazione
L’applicazione avrà solo due viste. La prima presenta un modulo vuoto:
QZXW2HTMLP000547ZQX 1 - formulaire

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

Il pulsante [Envoyer] consente di ottenere una conferma dei 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 [Retour au formulaire] ci permette di tornare al modulo così come è stato compilato. Si torna quindi alla prima vista.
6.2. L’architettura dell’applicazione
![]() |
- Il modulo (vista 1) sarà rappresentato da un oggetto Struts dinamico denominato dynaFormulaire, di tipo derivato da DynaActionForm. Verrà visualizzato dalla vista formulaire.jsp.
- L’azione Struts InitFormulaireAction avrà lo scopo di acquisire i dati necessari per la visualizzazione del modulo
- il modulo compilato verrà elaborato dall’azione ForwardAction, che si limiterà a reindirizzare la richiesta alla seconda vista confirmation.jsp. Quest’ultima si occuperà di visualizzare i valori del modulo.
6.3. La configurazione dell’applicazione
6.3.1. Il file server.xml
Il contesto dell’applicazione si chiamerà /formulaire2. Aggiungeremo quindi la seguente riga nel file server.xml di Tomcat:
Fatto ciò, se necessario, riavviamo 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 già incontrati, apportiamo alcune modifiche:
- introduciamo due nuove librerie di tag: struts-bean e struts-logic. Queste saranno utilizzate nella vista confirmation.jsp. La vista formulaire.jsp utilizzerà invece la libreria struts-html.
6.3.3. Il file struts-config.xml
Il file struts-config.xml sarà invece 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>
Qui si trovano le 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-ressources>
6.3.4. Gli oggetti (bean) dei moduli dell'applicazione
Gli oggetti utilizzati per rappresentare i moduli HTML dell'applicazione sono oggetti di tipo ActionForm o derivati (DynaActionForm, DynaValidatorForm, ...). Vengono chiamati bean perché la loro struttura segue le regole dei JavaBeans. Nella nostra applicazione è presente un solo bean del modulo, denominato dynaFormulaire e di tipo derivato da DynaActionForm. Verrà utilizzato nelle seguenti situazioni:
- contenere i dati necessari per la visualizzazione della vista n. 1
- recuperare i valori del modulo della vista n. 1 quando l’utente lo invia (submit)
- contenere i dati necessari per la visualizzazione della vista n. 2
La struttura del bean dynaFormulaire è strettamente legata al modulo della vista n. 1. Esaminiamolo:
![]() |
N. | Tipo HTML | Ruolo |
<input name="opt" type="radio" value="sì"> <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 indipendenti (non hanno lo stesso nome) | |
<input type="text" name="champSaisie" > | un campo di immissione | |
<input type="password" name="mdp"> | un campo password | |
<textarea name="boiteSaisie">...</textarea> | un campo di immissione multilinea | |
<select name="combo" size="1">..</select> | un menu a tendina | |
<select name="listeSimple" 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='effacerListe("listeSimple")'> | pulsante che consente di deselezionare gli elementi selezionati in listeSimple (7) | |
<input type="button" value="Cancella" onclick='effacerListe("listeMultiple")'> | pulsante che consente di deselezionare gli elementi selezionati in listeMultiple (8) | |
<input type="submit" value="Invia"> | pulsante di invio del modulo | |
<input type="hidden" name="secret" value="..."> | un campo nascosto |
Distinguiamo diversi casi:
- l'oggetto dynaFormulaire viene utilizzato per contenere i valori del modulo HTML sopra riportato, che verrà inviato tramite il pulsante [Envoyer]. Deve quindi avere gli stessi campi presenti nel modulo HTML. Il tipo di campo è determinato dalla seguente regola:
- se il campo HTML fornisce un solo valore, allora il campo di dynaFormulaire sarà di tipo java.lang.String
- se il campo HTML fornisce più valori, allora il campo di 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 prima definizione 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>
Come avverrà il popolamento di dynaFormulaire con i valori del modulo HTML inviati dal client web?
il campo «opt» riceverà il valore «sì» se è stato selezionato il campo HTML <input type="radio" name="opt" value="sì">, il valore «no» se è stato selezionato il campo <input type="radio" name="opt" value="no">. | |
il campo chk1 assumerà il valore "on" se è stato selezionato il campo HTML <input name="chk1" type="radio" value="1">, altrimenti non assumerà alcun valore. In quest’ultimo caso, il campo chk1 manterrà il suo valore precedente. | |
idem | |
idem | |
il campo champSaisie riceverà il testo inserito dall'utente nel campo HTML <input type="text" name="champSaisie">. Tale testo può eventualmente essere una stringa vuota. | |
il campo mdp riceverà il testo inserito dall'utente nel campo HTML <input type="password" name="mdp">. Tale testo può eventualmente essere una stringa vuota. | |
Il campo boiteSaisie riceverà il testo inserito dall'utente nel campo HTML <textarea name="boiteSaisie">...</textarea>. Questo testo costituisce un'unica stringa di caratteri, formata dalle righe digitate dall'utente e separate l'una dall'altra dalla sequenza di caratteri "\r\n". Il testo ottenuto può eventualmente essere una stringa vuota. | |
il campo a discesa riceverà l’opzione selezionata dall’utente nel campo HTML <select name="combo" size="1">..</select>. L’opzione selezionata è quella che appare nel campo a discesa. Se l’opzione HTML selezionata è del tipo <option value="XX">YY</option>, il campo a discesa riceverà il valore "XX". Se l’opzione HTML selezionata è del tipo <option>YY</option>, il campo a discesa riceverà il valore "YY". | |
il campo listeSimple riceverà l’opzione selezionata dall’utente nel campo HTML <select name="listeSimple" size="..">..</select> se presente. Se non ce n’è nessuna, il campo listeSimple non riceverà alcun valore e manterrà il valore precedente. Il valore effettivamente assegnato al campo listeSimple segue le regole indicate per il menu a tendina. | |
il campo listeMultiple di tipo String[] riceverà le opzioni selezionate dall’utente nel campo HTML <select name="listeMultiple" size=".." multiple>..</select> se presenti. Se non ce ne sono, l'array listeMultiple non riceverà alcun valore e il suo contenuto rimarrà invariato. I valori effettivamente assegnati all'array listeMultiple seguono le regole indicate per il menu a tendina. | |
il campo «secret» riceverà il valore XX dal campo HTML <input type="hidden" name="secret" value="XX">. Questo testo può eventualmente essere 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:
dovrà avere il valore "sì" o "no" affinché 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 | |
idem | |
il valore del campo verrà visualizzato nell'area di immissione champSaisie | |
il valore del campo verrà visualizzato nel campo di immissione password | |
il valore del campo verrà visualizzato nel campo di immissione boiteSaisie | |
il valore di questo campo indica quale elemento del menu a tendina deve essere selezionato alla visualizzazione del modulo | |
idem | |
i valori della tabella listeMultiple indicano quali elementi dell'elenco multiplo devono essere selezionati al momento della visualizzazione del modulo | |
il valore del campo verrà assegnato all'attributo "value" del campo segreto HTML. |
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 listeMultiple
Esistono diversi modi per fornire queste informazioni alla vista. Ad esempio, potrebbero andare bene delle tabelle inserite nella query passata alla vista. In questo caso, inseriamo queste tabelle 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. Sarà questo oggetto a occuparsi di creare i tre array necessari per la visualizzazione dei tre elenchi e di inserirli nel bean dynaFormulaire. Il file di configurazione assegna a questo bean un ambito pari alla sessione. Ciò comporta che il controller Struts inserirà questo bean nella sessione. In questo modo non sarà necessario rigenerarlo tra un ciclo richiesta-risposta e l’altro. Pertanto, l’azione /init verrà chiamata una sola volta.
- L’oggetto dynaFormulaire viene utilizzato anche per fornire il contenuto della vista n. 2. Quest’ultima si limita a visualizzarne i valori.
6.3.5. Le azioni dell’applicazione
Le azioni sono gestite da oggetti di tipo Action o derivati. La configurazione delle azioni avviene 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, ricordiamo il funzionamento della coppia azione-modulo associata all'interno di un tag <action>:
- un'azione inizia con una richiesta da parte di un client web e termina con l'invio di una pagina di risposta. Si tratta del ciclo richiesta-risposta del client-server web. La richiesta viene ricevuta dal controller Struts di tipo ActionServlet o derivato. È lo stesso controller che invia la risposta.
- Il bean del modulo di tipo ActionForm o derivato viene creato se non esiste già. Il controller verifica se riesce a trovare un oggetto con il nome name nell’ambito indicato da scope. In caso affermativo, lo utilizza. In caso contrario, lo crea e lo inserisce nell’ambito indicato da scope, associandolo all’attributo indicato da name.
Nell’esempio dell’azione /init, ad esempio, il controller eseguirà un request.getSession().getAttribute("dynaFormulaire") per verificare se dynaFormulaire sia già stato creato o meno. Se così non fosse, lo creerà e lo inserirà nella sessione tramite un’istruzione del tipo request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- Il controller cercherà inoltre un oggetto Action del tipo indicato dall’attributo type. Se non lo trova, lo crea; altrimenti lo utilizza.
- Verrà chiamato il metodo reset del bean del modulo. Quest’ultimo, tranne che al momento della sua creazione iniziale, viene riciclato. Contiene quindi dati che si potrebbe voler “ripulire”. È nel metodo reset del bean ActionForm o derivato che si effettuerà questa operazione.
- Se l'azione è la destinazione di un modulo inviato tramite POST, i valori del modulo presenti nella richiesta del client vengono copiati nei campi con lo stesso nome del 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. Quest'ultimo dovrà quindi verificare i dati del bean. Questa verifica avviene solitamente solo quando il modulo ha appena ricevuto nuovi dati tramite un form inviato con il metodo POST e si desidera verificarne la validità. Questo metodo restituisce al controller un eventuale elenco di errori in un oggetto ActionErrors.
- Se l’oggetto ActionErrors non è vuoto, il controller fa visualizzare la vista specificata dall’attributo input dell’azione.
- Se la convalida dei dati non è richiesta o se è stata eseguita con successo, il controller fa eseguire il metodo `execute` dell’oggetto di tipo `Action` o derivato associato all’azione in corso. È all’interno di questo metodo che viene elaborata la richiesta del client web. Il metodo `execute` restituisce un oggetto ActionForward indicizzato da chiavi di tipo stringa di caratteri. Queste chiavi sono quelle dichiarate dai tag forward dell’azione configurata. Nel nostro esempio, l’azione /init ha un unico tag forward. Essa associa la chiave "afficherFormulaire" alla vista formulaire.jsp.
- il controller fa visualizzare la vista a cui è associata la 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 avviene normalmente una volta durante il primo ciclo richiesta-risposta quando l'utente richiede l'http://localhost:8080/formulaire2/init.do URL
- viene creato o riciclato l’oggetto dynaFormulaire. Esso viene recuperato (riciclaggio) o inserito (creazione) nella sessione come richiesto dall’attributo scope.
- Viene chiamato il suo metodo reset. Cosa deve fare? Normalmente, i campi dell’oggetto ActionForm vengono reimpostati ai valori predefiniti. Solo che in questo caso non lo faremo, poiché l’oggetto dynaFormulaire viene inserito nella sessione (scope="session"). I campi di dynaFormulaire devono quindi mantenere i propri valori. Quali sono questi valori al momento della creazione iniziale dell’oggetto dynaFormulaire? Esistono due casi:
- il campo ha un valore iniziale specificato nel file di configurazione:
In questo caso, il controller Struts creerà questo campo con tale 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 di caratteri avranno come valore la stringa vuota, mentre gli altri oggetti avranno il valore null.
Esaminiamo la 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 di dynaFormulaire dopo la sua creazione saranno i seguenti:
Campo | Valore iniziale |
"no" | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
stringa vuota | |
tabella di stringhe vuote | |
"xxx" | |
array di stringhe vuote |
- si potrebbe immaginare che il metodo reset di dynaFormulaire assegni dei valori ai tre array destinati ad alimentare le tre liste della vista formulaire.jsp. Ciò sarebbe possibile in questo caso poiché i dati di questi tre array vengono generati in modo arbitrario. Tuttavia, il caso più comune è che tali dati provengano dal modello dell’applicazione, ovvero l’M di MVC. In questo caso, per non complicare l’esempio, adotteremo una posizione intermedia, facendo generare questi valori dall’azione InitFormulaireAction, ovvero dal C di MVC.
- Non è obbligatorio 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, il valore è "false". Il metodo validate di dynaFormulaire non verrà chiamato.
- L’oggetto InitFormulaireAction viene creato o riciclato se già esistente e viene eseguito il suo metodo `execute`. È proprio questo metodo che assegnerà valori arbitrari ai tre array di dynaFormulaire: valeursCombo, valeursListeSimple e valeursListeMultiple. Il metodo restituisce un ActionForward con chiave "afficherFormulaire".
- Il controller visualizza la vista /vues/formulaire.jsp, che è stata associata alla chiave "afficherFormulaire" tramite un tag forward dell'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 viene eseguita quando l'utente preme il pulsante [Envoyer] nella vista n. 1. Il browser "invia" quindi al controller Struts il modulo compilato dall'utente.
- L'oggetto dynaFormulaire viene inserito nella sessione
- viene chiamato il suo metodo reset. Una volta chiamato, il controller Struts copierà i valori dei campi del modulo inviato dal client nei campi con lo stesso nome di dynaFormulaire. Riprendiamo l’elenco dei campi di quest’ultimo e vediamo come avviene questa copia:
Campo | Codice HTML associato | Valore del campo dopo il trasferimento dei valori del modulo |
<input type="radio" name="opt" value="sì">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 chk1 è stata selezionata - mantiene il valore precedente se la casella chk1 non è stata spuntata | |
<input type="checkbox" name="chk2" value="on"> | - "on" se la casella chk2 è stata selezionata - mantiene il valore precedente se la casella chk2 non è stata selezionata | |
<input type="checkbox" name="chk2" value="on"> | - "on" se la casella chk3 è stata selezionata - mantiene il valore precedente se la casella chk3 non è stata selezionata | |
<input type="text" name="champSaisie" value=""> | - valore digitato dall'utente in champSaisie | |
<input type="password" name="mdp" value=""> | - valore digitato dall'utente in mdp | |
<textarea name="boiteSaisie"></textarea> | - valore digitato dall'utente in boiteSaisie | |
<select name="combo">...</select> | - valore selezionato dall'utente in combo | |
<select name="listeSimple" size="3">...</select> | - valore selezionato dall'utente in listeSimple | |
<select name="listeMultiple" multiple="multiple" size="5"> | - array di stringhe contenente i valori selezionati dall'utente in listeMultiple | |
<input type="hidden" name="secret" value="xxx"> | - "xxx". |
Si riscontra una difficoltà con i campi che non ricevono necessariamente un valore nella richiesta inviata dal browser. È il caso delle caselle di controllo da chk1 a chk3 e dei due elenchi listeSimple e listeMultiple. In questo caso, tali campi mantengono il loro valore precedente, ovvero quello acquisito durante il ciclo richiesta-risposta precedente.
Prendiamo ad esempio la casella di controllo chk1 e supponiamo che nel precedente ciclo richiesta-risposta l’utente avesse spuntato questa casella. Il browser aveva quindi inviato nella stringa dei parametri della sua richiesta l’informazione chk1="on". Il costruttore ha quindi assegnato il valore "on" al campo chk1 di dynaFormulaire. Supponiamo ora che nel ciclo in corso l’utente non selezioni la casella 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 di dynaFormulaire manterrà il valore "on" e quindi avrà un valore che non riflette quello del modulo convalidato dall’utente. Per risolvere questo problema useremo il metodo reset di dynaFormulaire. In questo metodo imposteremo i tre campi chk1, chk2, chk3 su "off". Nel nostro esempio relativo a chk1, supponiamo che l’utente:
- spunta la casella chk1. In tal caso, il browser invia l’informazione chk1="on" e il campo chk1 di dynaFormulaire passerà a "on"
- non seleziona la casella chk1. In tal caso, il browser non invia alcun valore per il campo chk1, che manterrà il suo valore precedente "off". In entrambi i casi, il valore registrato nel campo chk1 di dynaFormulaire è corretto.
Il problema è analogo per entrambi gli elenchi listeSimple e listeMultiple. Se in questi elenchi non è stata selezionata alcuna opzione, esse non saranno presenti nei parametri della query e manterranno quindi i loro valori precedenti. Nel metodo reset di dynaFormulaire, reinizializzeremo listeSimple con una stringa vuota e listeMultiple con un array di stringhe di lunghezza 0.
- Una volta chiamato il metodo reset di dynaFormulaire, il controller ricopia nei campi di dynaFormulaire le informazioni che gli sono state inviate nella richiesta del cliente
- Viene creato o riciclato 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 è completato.
L'azione /visualizza
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- L'azione /affiche viene attivata cliccando sul link [Retour vers le formulaire] della vista n. 2.
- In questo caso non vi è alcun modulo associato all’azione. Si passa quindi immediatamente all’esecuzione del metodo `execute` di un oggetto `ForwardAction`, che restituirà un oggetto `ActionForward` che punta alla vista `/vues/formulaire.jsp`.
6.3.6. Il file dei messaggi dell’applicazione
La terza sezione del file struts-config.xml è quella del file dei messaggi:
Il file ApplicationResources.properties si trova nella cartella 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 è utilizzata dalla vista confirmation.jsp.
6.4. Il codice delle viste
6.4.1. La vista formulaire.jsp
Ricordiamo che questa vista viene visualizzata in due casi:
- quando viene chiamata l’azione /init durante il primo ciclo richiesta-risposta
- all'invocazione dell'azione /affiche nei 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 tag provenienti dalla libreria struts-html. Ricordiamo che per utilizzare una libreria di tag è necessario:
- dichiararla nel file web.xml dell'applicazione con un tag <tag-lib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- inserire il codice di questa libreria in una posizione qualsiasi nella struttura dell'applicazione, in questo caso WEB-INF/struts-html.tld
- Dichiarare l'utilizzo di questa libreria all'inizio delle pagine JSP che la utilizzano:
La vista formulaire.jsp utilizza dei tag che spieghiamo ora:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
Il tag html:rewrite consente di prescindere dal nome dell'applicazione in URL. Ha un attributo:
Quindi, come sopra, se si decide di chiamare l'applicazione "formulaire3", il codice dell'attributo background non deve essere riscritto. 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 consente di generare il tag HTML form. Presenta diversi attributi:
Si nota che, per impostazione predefinita, il codice HTML generato utilizza il metodo POST. Nello stesso codice HTML, il codice 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="sì">Sì</html:radio> | |||||||
Il tag html:radio serve a generare il tag HTML <input type="radio" ...>. Accetta diversi attributi:
Il testo tra il tag di apertura e quello di chiusura è il testo che verrà visualizzato accanto al pulsante di opzione. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
Il tag html:checkbox serve a generare il tag HTML <input type="checkbox" ...>. Accetta diversi attributi:
Il testo tra il tag di inizio e quello di fine è il testo che verrà visualizzato accanto alla casella di controllo. |
<html:text name="dynaFormulaire" property="champSaisie" /> | |||||||
Il tag html:text serve a generare il tag HTML <input type="text" ...>. Accetta diversi attributi:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
Il tag html:password serve a generare il tag HTML <input type="password" ...>. Accetta diversi attributi: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
Il tag html:textarea serve a generare il tag HTML <textarea>...</textarea>. Accetta diversi attributi:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
Il tag html:select serve a generare il tag HTML <select>...</select>. Accetta diversi attributi:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |||||
Il tag HTML:options serve a generare i tag HTML <option>...</option> all'interno di un tag HTML <select>. Esistono diversi modi per specificare come individuare i valori di riempimento del menu a tendina. In questo caso, abbiamo utilizzato gli attributi name e property:
|
Gli altri due elenchi vengono generati in modo analogo al precedente:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
Nell’esempio sopra riportato, si specifica un attributo size diverso da 1 per ottenere un elenco anziché un menu a tendina.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
Qui sopra si specifica l'attributo multiple="true" per ottenere un elenco a selezione multipla.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
Il tag html:hidden serve a generare il tag HTML <input type="hidden" ...>.
|
Per comprendere appieno il collegamento tra la vista formulaire.jsp e il bean dynaFormulaire che la rappresenta in memoria, occorre ricordare che il bean dynaFormulaire viene utilizzato sia in lettura che in scrittura:
![]() |
La richiesta viene effettuata quando l’utente fa clic sul pulsante [Envoyer] del modulo. Il browser “invia” quindi il modulo HTML all’azione /confirmation. Abbiamo già spiegato cosa succede in quel momento e, in particolare, che i campi di dynaFormulaire riceveranno i valori dei campi con lo stesso nome presenti nel modulo HTML.
Cosa succede quando il controller richiede la visualizzazione della vista formulaire.jsp in risposta a una richiesta? Esaminiamo nuovamente i 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="sì">Sì</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">No</html:radio> | |
Se il campo opt di dynaFormulaire è "sì", 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="dynaFormulaire" property="chk3">3</html:checkbox> | |
Se i campi chk1 e chk3 di dynaFormulaire hanno valore "on" e il campo chk2 ha valore "off", genera il codice HTML |
<html:text name="dynaFormulaire" property="champSaisie" /> | |
se il campo champSaisie ha il valore "questo è un test", genera il codice HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
se il campo mdp è pari a "azerty", genera il codice HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
se il campo mdp è pari a "azerty", genera il codice HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
se il campo mdp è pari a "azerty", genera il codice HTML |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |
se il campo combo ha il valore "combo2", genera il codice HTML |
<html:select name="dynaFormulaire" property="listeSimple" size="3"> <html:options name="dynaFormulaire" property="valeursListeSimple"/> </html:select> | |
se il campo listeSimple ha il valore "simple1", genera il codice HTML |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="valeursListeMultiple"/> </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 collegato ai due pulsanti [Effacer] che deselezionano gli elementi selezionati negli elenchi listeSimple e listeMultiple:
<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 [Effacer], ricordiamo come vengono identificati i diversi elementi di un documento web all’interno di un codice JavaScript che utilizza tale documento:
Dato | Significato |
indica l’intero documento web | |
indica l'insieme dei moduli definiti nel documento | |
indica il modulo n. i del documento | |
indica il modulo <form> con l'attributo name pari a "nomFormulaire" | |
indica il modulo <form> con l'attributo name pari a "nomFormulaire" | |
indica la raccolta degli elementi che compongono il modulo indicato dall'espressione [formulaire]. Questa raccolta comprende tutti i tag <input>, <textarea>, <select> del modulo indicato. | |
indica l'elemento n. i di [formulaire] | |
indica l'elemento di [formulaire] con l'attributo "name" pari a nomComposant | |
indica l'elemento di [formulaire] con l'attributo name pari a nomComposant | |
indica il valore del componente [composant] del modulo [formulaire] quando il codice HTML di quest’ultimo può avere un attributo value (<input>, <textarea>) | |
indica l'indice dell'opzione selezionata in un elenco. Si utilizza sia in lettura che in scrittura. Impostando questa proprietà su -1 si deseleziona tutti gli elementi dell'elenco. | |
indica l'array delle opzioni associate a un tag <select> | |
indica l'opzione n. i del tag <select> specificato | |
valore booleano che indica se l'opzione n. i del tag [select] indicato è selezionata (true) o meno. Può essere utilizzato sia in lettura che in scrittura |
Torniamo al codice JavaScript dei due pulsanti:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
All'evento clic sul pulsante, viene eseguito il codice associato all'attributo "onclick". In questo caso si tratta di codice in linea. Il più delle volte si scrive onclick="funzione(...)", dove funzione è una funzione definita all'interno di un tag <script language="javascript">...</script>. Cosa fa il codice sopra riportato? Commentiamo il codice del primo pulsante:
indica il documento web in cui si trova il pulsante | |
indica il modulo in cui si trova il pulsante | |
indica il componente listeSimple del modulo | |
indica l'indice dell'opzione selezionata in listeSimple. Impostando questa proprietà su -1, tutte le opzioni vengono deselezionate. |
6.4.2. La vista confirmation.jsp
Ricordiamo che questa vista viene visualizzata al termine dell’azione /conferma, c.a.d, 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>
Introduciamo qui due nuove librerie di tag: struts-bean e struts-logic. La libreria struts-bean consente di accedere agli oggetti presenti nella richiesta, nella sessione o nel contesto dell'applicazione. La libreria struts-logic consente di inserire la logica di esecuzione tramite tag. Queste due librerie non sono affatto indispensabili. Come abbiamo visto, una pagina JSP può:
- recuperare oggetti dalla richiesta (request.getAttribute(...)), dalla sessione (session.getAttribute(...)) o dal contesto dell’applicazione
- includere parti dinamiche nel codice HTML tramite variabili <%= variabile %>
- contenere codice Java <% codice Java %>
L’inclusione di codice Java nelle pagine JSP crea difficoltà a tutti coloro che desiderano una separazione rigorosa tra logica applicativa (codice Java) e presentazione (uso dei tag). Per questo motivo sono state create delle librerie di tag appositamente per loro.
Procederemo come per la vista formulaire.jsp e spiegheremo ciascuno dei tag presenti nel codice di confirmation.jsp, qualora non fossero già stati incontrati nella vista formulaire.jsp. Innanzitutto, notiamo 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" %>
Ricordiamo inoltre che queste tre librerie devono essere dichiarate nel file web.xml dell’applicazione. Commentiamo ora i tag del documento formulaire.jsp:
scrive un valore nel flusso HTML corrente. Il tag bean:write ammette i seguenti attributi: name: nome dell'oggetto da utilizzare scope: ambito (request, session, context) in cui cercare tale oggetto property: campo dell'oggetto indicato da name di cui si deve scrivere la proprietà. Questo campo può essere un oggetto di qualsiasi tipo. Verrà utilizzato il metodo toString dell'oggetto. In questo caso, viene scritto il valore del campo opt di dynaFormulaire. Si otterrà “sì” se l’utente ha selezionato il pulsante di opzione con l’attributo value=”sì”, oppure “no” se ha selezionato il pulsante di opzione con l’attributo value=”no” |
scrive il valore del campo chk1 di dynaFormulaire. Si otterrà "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 da dynaFormulaire, ovvero il testo digitato dall’utente in quel campo. Lo stesso vale per mdp, boiteSaisie. |
scrive il valore del campo a discesa di dynaFormulaire. Si otterrà l’attributo value dell’elemento <option> selezionato dall’utente. |
scrive il valore del campo listeSimple da dynaFormulaire. Si otterrà l'attributo value dell'elemento <option> selezionato dall'utente, se ne è stato selezionato uno. In caso contrario, si otterrà la stringa vuota. |
Qui introduciamo dei tag logici. Abbiamo a che fare con un elenco a scelta multipla. Il valore del campo listeMultiple dell'oggetto dynaFormulaire è un array di String. In Java, scriveremmo un ciclo. Il tag logic:iterate ci permette di eseguire lo stesso ciclo senza scrivere codice Java. Nel nostro esempio, il tag logic:iterate presenta i seguenti attributi: name="dynaFormulaire": nome dell’oggetto da utilizzare property="listeMultiple": nome della proprietà che, nell’oggetto indicato da name, contiene la collezione che verrà iterata nel ciclo. In questo caso, tale collezione è l’array dei valori selezionati in listeMultiple. Questo array può essere vuoto. id="choix": identificatore che indica l'elemento corrente dell'array ad ogni iterazione del ciclo. Durante la prima iterazione, «choix» rappresenterà listeMultiple[0], durante la seconda listeMultiple[1] e così via. indexID="index": identificatore che indica l'indice dell'elemento corrente dell'array ad ogni iterazione del ciclo. Nella prima iterazione, index avrà il valore 0, nella seconda il valore 1 e così via. Il codice HTML contenuto tra i tag <logic:iterate ...> e </logic:iterate> viene ripetuto per ogni elemento della collezione indicata dalla coppia (name,property). La parte dinamica di questo codice è la seguente:
Da quanto detto in precedenza, all’iterazione n. i (i>=0), il codice HTML generato è equivalente al seguente codice: |
genera un link relativo al contesto dell'applicazione, il che evita di doverlo conoscere. 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 inviato tramite il pulsante [Envoyer] di 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 ridefinire uno dei metodi reset o validate di questa classe. In questo caso, il metodo validate non deve essere ridefinito poiché non viene eseguita alcuna convalida dei dati. Il metodo reset, invece, deve essere ridefinito. Infatti, i campi dell’oggetto DynaFormulaire riceveranno i propri valori dal modulo inviato dal client web. Tuttavia, alcuni campi potrebbero non ricevere alcun valore se non sono presenti nella richiesta. Ciò si verifica nei seguenti casi:
- una casella di selezione che non è stata spuntata dall'utente
- un elenco con più di una voce o nessuna opzione selezionata
Per i moduli che contengono questo tipo di componente, il metodo reset deve
- assegnare il valore "off" al campo associato alla casella di controllo
- assegnare la stringa vuota al campo associato a un elenco a selezione singola
- assegnare un array di stringhe di lunghezza zero al campo associato a un elenco a selezione multipla
Pertanto, se questi campi non ricevono alcun valore dalla richiesta, mantengono il valore assegnato dal metodo reset, valore che corrisponde allo stato del componente nel modulo convalidato dall’utente (casella deselezionata, elenco senza alcun elemento selezionato).
Il codice della classe DynaFormulaire, classe derivata da 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 delle caselle di controllo - valore off
set("chk1","off");
set("chk2","off");
set("chk2","off");
// reset di listeSimple - stringa vuota
set("listeSimple","");
// reset di listeMultiple - tabella vuota
set("listeMultiple",new String[]{});
}
}
6.5.2. La classe InitFormulaireAction
La classe InitFormulaireAction è, nel file struts-config.xml, associata all'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 viene utilizzata una sola volta durante la creazione iniziale dell'oggetto DynaFormulaire. Ha lo scopo di fornire contenuti ai tre elenchi del form a discesa, listeSimple, listeMultiple. Tale contenuto viene fornito sotto forma di tre array, proprietà dell’oggetto dynaFormulaire:
<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 le tabelle valeursCombo, valeursListeSimple, valeursListeMultiple saranno state inizializzate da InitFormulaireAction, non sarà più necessario inizializzarle nuovamente. Infatti, l’oggetto dynaFormulaire viene inserito nella sessione e mantiene quindi il proprio valore nel corso dei cicli richiesta-risposta. Per questo motivo l’azione /init viene eseguita una sola volta. Il codice di InitFormulaireAction è 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 {
// prepara il modulo da visualizzare
// si inseriscono le informazioni necessarie nel bean del modulo
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
// si restituisce il controllo
return mapping.findForward("afficherFormulaire");
} //esegue
// elenco dei valori del menu a tendina
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 deriva dalla classe Action. È obbligatorio.
- Il controller Struts utilizza un oggetto Action tramite il suo metodo execute. È quindi questo 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 (attributo name dell’azione).
- HttpServletRequest request: la richiesta del client
- HttpServletResponse: la risposta al client
- la classe InitFormulaireAction deve inizializzare il modulo dynaFormulaire. Quest'ultimo viene passato al metodo execute sotto forma del parametro ActionForm form. Ricordiamo che dynaFormulaire è di tipo DynaFormulaire, classe derivata dalla classe DynaActionForm, a sua volta derivata dalla classe ActionForm.
- Nel metodo `execute`, vengono assegnati dei valori ai tre campi valeursCombo, valeursListeSimple e valeursListeMultiple tramite il metodo `set` della classe DynaActionForm. Questi valori sono array arbitrari per motivi di semplicità. Si noti che il metodo set assegna un valore a un campo esistente. Non può essere utilizzato per creare nuovi campi. Per questo motivo, è necessario definire i tre campi valeursCombo, valeursListeSimple, 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 dell'applicazione è la seguente:
![]() | ![]() |
![]() | ![]() |


Ricordiamo che il file ApplicationResources.properties sopra riportato è necessario per la libreria di tag struts-bean. È noto che questo file contiene i messaggi dell'applicazione. Questi sono accessibili alla libreria struts-bean. 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 diversi componenti di un modulo HTML. Ora possiamo utilizzare moduli complessi nelle nostre applicazioni Struts.






