6. Formulare HTML
Bisher haben wir ein einziges Formular verwendet, das nur zwei Eingabefelder enthielt. Hier wollen wir nun ein Formular erstellen und bearbeiten, das die üblichen grafischen Komponenten (Optionsfelder, Kontrollkästchen, Eingabefelder, Comboboxen, Listen) nutzt.
6.1. Die Ansichten der Anwendung
Die Anwendung wird nur zwei Ansichten haben. Die erste zeigt ein leeres Formular:
QZXW2HTMLP000547ZQX 1 - formulaire

Diese erste Ansicht mit dem Namen formulaire.jsp ermöglicht es uns, verschiedene Tags aus der Struts-HTML-Bibliothek zu implementieren. Der Benutzer füllt das Formular aus:

Über die Schaltfläche [Envoyer] kann eine Bestätigung der eingegebenen Werte abgerufen werden. Dies ist die zweite Ansicht:

Diese zweite Ansicht ermöglicht es uns, zwei weitere Tag-Bibliotheken zu nutzen: „struts-bean“ und „struts-logic“. Über den Link [Retour au formulaire] gelangen wir zurück zu dem Formular, wie es ausgefüllt wurde. Wir befinden uns dann wieder in der ersten Ansicht.
6.2. Die Architektur der Anwendung
![]() |
- Das Formular (Ansicht 1) wird durch ein dynamisches Struts-Objekt namens dynaFormulaire dargestellt, dessen Typ von DynaActionForm abgeleitet ist. Es wird von der Ansicht formulaire.jsp angezeigt.
- Die Struts-Aktion InitFormulaireAction dient dazu, die für die Anzeige des Formulars erforderlichen Daten abzurufen
- Das ausgefüllte Formular wird von der Aktion ForwardAction verarbeitet, die lediglich die Anfrage an die zweite Ansicht confirmation.jsp weiterleitet. Diese übernimmt die Anzeige der Formularwerte.
6.3. Die Konfiguration der Anwendung
6.3.1. Die Datei server.xml
Der Anwendungskontext wird /formulaire2 heißen. Daher fügen wir die folgende Zeile in die Tomcat-Datei server.xml ein:
Anschließend starten wir Tomcat gegebenenfalls neu, damit der neue Kontext berücksichtigt wird. Wir können die Gültigkeit des Kontexts überprüfen, indem wir die Seite URL unter http://localhost:8080/formulaire2 aufrufen:

6.3.2. Die Datei web.xml
Die Konfigurationsdatei web.xml der Anwendung sieht wie folgt aus:
<?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>
An den bereits bekannten Konfigurationsdateien web.xml nehmen wir einige Änderungen vor:
- Wir fügen zwei neue Tag-Bibliotheken hinzu: „struts-bean“ und „struts-logic“. Diese werden in der Ansicht confirmation.jsp verwendet. Die Ansicht formulaire.jsp nutzt hingegen die Bibliothek „struts-html“.
6.3.3. Die Datei struts-config.xml
Die Datei struts-config.xml sieht wie folgt aus:
<?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>
Darin finden sich die drei Hauptabschnitte:
- die Deklaration der Formulare im Abschnitt <form-beans>
- die Deklaration der Aktionen im Abschnitt <action-mappings>
- die Deklaration der Ressourcendatei im Abschnitt <message-ressources>
6.3.4. Die Formularobjekte (Beans) der Anwendung
Die Objekte, die zur Darstellung der HTML-Formulare der Anwendung verwendet werden, sind Objekte vom Typ ActionForm oder davon abgeleitete Typen (DynaActionForm, DynaValidatorForm, ...). Sie werden als Beans bezeichnet, da ihre Struktur den Regeln von JavaBeans folgt. In unserer Anwendung gibt es nur eine Formular-Bean, die den Namen dynaFormulaire trägt und vom Typ DynaActionForm abgeleitet ist. Sie wird in den folgenden Situationen verwendet:
- die für die Anzeige der Ansicht Nr. 1 erforderlichen Daten enthalten
- die Werte des Formulars aus Ansicht Nr. 1 abzurufen, wenn der Benutzer es absendet (submit)
- die für die Anzeige der Ansicht Nr. 2 erforderlichen Daten enthalten
Die Struktur des Beans dynaFormulaire ist eng mit dem Formular der Ansicht Nr. 1 verknüpft. Sehen wir uns dieses einmal genauer an:
![]() |
Nr. | Typ HTML | Rolle |
<input name="opt" type="radio" value="ja"> <input name="opt" type="radio" value="nein"> | Gruppe miteinander verknüpfter Radiobuttons (gleicher Name) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | Gruppen von Kontrollkästchen (nicht denselben Namen) | |
<input type="text" name="champSaisie" > | ein Eingabefeld | |
<input type="password" name="mdp"> | ein Passwortfeld | |
<textarea name="boiteSaisie">...</textarea> | ein mehrzeiliges Eingabefeld | |
<select name="combo" size="1">..</select> | ein Dropdown-Menü | |
<select name="listeSimple" size="3">..</select> | eine Liste mit einer Auswahlmöglichkeit | |
<select name="listeMultiple" size="3" multiple>..</select> | eine Liste mit Mehrfachauswahl | |
<input type="button" value="Löschen" onclick='effacerListe("listeSimple")'> | Schaltfläche zum Aufheben der Auswahl die in listeSimple (7) ausgewählten Elemente | |
<input type="button" value="Löschen" onclick='Liste löschen("listeMultiple")'> | Schaltfläche zum Aufheben der Auswahl die in listeMultiple (8) ausgewählten Elemente | |
<input type="submit" value="Senden"> | Absenden-Schaltfläche des Formulars | |
<input type="hidden" name="secret" value="..."> | Ein verstecktes Feld |
Es gibt verschiedene Fälle:
- Das Objekt dynaFormulaire dient dazu, die Werte des oben genannten Formulars HTML zu speichern, das über die Schaltfläche [Envoyer] übermittelt wird. Es muss daher dieselben Felder enthalten wie das Formular HTML. Der Feldtyp wird durch die folgende Regel festgelegt:
- Wenn das Feld HTML nur einen Wert liefert, dann hat das Feld dynaFormulaire den Typ java.lang.String
- Wenn das Feld HTML mehrere Werte liefert, hat das Feld in dynaFormulaire den Typ java.lang.String[]
Im obigen Formular HTML kann nur das Feld listeMultiple mehreren Werten zugeordnet werden (den vom Benutzer ausgewählten). Eine erste Definition des Objekts dynaFormulaire würde daher wie folgt lauten:
<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>
Wie erfolgt die Befüllung von dynaFormulaire mit den vom Web-Client übermittelten Werten aus dem Formular HTML?
Das Feld „opt“ erhält den Wert „ja“, wenn das Feld HTML <input type="radio" name="opt" value="ja"> angekreuzt wurde, und den Wert „nein“, wenn das Feld <input type="radio" name="opt" value="nein"> angekreuzt wurde. | |
Das Feld „chk1“ erhält den Wert „on“, wenn das Feld HTML <input name="chk1" type="radio" value="1"> ausgewählt wurde, andernfalls keinen Wert. Im letzteren Fall behält das Feld „chk1“ seinen vorherigen Wert bei. | |
ebenso | |
dasselbe | |
Das Feld champSaisie erhält den Text, den der Benutzer in das Feld HTML <input type="text" name="champSaisie"> eingegeben hat. Dieser Text kann gegebenenfalls die leere Zeichenfolge sein. | |
Das Feld „mdp“ erhält den vom Benutzer in das Feld HTML <input type="password" name="mdp"> eingegebenen Text. Dieser Text kann gegebenenfalls die leere Zeichenfolge sein. | |
Das Feld boiteSaisie erhält den vom Benutzer in das Feld HTML eingegebenen Text <textarea name="boiteSaisie">...</textarea>. Dieser Text bildet eine einzige Zeichenkette, die aus den vom Benutzer eingegebenen Zeilen besteht, die durch die Zeichenfolge „\r\n“ voneinander getrennt sind. Der resultierende Text kann gegebenenfalls die leere Zeichenkette sein. | |
Das Kombinationsfeld erhält die vom Benutzer im Feld HTML <select name="combo" size="1">..</select> ausgewählte Option. Die ausgewählte Option ist diejenige, die im Kombinationsfeld angezeigt wird. Wenn die ausgewählte Option HTML vom Typ <option value="XX">YY</option> ist, erhält das Kombinationsfeld den Wert „XX“. Wenn die ausgewählte Option „HTML“ vom Typ <option>YY</option> ist, erhält das Kombinationsfeld den Wert „YY“. | |
Das Feld listeSimple erhält die vom Benutzer im Feld HTML <select name="listeSimple" size="..">..</select> ausgewählte Option, sofern eine vorhanden ist. Ist dies nicht der Fall, erhält das Feld listeSimple keinen Wert und behält seinen vorherigen Wert bei. Der tatsächlich dem Feld listeSimple zugewiesene Wert folgt den für das Kombinationsfeld angegebenen Regeln. | |
Das Feld listeMultiple vom Typ String[] erhält die vom Benutzer im Feld HTML <select name="listeMultiple" size=".." multiple>..</select> ausgewählten Optionen, sofern vorhanden. Sind keine vorhanden, erhält das Array listeMultiple keinen Wert und sein Inhalt bleibt unverändert. Die tatsächlich dem Array listeMultiple zugewiesenen Werte folgen den für das Kombinationsfeld angegebenen Regeln. | |
Das Feld „secret“ erhält den Wert XX aus dem Feld HTML <input type="hidden" name="secret" value="XX">. Dieser Text kann gegebenenfalls die leere Zeichenfolge sein. |
- Das Objekt dynaFormulaire wird verwendet, um den Anfangsinhalt der Ansicht Nr. 1 festzulegen. Die Werte der vorherigen Felder werden für folgende Zwecke verwendet:
muss den Wert „ja“ oder „nein“ haben, damit der Browser weiß, welches Optionsfeld ausgewählt werden soll | |
Wenn chk1 den Wert „on“ hat, wird das Kontrollkästchen aktiviert, andernfalls bleibt es deaktiviert | |
ebenso | |
dasselbe | |
Der Wert des Feldes wird im Eingabefeld angezeigt champSaisie | |
Der Wert des Feldes wird im Eingabefeld „mdp“ angezeigt | |
Der Wert des Feldes wird im Eingabefeld angezeigt boiteSaisie | |
Der Wert dieses Feldes gibt an, welches Element der Combobox bei der Anzeige des Formulars ausgewählt sein soll | |
dasselbe | |
Die Werte der Tabelle listeMultiple geben an, welche Elemente der Mehrfachauswahlliste bei der Anzeige des Formulars ausgewählt werden sollen | |
Der Wert des Feldes wird dem Attribut „value“ des Feldes „secret“ zugewiesen. |
Die Ansicht Nr. 1 benötigt weitere Informationen:
- die Liste der Werte, die in der Kombinationsliste angezeigt werden sollen
- die Liste der Werte, die in der Liste listeSimple angezeigt werden sollen
- die Liste der Werte, die in der Liste listeMultiple angezeigt werden sollen
Es gibt mehrere Möglichkeiten, diese Informationen an die Ansicht zu übergeben. Zum Beispiel würden Arrays, die in der an die Ansicht übergebenen Abfrage enthalten sind, diesen Zweck erfüllen. Hier speichern wir diese Arrays in der 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>
Das Formular dynaFormulaire wird durch die Aktion /init initialisiert, die ein von Action abgeleitetes Objekt namens InitFormulaireAction aufruft. Dieses Objekt ist dafür zuständig, die drei für die Anzeige der drei Listen erforderlichen Arrays zu erstellen und sie in die Bean dynaFormulaire zu übertragen. Die Konfigurationsdatei weist dieser Bean einen Gültigkeitsbereich zu, der der Sitzung entspricht. Dies hat zur Folge, dass der Struts-Controller diese Bean in die Sitzung einfügt. Wir müssen sie somit zwischen zwei Anfrage-Antwort-Zyklen nicht neu generieren. Daher wird die Aktion /init nur einmal aufgerufen.
- Das Objekt dynaFormulaire wird ebenfalls verwendet, um den Inhalt der Ansicht Nr. 2 bereitzustellen. Diese beschränkt sich darauf, die Werte anzuzeigen.
6.3.5. Die Aktionen der Anwendung
Die Aktionen werden von Objekten vom Typ „Action“ oder davon abgeleiteten Objekten ausgeführt. Die Konfiguration der Aktionen erfolgt innerhalb der Tags <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>
Es ist zu beachten, dass einer Aktion nicht immer ein Formular zugeordnet ist. Dies ist im obigen Beispiel bei der Aktion /affiche der Fall. Bevor wir jede Aktion im Detail betrachten, wollen wir noch einmal die Funktionsweise des Paares aus Aktion und zugehörigem Formular innerhalb eines <action>-Tags erläutern:
- Eine Aktion beginnt mit einer Anfrage eines Web-Clients und endet mit dem Senden einer Antwortseite. Dies ist der Anfrage-Antwort-Zyklus zwischen Web-Client und Web-Server. Die Anfrage wird vom Struts-Controller vom Typ ActionServlet oder einem davon abgeleiteten Typ empfangen. Dieser Controller sendet auch die Antwort.
- Die Formular-Bean vom Typ ActionForm oder einem davon abgeleiteten Typ wird erstellt, falls sie noch nicht existiert. Der Controller prüft, ob er ein Objekt mit dem Namen „name“ im durch „scope“ angegebenen Gültigkeitsbereich finden kann. Wenn ja, verwendet er es. Wenn nicht, erstellt er es und fügt es dem durch „scope“ angegebenen Gültigkeitsbereich hinzu, verknüpft mit dem durch „name“ angegebenen Attribut.
Im Beispiel der Aktion /init führt der Controller beispielsweise einen Aufruf von request.getSession().getAttribute("dynaFormulaire") durch, um festzustellen, ob dynaFormulaire bereits angelegt wurde oder nicht. Ist dies nicht der Fall, wird er es erstellen und mittels einer Anweisung wie request.getSession() in die Sitzung einfügen.setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- Der Controller sucht außerdem nach einem Action-Objekt des durch das Attribut „type“ angegebenen Typs. Findet er keines, erstellt er es; andernfalls verwendet er es.
- Die Methode „reset“ des Formular-Beans wird aufgerufen. Dieses wird – außer bei seiner erstmaligen Erstellung – wiederverwendet. Es enthält dann Daten, die man möglicherweise „bereinigen“ möchte. Dies geschieht in der Methode „reset“ des Beans ActionForm oder eines davon abgeleiteten Beans.
- Wenn die Aktion das Ziel eines gesendeten Formulars ist, werden die im Client-Request enthaltenen Formularwerte in die gleichnamigen Felder des Formular-Beans kopiert. Dabei ist zu beachten, dass die Methode „reset“ vor dieser Kopieraktion aufgerufen wurde.
- Wenn in der Konfiguration das Attribut `validate="true"` angegeben ist, wird die Methode `validate` der Formular-Bean aufgerufen. Diese muss dann die Daten der Bean überprüfen. Diese Überprüfung findet meist nur dann statt, wenn das Formular gerade neue Daten über ein per POST übermitteltes Formular erhalten hat und die Gültigkeit dieser Daten überprüft werden soll. Diese Methode gibt dem Controller eine eventuelle Fehlerliste in einem Objekt vom Typ ActionErrors zurück.
- Ist das Objekt ActionErrors nicht leer, lässt der Controller die durch das Attribut „input“ der Aktion angegebene Ansicht anzeigen.
- Wenn keine Datenvalidierung angefordert wurde oder diese erfolgreich verlaufen ist, lässt der Controller die Methode `execute` des Objekts vom Typ `Action` oder eines davon abgeleiteten Typs ausführen, das der aktuellen Aktion zugeordnet ist. In dieser Methode wird die Anfrage des Web-Clients verarbeitet. Die Methode `execute` gibt ein Objekt vom Typ `ActionForward` zurück, das durch Schlüssel vom Typ Zeichenkette indiziert ist. Diese Schlüssel sind diejenigen, die durch die „forward“-Tags der konfigurierten Aktion deklariert wurden. In unserem Beispiel hat die Aktion /init ein einziges „forward“-Tag. Es ordnet den Schlüssel „afficherFormulaire“ der Ansicht formulaire.jsp zu.
- Der Controller lässt die Ansicht anzeigen, der der empfangene Schlüssel zugeordnet ist. Diese Ansicht kann wiederum eine Aktion sein; in diesem Fall wird der vorherige Vorgang wiederholt.
Die Aktion /init
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
- Die Aktion /init findet normalerweise einmal während des ersten Anfrage-Antwort-Zyklus statt, wenn der Benutzer das URL-http://localhost:8080/formulaire2/init.do anfordert
- das Objekt dynaFormulaire angelegt oder wiederverwendet wird. Es wird entsprechend dem Attribut „scope“ in die Sitzung übernommen (Wiederverwendung) oder dort abgelegt (Anlegen).
- Seine Methode „reset“ wird aufgerufen. Was soll sie tun? Normalerweise werden die Felder des Objekts ActionForm auf Standardwerte zurückgesetzt. Nur in diesem Fall tun wir das nicht, da das Objekt dynaFormulaire in die Sitzung gesetzt wird (scope="session"). Die Felder von dynaFormulaire müssen daher ihre Werte beibehalten. Welche Werte hatten diese Felder bei der erstmaligen Erstellung des Objekts dynaFormulaire? Es gibt zwei Fälle:
- Das Feld hat einen in der Konfigurationsdatei angegebenen Anfangswert:
In diesem Fall legt der Struts-Controller dieses Feld mit diesem Anfangswert an.
- Das Feld hat keinen in der Konfiguration festgelegten Anfangswert: Es gelten die Initialisierungsregeln von Java. Im Allgemeinen erhalten numerische Felder den Wert Null, Zeichenfolgen den Wert der leeren Zeichenfolge und alle anderen Objekte den Wert Null.
Sehen wir uns die ursprüngliche Konfiguration von dynaFormulaire an:
<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>
Die Anfangswerte der Felder von dynaFormulaire nach seiner Erstellung lauten wie folgt:
Feld | Anfangswert |
„nein“ | |
leere Zeichenfolge | |
leere Zeichenfolge | |
leere Zeichenkette | |
leere Zeichenfolge | |
leere Zeichenfolge | |
leere Zeichenfolge | |
Array aus leeren Zeichenfolgen | |
„xxx“ | |
Array mit leeren Zeichenfolgen |
- Man könnte sich vorstellen, dass die Methode „reset“ von dynaFormulaire Werte an die drei Arrays übergibt, die die drei Listen der Ansicht formulaire.jsp füllen sollen. Dies wäre hier möglich, da die Daten dieser drei Arrays willkürlich generiert werden. Der häufigste Fall ist jedoch, dass diese Daten aus dem Anwendungsmodell stammen, dem M von MVC. Um das Beispiel nicht zu verkomplizieren, wählen wir hier einen Mittelweg und lassen diese Werte durch die Aktion InitFormulaireAction generieren, also durch das C von MVC.
- Es besteht keine Verpflichtung, eine Reset-Methode in dynaFormulaire zu schreiben, da die Klasse ActionForm, von der sie abgeleitet ist, über eine solche Methode verfügt, die nichts tut (keine Initialisierungen).
- Sobald die Reset-Methode von dynaFormulaire aufgerufen wurde, prüft der Controller das Attribut „validate“ der Aktion. Hier hat es den Wert „false“. Die Validate-Methode von dynaFormulaire wird nicht aufgerufen.
- Das Objekt InitFormulaireAction wird erstellt oder, falls es bereits existierte, wiederverwendet, und seine Methode „execute“ wird aufgerufen. Diese Methode weist den drei Arrays von dynaFormulaire – valeursCombo, valeursListeSimple und valeursListeMultiple – beliebige Werte zu. Die Methode gibt ein ActionForward mit dem Schlüssel „afficherFormulaire“ zurück.
- Der Controller lässt die Ansicht /vues/formulaire.jsp anzeigen, die über ein Forward-Tag der Aktion /init dem Schlüssel „afficherFormulaire“ zugeordnet wurde.
Die Aktion /confirmation
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- Die Aktion /confirmation wird ausgelöst, wenn der Benutzer in Ansicht Nr. 1 auf die Schaltfläche [Envoyer] klickt. Der Browser „sendet“ daraufhin das vom Benutzer ausgefüllte Formular an den Struts-Controller.
- Das Objekt dynaFormulaire wird in die Sitzung aufgenommen
- und seine reset-Methode wird aufgerufen. Sobald diese aufgerufen wurde, kopiert der Struts-Controller die Werte der vom Client übermittelten Formularfelder in die gleichnamigen Felder von dynaFormulaire. Sehen wir uns noch einmal die Liste der Felder dieses Objekts an und schauen wir uns an, wie diese Übertragung abläuft:
Feld | Zugehöriger Code von HTML | Feldwert nach der Übernahme der Formularwerte |
<input type="radio" name="opt" value="ja">Ja <input type="radio" name="opt" value="nein" checked="checked">Nein | – „Ja“ oder „Nein“, je nach ausgewähltem Optionsfeld | |
<input type="checkbox" name="chk1" value="on"> | - „on“, wenn das Kontrollkästchen chk1 aktiviert wurde - behält seinen vorherigen Wert bei, wenn das Kontrollkästchen „chk1“ nicht angekreuzt wurde | |
<input type="checkbox" name="chk2" value="on"> | - „on“, wenn das Kontrollkästchen chk2 angekreuzt wurde - behält seinen vorherigen Wert bei, wenn das Kontrollkästchen „chk2“ nicht angekreuzt wurde | |
<input type="checkbox" name="chk2" value="on"> | - „on“, wenn das Kontrollkästchen chk3 aktiviert wurde - behält den vorherigen Wert bei, wenn das Kontrollkästchen „chk3“ nicht angekreuzt wurde | |
<input type="text" name="champSaisie" value=""> | - vom Benutzer in champSaisie eingegebener Wert | |
<input type="password" name="mdp" value=""> | - vom Benutzer in „mdp“ eingegebener Wert | |
<textarea name="boiteSaisie"></textarea> | - vom Benutzer in „boiteSaisie“ eingegebener Wert | |
<select name="combo">...</select> | - vom Benutzer in „combo“ ausgewählter Wert | |
<select name="listeSimple" size="3">...</select> | - vom Benutzer in listeSimple ausgewählter Wert | |
<select name="listeMultiple" multiple="multiple" size="5"> | - Array von Zeichenfolgen, das die vom Benutzer in listeMultiple ausgewählten Werte enthält | |
<input type="hidden" name="secret" value="xxx"> | - „xxx“. |
Es gibt ein Problem mit Feldern, die in der vom Browser gesendeten Anfrage nicht unbedingt einen Wert erhalten. Dies gilt für die Kontrollkästchen chk1 bis chk3 sowie für die beiden Listen listeSimple und listeMultiple. In diesem Fall behalten diese Felder ihren vorherigen Wert bei, der im Verlauf des vorherigen Anfrage-Antwort-Zyklus erfasst wurde.
Betrachten wir zum Beispiel das Kontrollkästchen chk1 und nehmen wir an, dass der Benutzer dieses Kontrollkästchen im vorherigen Anfrage-Antwort-Zyklus aktiviert hatte. Der Browser hatte dann in der Parameterzeichenfolge seiner Anfrage die Information chk1="on" gesendet. Der Hersteller hat dem Feld chk1 von dynaFormulaire daher den Wert „on“ zugewiesen. Nehmen wir nun an, dass der Benutzer im aktuellen Zyklus das Kontrollkästchen chk1 nicht aktiviert. In diesem Fall sendet der Browser in der Parameterzeichenfolge der neuen Anfrage nicht etwa chk1="off", sondern gar nichts. Dadurch behält das Feld chk1 von dynaFormulaire seinen Wert „on“ bei und weist somit einen Wert auf, der nicht dem vom Benutzer validierten Formular entspricht. Um dieses Problem zu beheben, verwenden wir die Methode „reset“ von dynaFormulaire. In dieser Methode setzen wir die drei Felder chk1, chk2 und chk3 auf „off“. In unserem Beispiel für chk1: Wenn der Benutzer
- das Kontrollkästchen chk1 ankreuzt. Dann sendet der Browser die Information chk1="on" und das Feld chk1 von dynaFormulaire wird auf „on“ gesetzt
- das Kontrollkästchen chk1 nicht aktiviert. Dann sendet der Browser keinen Wert für das Feld chk1, das seinen vorherigen Wert „off“ beibehält. In beiden Fällen ist der im Feld chk1 von dynaFormulaire gespeicherte Wert korrekt.
Das Problem tritt bei den beiden Listen „listeSimple“ und „listeMultiple“ in gleicher Weise auf. Wenn in diesen Listen keine Option ausgewählt wurde, sind sie nicht in den Abfrageparametern enthalten und behalten daher ihre bisherigen Werte bei. In der Reset-Methode von dynaFormulaire setzen wir listeSimple auf eine leere Zeichenkette und listeMultiple auf ein Array von Zeichenketten der Länge 0 zurück.
- Sobald die reset-Methode von dynaFormulaire aufgerufen wird, kopiert der Controller die Informationen, die ihm in der Client-Anfrage gesendet wurden, in die Felder von dynaFormulaire
- Ein Objekt ForwardAction wird erstellt oder wiederverwendet und seine Methode „execute“ aufgerufen. ForwardAction ist eine vordefinierte Klasse, die ein Objekt ActionForward zurückgibt, das auf die durch das Attribut „parameter“ der Aktion definierte Ansicht verweist, hier /vues/confirmation.jsp.
- Der Controller sendet diese Ansicht. Der Zyklus ist abgeschlossen.
Die Aktion /zeigt
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- Die Aktion /anzeigen wird durch Anklicken des Links [Retour vers le formulaire] in Ansicht Nr. 2 ausgelöst.
- Hier ist der Aktion kein Formular zugeordnet. Es wird daher sofort die Methode „execute“ eines Objekts ForwardAction aufgerufen, die ein Objekt ActionForward zurückgibt, das auf die Ansicht /vues/formulaire.jsp verweist.
6.3.6. Die Meldungsdatei der Anwendung
Der dritte Abschnitt der Datei struts-config.xml ist die Meldungsdatei:
Die Datei ApplicationResources.properties befindet sich im Verzeichnis WEB-INF/classes. Sie ist leer. Auch wenn sie leer ist, muss sie dennoch in der Konfigurationsdatei deklariert werden, da sonst die Struts-Bean-Tag-Bibliothek, auf die wir später noch eingehen werden, einen Fehler generiert. Diese Bibliothek wird von der Ansicht confirmation.jsp verwendet.
6.4. Der Code der Ansichten
6.4.1. Die Ansicht formulaire.jsp
Zur Erinnerung: Diese Ansicht wird in zwei Fällen angezeigt:
- beim Aufruf der Aktion /init im ersten Anfrage-Antwort-Zyklus
- beim Aufruf der Aktion /affiche in den folgenden Zyklen
Der Code der Ansicht formulaire.jsp lautet wie folgt:
<%@ 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>
Diese Seite JSP verwendet Tags aus der Struts-HTML-Bibliothek. Zur Erinnerung: Um eine Tag-Bibliothek zu verwenden, muss man:
- sie in der Datei web.xml der Anwendung mit einem <tag-lib>-Tag deklarieren
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- den Code dieser Bibliothek an einer beliebigen Stelle im Verzeichnisbaum der Anwendung ablegen, hier WEB-INF/struts-html.tld
- Deklarieren Sie die Verwendung dieser Bibliothek am Anfang der Seiten JSP, die sie nutzen:
Die Ansicht formulaire.jsp verwendet Tags, die wir nun erläutern:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
Mit dem Tag „html:rewrite“ lässt sich der Name der Anwendung in URL umgehen. Es verfügt über ein Attribut:
Wie oben gezeigt, muss der Code des Attributs „background“ nicht neu geschrieben werden, wenn man beschließt, die Anwendung „formulaire3“ aufzurufen. Das Tag „html:rewrite“ generiert den neuen Code „HTML“ background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
Mit dem HTML-Tag „html:form“ lässt sich das Formular-Tag „HTML“ generieren. Es verfügt über mehrere Attribute:
Man sieht, dass der generierte Code HTML standardmäßig die Methode POST verwendet. In eben diesem Code HTML wurde der Code URL der Aktion so umgeschrieben, dass ihm der Name der Anwendung als Präfix und „.do“ als Suffix vorangestellt bzw. angehängt wird. |
<html:radio name="dynaFormulaire" property="opt" value="ja">Ja</html:radio> | |||||||
Das HTML-Tag „html:radio“ dient dazu, das Tag HTML <input type="radio" ...> zu generieren. Es unterstützt verschiedene Attribute:
Der Text zwischen dem Start- und End-Tag ist der Text, der neben dem Optionsfeld angezeigt wird. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
Das HTML-Tag „html:checkbox“ dient dazu, das Tag HTML <input type="checkbox" ...> zu generieren. Es unterstützt verschiedene Attribute:
Der Text zwischen dem Start- und End-Tag ist der Text, der neben dem Kontrollkästchen angezeigt wird. |
<html:text name="dynaFormulaire" property="champSaisie" /> | |||||||
Das HTML-Tag „html:text“ dient dazu, das Tag HTML <input type="text" ...> zu generieren. Es unterstützt verschiedene Attribute:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
Das HTML-Tag „html:password“ dient dazu, das Tag „HTML <input type="password" ...>“ zu generieren. Es unterstützt verschiedene Attribute: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
Das HTML-Tag „textarea“ dient dazu, das Tag HTML <textarea>...</textarea> zu generieren. Es unterstützt verschiedene Attribute:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
Das HTML-Element „html:select“ dient dazu, das Element „HTML <select>...</select>“ zu generieren. Es unterstützt verschiedene Attribute:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |||||
Das HTML-Tag „options“ dient dazu, die Tags HTML <option>...</option> innerhalb eines Tags HTML <select> zu generieren. Es gibt verschiedene Möglichkeiten, anzugeben, wie die Ausfüllwerte für das Select-Element ermittelt werden sollen. Hier haben wir die Attribute „name“ und „property“ verwendet:
|
Die beiden anderen Listen werden analog zur vorherigen generiert:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
Oben wird ein „size“-Attribut ungleich 1 angegeben, um eine Liste anstelle eines Kombinationsfelds zu erhalten.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
Oben wird das Attribut „multiple=“true““ festgelegt, um eine Liste mit Mehrfachauswahl zu erhalten.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
Das HTML-Tag „html:hidden“ dient dazu, das Tag „HTML <input type="hidden" ...>“ zu generieren.
|
Um den Zusammenhang zwischen der Ansicht formulaire.jsp und der Bean dynaFormulaire, die sie im Speicher repräsentiert, richtig zu verstehen, muss man bedenken, dass die Bean dynaFormulaire sowohl zum Lesen als auch zum Schreiben verwendet wird:
![]() |
Die Anfrage erfolgt, wenn der Benutzer auf die Schaltfläche [Envoyer] im Formular klickt. Der Browser „sendet“ dann das Formular HTML an die Aktion /confirmation. Wir haben bereits erläutert, was dann geschieht, und insbesondere, dass die Felder von dynaFormulaire die Werte der gleichnamigen Felder des Formulars HTML erhalten.
Was geschieht, wenn der Controller als Antwort auf eine Anfrage die Anzeige der Ansicht formulaire.jsp anfordert? Betrachten wir die Tags noch einmal einzeln:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
erzeugt den Code HTML |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
erzeugt den Code HTML |
<html:radio name="dynaFormulaire" property="opt" value="ja">Ja</html:radio> <html:radio name="dynaFormulaire" property="opt" value="nein">Nein</html:radio> | |
Wenn das Feld „opt“ von dynaFormulaire den Wert „ja“ hat, generiere den Code 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> | |
Wenn die Felder chk1 und chk3 von dynaFormulaire den Wert „on“ haben und das Feld chk2 den Wert „off“ hat, generiere den Code HTML |
<html:text name="dynaFormulaire" property="champSaisie" /> | |
Wenn das Feld champSaisie den Wert „Dies ist ein Test“ hat, wird der Code HTML generiert |
<html:password name="dynaFormulaire" property="mdp" /> | |
Wenn das Feld „mdp“ den Wert „azerty“ hat, wird der Code HTML generiert |
<html:password name="dynaFormulaire" property="mdp" /> | |
Wenn das Feld „mdp“ den Wert „azerty“ hat, wird der Code HTML generiert |
<html:password name="dynaFormulaire" property="mdp" /> | |
Wenn das Feld „mdp“ den Wert „azerty“ hat, wird der Code HTML generiert |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |
Wenn das Kombinationsfeld den Wert „combo2“ hat, wird der Code HTML generiert |
<html:select name="dynaFormulaire" property="listeSimple" size="3"> <html:options name="dynaFormulaire" property="valeursListeSimple"/> </html:select> | |
Wenn das Feld listeSimple den Wert „simple1“ hat, wird der Code HTML generiert |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="valeursListeMultiple"/> </html:select> | |
Wenn das Feld listeMultiple das Array {"multiple0", "multiple2"} ist, wird der Code HTML generiert |
<html:hidden name="dynaFormulaire" property="secret"/> | |
Wenn das Feld „secret“ den Wert „xxx“ hat, wird der Code HTML generiert |
<html:submit>Senden</html:submit> | |
erzeugt den Code HTML |
Als Letztes soll der JavaScript-Code erläutert werden, der in der Seite JSP enthalten ist und mit den beiden Schaltflächen [Effacer] verknüpft ist, die die in den Listen listeSimple und listeMultiple ausgewählten Elemente abwählen:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Das Tag
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
erzeugt den folgenden Code HTML:
Um den JavaScript-Code zu verstehen, der mit den Schaltflächen [Effacer] verbunden ist, wollen wir uns noch einmal vor Augen führen, wie die verschiedenen Elemente eines Webdokuments in einem JavaScript-Code bezeichnet werden, der dieses Dokument nutzt:
Bezeichnung | Bedeutung |
bezeichnet das gesamte Webdokument | |
bezeichnet die Sammlung der im Dokument definierten Formulare | |
bezeichnet das Formular Nr. i des Dokuments | |
bezeichnet das Formular <form>, dessen Attribut „name“ den Wert „nomFormulaire“ hat | |
bezeichnet das Formular <form>, dessen Attribut „name“ den Wert „nomFormulaire“ hat | |
bezeichnet die Sammlung der Elemente, die zu dem durch den Ausdruck [formulaire] bezeichneten Formular gehören. Diese Sammlung umfasst alle Tags <input>, <textarea> und <select> des bezeichneten Formulars. | |
bezeichnet das Element Nr. i von [formulaire] | |
bezeichnet das Element von [formulaire], dessen Attribut „name“ den Wert nomComposant hat | |
bezeichnet das Element von [formulaire], dessen Attribut „name“ den Wert „nomComposant“ hat | |
bezeichnet den Wert der Komponente [composant] des Formulars [formulaire], wenn der Code HTML dieses Formulars ein „value“-Attribut haben kann (<input>, <textarea>) | |
bezeichnet den Index der in einer Liste ausgewählten Option. Kann zum Lesen und Schreiben verwendet werden. Wenn diese Eigenschaft auf -1 gesetzt wird, werden alle Elemente der Liste abgewählt. | |
bezeichnet das Array der Optionen, die einem <select>-Tag zugeordnet sind | |
bezeichnet die Option Nr. i des angegebenen <select>-Tags | |
Boolescher Wert, der angibt, ob die Option Nr. i des angegebenen Tags [select] ausgewählt ist (true) oder nicht. Kann zum Lesen und Schreiben verwendet werden |
Werfen wir noch einmal einen Blick auf den JavaScript-Code der beiden Schaltflächen:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Beim Klicken auf die Schaltfläche wird der dem Attribut „onclick“ zugeordnete Code ausgeführt. Hier handelt es sich um Inline-Code. Meistens schreibt man onclick="Funktion(...)", wobei „Funktion“ eine Funktion ist, die innerhalb eines Tags <script language="javascript">...</script> definiert ist. Was macht der obige Code? Kommentieren wir den Code der ersten Schaltfläche:
bezeichnet das Webdokument, in dem sich die Schaltfläche befindet | |
bezeichnet das Formular, in dem sich die Schaltfläche befindet | |
bezeichnet die Komponente listeSimple des Formulars | |
bezeichnet den Index der in listeSimple ausgewählten Option. Wenn Sie diese Eigenschaft auf -1 setzen, wird die Auswahl aller Optionen aufgehoben. |
6.4.2. Die Ansicht confirmation.jsp
Zur Erinnerung: Diese Ansicht wird nach Abschluss der Aktion /Bestätigung c.a.d angezeigt, nachdem das in der Ansicht formulaire.jsp enthaltene Formular vom Web-Client übermittelt wurde. Ihr einziger Zweck besteht darin, die vom Benutzer eingegebenen Werte anzuzeigen. Ihr Code lautet wie folgt:
<%@ 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>
Wir stellen hier zwei neue Tag-Bibliotheken vor: struts-bean und struts-logic. Die Bibliothek struts-bean ermöglicht den Zugriff auf Objekte, die in der Anfrage, der Sitzung oder dem Anwendungskontext abgelegt sind. Die Bibliothek „struts-logic“ ermöglicht es, mithilfe von Tags Ausführungslogik einzubinden. Diese beiden Bibliotheken sind keineswegs unverzichtbar. Wie wir gesehen haben, kann eine Seite JSP:
- Objekte aus der Anfrage (request.getAttribute(...)), der Sitzung (session.getAttribute(...)) oder dem Anwendungskontext abrufen
- dynamische Teile mithilfe von Variablen <%= Variable %> in den Code HTML einbinden
- Java-Code enthalten <% Java-Code %>
Das Einfügen von Java-Code in JSP-Seiten stört alle, die eine strikte Trennung zwischen Anwendungslogik (Java-Code) und Darstellung (Verwendung von Tags) wünschen. Deshalb wurden für sie Tag-Bibliotheken entwickelt.
Wir gehen genauso vor wie bei der Ansicht formulaire.jsp und erläutern jedes der im Code von confirmation.jsp vorhandenen Tags, sofern diese nicht bereits in der Ansicht formulaire.jsp behandelt wurden. Zunächst ist zu beachten, dass die Seite mit der Deklaration der drei Tag-Bibliotheken beginnt, die sie verwenden wird:
<%@ 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" %>
Beachten Sie außerdem, dass diese drei Bibliotheken in der Datei web.xml der Anwendung deklariert werden müssen. Wir kommentieren nun die Tags des Dokuments formulaire.jsp:
schreibt einen Wert in den aktuellen Datenstrom HTML. Das Tag „bean:write“ unterstützt die folgenden Attribute: name: Name des zu verwendenden Objekts scope: Geltungsbereich (request, session, context), in dem nach diesem Objekt gesucht werden soll property: Feld des durch „name“ bezeichneten Objekts, dessen Eigenschaft geschrieben werden soll. Dieses Feld kann ein Objekt beliebigen Typs sein. Es wird die Methode toString des Objekts verwendet. Hier wird der Wert des Felds „opt“ von dynaFormulaire geschrieben. Der Wert lautet entweder „ja“, wenn der Benutzer das Optionsfeld mit dem Attribut „value=“ja““ ausgewählt hat, oder „nein“, wenn er das Optionsfeld mit dem Attribut „value=“nein““ ausgewählt hat |
Schreibt den Wert des Feldes chk1 aus dynaFormulaire. Der Wert ist entweder „on“, wenn der Benutzer das Kontrollkästchen aktiviert hat, oder „off“, wenn nicht. Gleiches gilt für chk2 und chk3. |
schreibt den Wert des Feldes champSaisie aus dynaFormulaire, d. h. den vom Benutzer in dieses Feld eingegebenen Text. Gleiches gilt für „mdp“, boiteSaisie. |
schreibt den Wert des Kombinationsfelds von dynaFormulaire. Man erhält das Attribut „value“ des vom Benutzer ausgewählten Elements <option>. |
Schreibt den Wert des Feldes listeSimple aus dynaFormulaire. Dabei wird das Attribut „value“ des vom Benutzer ausgewählten Elements <option> verwendet, sofern ein solches vorhanden war. Andernfalls wird die leere Zeichenfolge zurückgegeben. |
Hier fügen wir Logik-Tags ein. Es handelt sich um eine Auswahlliste. Der Wert des Feldes listeMultiple des Objekts dynaFormulaire ist ein String-Array. In Java würden wir eine Schleife schreiben. Mit dem Tag „logic:iterate“ können wir dieselbe Schleife ausführen, ohne Java-Code schreiben zu müssen. Das Tag „logic:iterate“ hat im Beispiel die folgenden Attribute: name="dynaFormulaire": Name des zu verwendenden Objekts property="listeMultiple": Name der Eigenschaft, die in dem durch „name“ angegebenen Objekt die Sammlung enthält, die in der Schleife durchlaufen wird. Hier ist diese Sammlung das Array der in listeMultiple ausgewählten Werte. Dieses Array kann leer sein. id="choix": Kennung, die bei jedem Durchlauf der Schleife das aktuelle Element des Arrays bezeichnet. Bei der ersten Iteration steht „choix“ für listeMultiple[0], bei der zweiten für listeMultiple[1] und so weiter. indexID="index": Bezeichner, der bei jedem Durchlauf der Schleife den Index des aktuellen Elements des Arrays angibt. Bei der ersten Iteration hat „index“ den Wert 0, bei der zweiten den Wert 1 und so weiter. Der Code HTML, der zwischen den Tags <logic:iterate ...> und </logic:iterate> steht, wird für jedes Element der durch das Paar (name,property) bezeichneten Sammlung wiederholt. Der dynamische Teil dieses Codes lautet wie folgt:
Aus den vorangegangenen Ausführungen folgt, dass bei der Iteration Nr. i (i >= 0) der generierte Code HTML dem folgenden Code entspricht: |
erzeugt einen Link, der sich auf den Kontext der Anwendung bezieht, sodass dessen Kenntnis nicht erforderlich ist. Der durch dieses Tag generierte Code HTML lautet wie folgt: |
6.5. Die Java-Klassen
Die Konfigurationsdatei struts-config.xml verweist auf zwei Java-Klassen:
<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"
>
Die Klasse DynaFormulaire ist die Klasse, die die Werte der Ansicht Nr. 1 formulaire.jsp enthält. Die Klasse InitFormulaireAction ist die Klasse, die die Werte des Formulars verarbeitet, das über die Schaltfläche [Envoyer] von formulaire.jsp übermittelt wurde.
6.5.1. Die Klasse DynaFormulaire
Um die Werte eines Formulars zu speichern, reicht ein Objekt vom Typ DynaActionForm aus, es sei denn, eine der Methoden „reset“ oder „validate“ dieser Klasse muss neu definiert werden. In diesem Fall muss die Methode „validate“ nicht neu definiert werden, da keine Datenvalidierung durchgeführt wird. Die Methode „reset“ muss jedoch neu definiert werden. Denn die Felder des Objekts DynaFormulaire erhalten ihre Werte aus dem vom Web-Client gesendeten Formular. Bestimmte Felder erhalten jedoch möglicherweise keinen Wert, wenn sie in der Anfrage nicht vorhanden sind. Dies tritt in den folgenden Fällen auf:
- ein Kontrollkästchen, das vom Benutzer nicht angekreuzt wurde
- eine Liste mit mehr als einem Eintrag oder es wurde keine Option ausgewählt
Bei Formularen mit dieser Art von Komponente muss die Methode „reset“
- dem Feld, das dem Kontrollkästchen zugeordnet ist, den Wert „off“ zuweisen
- dem Feld, das einer Liste mit Einzelauswahl zugeordnet ist, die leere Zeichenkette zuweisen
- dem Feld, das einer Mehrfachauswahlliste zugeordnet ist, ein Array von Zeichenfolgen der Größe Null zuweisen
Wenn diese Felder also keinen Wert aus der Abfrage erhalten, behalten sie den durch „reset“ zugewiesenen Wert bei, der dem Zustand der Komponente in dem vom Benutzer validierten Formular entspricht (Kontrollkästchen nicht markiert, Liste ohne ausgewähltes Element).
Der Code der Klasse DynaFormulaire, einer von DynaActionForm abgeleiteten Klasse, lautet wie folgt:
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){
// Checkboxen zurücksetzen – Wert „off“
set("chk1","off");
set("chk2","off");
set("chk2","off");
// Zurücksetzen von listeSimple – leere Zeichenfolge
set("listeSimple","");
// Zurücksetzen von listeMultiple – leeres Array
set("listeMultiple",new String[]{});
}
}
6.5.2. Die Klasse InitFormulaireAction
Die Klasse InitFormulaireAction ist in der Datei struts-config.xml der Aktion /init zugeordnet:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
Die Aktion /init wird nur einmal beim anfänglichen Aufbau des Objekts DynaFormulaire verwendet. Sie dient dazu, die drei Listen des Kombinationsfelds listeSimple, listeMultiple mit Inhalten zu füllen. Dieser Inhalt wird in Form von drei Arrays bereitgestellt, die Eigenschaften des Objekts dynaFormulaire sind:
<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>
Sobald die Tabellen valeursCombo, valeursListeSimple und valeursListeMultiple durch InitFormulaireAction initialisiert wurden, müssen sie nicht erneut initialisiert werden. Das Objekt dynaFormulaire wird nämlich in die Sitzung aufgenommen und behält daher seinen Wert über mehrere Anfrage-Antwort-Zyklen hinweg bei. Aus diesem Grund wird die Aktion /init nur einmal ausgeführt. Der Code von InitFormulaireAction lautet wie folgt:
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 {
// bereitet das Formular zur Anzeige vor
// Die erforderlichen Informationen werden in die Bean des Formulars geschrieben
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
// die Kontrolle wird zurückgegeben
return mapping.findForward("afficherFormulaire");
} //wird ausgeführt
// Liste der Werte des Kombinationsfelds
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;
}
}
- Die Klasse leitet sich von der Klasse „Action“ ab. Dies ist zwingend erforderlich.
- Der Struts-Controller verwendet über seine Methode „execute“ ein Action-Objekt. Diese Methode muss daher neu definiert werden. Sie erhält die folgenden Parameter:
- ActionMapping mapping: ein Objekt, das die Konfiguration der Anwendung in struts-config.xml darstellt
- ActionForm form: das der Aktion zugeordnete Formular, sofern in der Konfiguration der Aktion eines definiert ist (Attribut „name“ der Aktion).
- HttpServletRequest request: die Anfrage des Clients
- HttpServletResponse: die Antwort an den Client
- Die Klasse InitFormulaireAction muss das Formular dynaFormulaire initialisieren. Dieses wird in der Methode „execute“ als Parameter ActionForm form übergeben. Zur Erinnerung: dynaFormulaire ist vom Typ DynaFormulaire, einer Klasse, die von der Klasse DynaActionForm abgeleitet ist, die wiederum von der Klasse ActionForm abgeleitet ist.
- In der Methode „execute“ werden den drei Feldern valeursCombo, valeursListeSimple und valeursListeMultiple mithilfe der Methode „set“ der Klasse DynaActionForm Werte zugewiesen. Der Einfachheit halber handelt es sich bei diesen Werten um beliebige Arrays. Beachten Sie, dass die Methode „set“ einem vorhandenen Feld einen Wert zuweist. Sie kann nicht zum Anlegen neuer Felder verwendet werden. Aus diesem Grund müssen die drei Felder valeursCombo, valeursListeSimple, valeursListeMultiple in der Definition des Objekts dynaFormulaire in struts-config.xml zu definieren.
- Die Methode „execute“ endet damit, dass sie dem Controller den Schlüssel der anzuzeigenden Ansicht als Antwort an den Client zurückgibt. In diesem Fall ist es der Schlüssel afficherFormulaire, der in der Datei struts-config.xml der Ansicht /vues/formulaire.jsp zugeordnet wurde.
6.6. Bereitstellung
Die Verzeichnisstruktur der Anwendung sieht wie folgt aus:
![]() | ![]() |
![]() | ![]() |


Zur Erinnerung: Die oben genannte Datei „ApplicationResources.properties“ wird von der Struts-Bean-Tag-Bibliothek benötigt. Diese Datei enthält die Meldungen der Anwendung, auf die die Struts-Bean-Bibliothek zugreifen kann. In unserer Anwendung sind jedoch keine Meldungen definiert. Daher existiert die Datei „ApplicationResources.properties“ zwar, ist aber leer.
6.7. Fazit
In dieser Lektion haben wir detailliert beschrieben, wie die verschiedenen Komponenten eines Formulars HTML verwaltet werden. Wir können nun komplexe Formulare in unseren Struts-Anwendungen verwenden.






