Skip to content

6. HTML-Formulare

Bisher haben wir ein einzelnes Formular verwendet, das nur zwei Eingabefelder enthält. Hier schlagen wir vor, ein Formular unter Verwendung von Standard-Grafikkomponenten (Optionsfelder, Kontrollkästchen, Eingabefelder, Kombinationsfelder, Listen) zu erstellen und zu verarbeiten.

6.1. Die Ansichten der Anwendung

Die Anwendung wird nur zwei Ansichten haben. Die erste zeigt ein leeres Formular an:

ANSICHT 1 – Formular

Image

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

Image

Die Schaltfläche [Submit] bestätigt die eingegebenen Werte. Dies wird die zweite Ansicht sein:

Image

Diese zweite Ansicht ermöglicht es uns, zwei weitere Tag-Bibliotheken zu verwenden: struts-bean und struts-logic. Über den Link [Zurück zum Formular] können wir zu dem Formular zurückkehren, das wir gerade ausgefüllt haben. Wir gelangen dann zurück zur ersten Ansicht.

6.2. Die Anwendungsarchitektur

  • Das Formular (Ansicht 1) wird durch ein dynamisches Struts-Objekt namens dynaFormulaire dargestellt, eine Unterklasse von DynaActionForm. Es wird über die Ansicht form.jsp angezeigt.
  • Die Struts-Aktion „InitFormulaireAction“ ist für das Abrufen der zur Anzeige des Formulars erforderlichen Daten zuständig
  • Das ausgefüllte Formular wird von einer ForwardAction verarbeitet, die die Anfrage einfach an die zweite Ansicht, confirmation.jsp, weiterleitet. Diese Ansicht ist für die Anzeige der Formularwerte zuständig.

6.3. Anwendungskonfiguration

6.3.1. Die Datei server.xml

Der Anwendungskontext erhält den Namen /formulaire2. Wir fügen daher die folgende Zeile in die Datei server.xml von Tomcat ein:

    <Context path="/formulaire2" docBase="e:/data/serge/web/struts/formulaire2" />

Sobald dies erledigt ist, müssen wir Tomcat möglicherweise neu starten, damit es den neuen Kontext erkennt. Wir können überprüfen, ob er gültig ist, indem wir die URL http://localhost:8080/formulaire2 aufrufen:

Image

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>

Im Vergleich zu den bereits bekannten web.xml-Konfigurationsdateien nehmen wir einige Änderungen vor:

  • Wir führen zwei neue Tag-Bibliotheken ein: „struts-bean“ und „struts-logic“. Diese werden in der Ansicht „confirmation.jsp“ verwendet. Die Ansicht „formulaire.jsp“ hingegen nutzt 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>

Es enthält drei Hauptabschnitte:

  • die Deklaration von Formularen im Abschnitt <form-beans>
  • die Deklaration von Aktionen im Abschnitt <action-mappings>
  • die Deklaration der Ressourcendatei im Abschnitt <message-resources>

6.3.4. Die Formularobjekte (Beans) der Anwendung

Die Objekte, die zur Darstellung der HTML-Formulare der Anwendung verwendet werden, sind vom Typ ActionForm oder einem abgeleiteten Typ (DynaActionForm, DynaValidatorForm usw.). Sie werden als Beans bezeichnet, da ihre Konstruktion den Regeln von JavaBeans folgt. In unserer Anwendung gibt es nur eine Formular-Bean namens dynaFormulaire, die von DynaActionForm abgeleitet ist. Sie wird in den folgenden Situationen verwendet:

  • um die zur Anzeige von Ansicht Nr. 1 benötigten Daten zu enthalten
  • zum Abrufen der Werte aus dem Formular in Ansicht Nr. 1, wenn der Benutzer es absendet
  • um die Daten zu enthalten, die zur Anzeige von Ansicht Nr. 2 benötigt werden

Die Struktur des dynaFormulaire-Beans ist eng mit dem Formular in Ansicht Nr. 1 verknüpft. Sehen wir uns das einmal an:

Nr.
HTML-Typ
Rolle
1
<input name="opt" type="radio" value="yes">
<input name="opt" type="radio" value="no">
Gruppe miteinander verknüpfter Radiobuttons (gleicher Name)
2
<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 derselbe Name)
3
<input type="text" name="inputField">
ein Textfeld
4
<input type="password" name="password">
ein Passwortfeld
5
<textarea name="inputBox">...</textarea>
ein mehrzeiliges Eingabefeld
6
<select name="combo" size="1">..</select>
ein Dropdown-Menü
7
<select name="simpleList" size="3">..</select>
eine Liste mit Einzelauswahl
8
<select name="listeMultiple" size="3" multiple>..</select>
eine Mehrfachauswahlliste
9
<input type="button" value="Löschen"
onclick='clearList("singleList")'>
Schaltfläche zum Abwählen
die ausgewählten Elemente in simpleList (7)
10
<input type="button" value="Löschen"
onclick='clearList("multipleList")'>
Schaltfläche zum Abwählen
die ausgewählten Elemente in multipleList (8)
11
<input type="submit" value="Absenden">
Formular-Absenden-Schaltfläche
12
<input type="hidden" name="secret" value="...">
ein verstecktes Feld

Betrachten wir einige Fälle:

  1. Das dynaFormulaire-Objekt dient dazu, die Werte aus dem obigen HTML-Formular zu speichern, die über die Schaltfläche [Absenden] übermittelt werden. Es muss daher dieselben Felder wie das HTML-Formular enthalten. Der Feldtyp wird durch die folgende Regel bestimmt:
  • Wenn das HTML-Feld nur einen Wert enthält, ist das dynaFormulaire-Feld vom Typ java.lang.String
  • Wenn das HTML-Feld mehrere Werte liefert, hat das dynaFormulaire-Feld den Typ java.lang.String[]

Im obigen HTML-Formular kann nur das Feld listeMultiple mit mehreren Werten (den vom Benutzer ausgewählten) verknüpft werden. Daher würde eine anfängliche Definition des Objekts **dynaFormulaire** 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 wird dynaFormulaire mit den vom Web-Client gesendeten HTML-Formularwerten gefüllt?

opt
Das Feld „opt“ erhält den Wert „yes“, wenn das HTML-Feld <input type="radio" name="opt" value="yes"> ausgewählt wurde, und den Wert „no“, wenn das Feld <input type="radio" name="opt" value="no"> ausgewählt wurde.
chk1
Das Feld „chk1“ erhält den Wert „on“, wenn das HTML-Feld <input name="chk1" type="radio" value="1"> ausgewählt wurde; andernfalls erhält es keinen Wert. Im letzteren Fall behält das Feld „chk1“ seinen vorherigen Wert bei.
chk2
gleich
chk3
gleich
Eingabefeld
Das Feld `champSaisie` erhält den Text, den der Benutzer in das HTML-Feld `<input type="text" name="champSaisie">` eingegeben hat. Dieser Text kann eine leere Zeichenfolge sein.
Passwort
Das Feld „mdp“ erhält den Text, den der Benutzer in das HTML-Feld `<input type="password" name="mdp">` eingegeben hat. Dieser Text kann eine leere Zeichenfolge sein.
textarea
Das Feld „inputBox“ erhält den Text, den der Benutzer in das HTML-Feld <textarea name="inputBox">...</textarea> eingegeben hat. 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 optional eine leere Zeichenkette sein.
combo
Das Feld „combo“ erhält die vom Benutzer im HTML-Feld <select name="combo" size="1">..</select> ausgewählte Option. Die ausgewählte Option ist diejenige, die im Kombinationsfeld angezeigt wird. Wenn die ausgewählte HTML-Option vom Typ <option value="XX">YY</option> ist, erhält das Feld „combo“ den Wert „XX“. Wenn die ausgewählte HTML-Option vom Typ <option>YY</option> ist, erhält das Combo-Feld den Wert „YY“.
simpleList
Das simpleList-Feld erhält die vom Benutzer im HTML-Feld <select name="simpleList" size="..">..</select> ausgewählte Option, sofern eine vorhanden ist. Ist keine vorhanden, erhält das simpleList-Feld keinen Wert und behält seinen vorherigen Wert bei. Der dem simpleList-Feld tatsächlich zugewiesene Wert folgt den für die Combobox festgelegten Regeln.
listeMultiple
Das Feld „listeMultiple“ vom Typ „String[]“ nimmt die vom Benutzer im HTML-Feld <select name="listeMultiple" size=".." multiple>..</select> ausgewählten Optionen auf, sofern vorhanden. Sind keine vorhanden, erhält das Array „listeMultiple“ keinen Wert und sein Inhalt bleibt unverändert. Die dem Array „listeMultiple“ tatsächlich zugewiesenen Werte folgen den für das Kombinationsfeld festgelegten Regeln.
secret
Das Feld „secret“ erhält den Wert XX aus dem HTML-Feld <input type="hidden" name="secret" value="XX">. Dieser Text kann optional eine leere Zeichenfolge sein.
  1. Das dynaFormulaire-Objekt wird verwendet, um den Anfangsinhalt für Ansicht Nr. 1 bereitzustellen. Die Werte der vorangehenden Felder werden für folgende Zwecke verwendet:
opt
muss den Wert „yes“ oder „no“ haben, damit der Browser weiß, welches Optionsfeld ausgewählt werden soll
chk1
Wenn chk1 den Wert „on“ hat, wird das Kontrollkästchen aktiviert; andernfalls bleibt es deaktiviert
chk2
dasselbe
chk3
gleich
Eingabefeld
Der Feldwert wird im Eingabefeld angezeigt fieldInput
Passwort
Der Feldwert wird im MDP-Eingabefeld angezeigt
inputBox
Der Feldwert wird im Eingabefeld angezeigt. inputBox
combo
Der Wert dieses Feldes gibt an, welches Element in der Kombinationsfeld ausgewählt werden soll, wenn das Formular angezeigt wird
simpleList
same
multipleList
Die Werte im Array „multipleList“ geben an, welche Elemente in der Mehrfachauswahlliste ausgewählt werden sollen, wenn das Formular angezeigt wird
geheim
Der Wert des Feldes wird dem value-Attribut des geheimen HTML-Feldes zugewiesen.

Ansicht Nr. 1 erfordert zusätzliche Informationen:

  • die Liste der Werte, die in der Kombinationsliste angezeigt werden sollen
  • die Liste der Werte, die in der `listeSimple`-Liste angezeigt werden sollen
  • die Liste der Werte, die in der multipleList angezeigt werden sollen

Es gibt mehrere Möglichkeiten, diese Informationen an die Ansicht zu übergeben. Beispielsweise würden Arrays funktionieren, die in der an die Ansicht übergebenen Anfrage enthalten sind. Hier platzieren wir diese Arrays im dynaFormulaire-Bean:

        <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 dynaFormulaire-Formular wird durch die Aktion /init initialisiert, die ein von Action abgeleitetes Objekt namens InitFormulaireAction aufruft. Dieses Objekt ist dafür zuständig, die drei zur Anzeige der drei Listen erforderlichen Arrays zu erstellen und sie in der dynaFormulaire-Bean abzulegen. Die Konfigurationsdatei legt den Gültigkeitsbereich dieser Bean auf „session“ fest. Infolgedessen legt der Struts-Controller diese Bean in der Sitzung ab. Wir müssen sie daher nicht zwischen den Anfrage-Antwort-Zyklen neu generieren. Folglich wird die Aktion /init nur einmal aufgerufen.

  1. Das dynaFormulaire-Objekt wird auch zum Befüllen der Ansicht Nr. 2 verwendet. Diese Ansicht zeigt lediglich die Werte an.

6.3.5. Anwendungsaktionen

Aktionen werden von Objekten des Typs „Action“ oder abgeleiteten Typen verarbeitet. Die Konfiguration der Aktionen erfolgt innerhalb der <action-mappings>-Tags:

    <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>

Beachten Sie, dass nicht immer ein Formular mit einer Aktion verknüpft ist. Dies ist oben bei der Aktion /affiche der Fall. Bevor wir jede Aktion im Detail betrachten, wollen wir uns noch einmal ansehen, wie das Paar aus Aktion und Formular innerhalb eines <action>-Tags funktioniert:

  • Eine Aktion beginnt mit einer Anfrage eines Web-Clients und endet mit dem Senden einer Antwortseite. Dies ist der Client-Server-Zyklus von Anfrage und Antwort im Web. Die Anfrage wird vom Struts-Controller vom Typ ActionServlet oder einer davon abgeleiteten Klasse empfangen. Dieser Controller sendet auch die Antwort.
  • Die Formular-Bean vom Typ ActionForm oder einer abgeleiteten Klasse wird erstellt, falls sie noch nicht existiert. Der Controller prüft, ob er ein Objekt mit dem Namen name im durch scope angegebenen Bereich finden kann. Ist dies der Fall, verwendet er es. Ist dies nicht der Fall, erstellt er es und legt es in dem durch scope angegebenen Bereich ab, verknüpft mit dem durch name angegebenen Attribut.

Im Beispiel der Aktion /init ruft der Controller beispielsweise request.getSession().getAttribute("dynaFormulaire") auf, um festzustellen, ob dynaFormulaire bereits erstellt wurde oder nicht. Falls nicht, erstellt er es und fügt es der Sitzung mit einer Anweisung wie request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)) hinzu.

  • 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 reset-Methode des Formular-Beans wird aufgerufen. Dieses Bean wird – außer bei seiner erstmaligen Erstellung – wiederverwendet. Es enthält daher Daten, die Sie möglicherweise „bereinigen“ möchten. Dies geschieht in der reset-Methode des ActionForm-Beans oder einer abgeleiteten Klasse.
  • Ist die Aktion das Ziel eines übermittelten Formulars, werden die in der Client-Anfrage enthaltenen Formularwerte in die gleichnamigen Felder der Formular-Bean kopiert. Beachten Sie, dass die reset-Methode vor diesem Kopiervorgang aufgerufen wurde.
  • Wenn die Konfiguration das Attribut validate="true" angibt, wird die Validierungsmethode der Formular-Bean aufgerufen. Diese Methode muss dann die Daten in der Bean validieren. Diese Validierung findet typischerweise nur statt, wenn das Formular gerade neue Daten über ein übermitteltes Formular erhalten hat und Sie die Gültigkeit dieser Daten überprüfen möchten. Diese Methode gibt eine Liste von Fehlern in einem ActionErrors-Objekt an den Controller zurück.
  • Ist das ActionErrors-Objekt nicht leer, zeigt der Controller die durch das input-Attribut der Aktion angegebene Ansicht an.
  • Wenn keine Datenvalidierung erforderlich ist oder diese erfolgreich war, ruft der Controller die `execute`-Methode des `Action`-Objekts (oder einer abgeleiteten Klasse) auf, das der aktuellen Aktion zugeordnet ist. Innerhalb dieser Methode wird die Anfrage des Web-Clients verarbeitet. Die `execute`-Methode gibt ein `ActionForward`-Objekt zurück, das durch String-Schlüssel indiziert ist. Diese Schlüssel sind diejenigen, die durch die `forward`-Tags der konfigurierten Aktion deklariert wurden. In unserem Beispiel verfügt die Aktion `/init` über ein einziges `forward`-Tag. Es ordnet den Schlüssel „displayForm“ der Ansicht `form.jsp` zu.
  • Der Controller zeigt die Ansicht an, die dem empfangenen Schlüssel zugeordnet ist. Diese Ansicht kann tatsächlich eine Aktion sein; in diesem Fall wird der vorherige Prozess 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 wird normalerweise einmal während des ersten Anfrage-Antwort-Zyklus ausgeführt, wenn der Benutzer die URL http://localhost:8080/formulaire2/init.do aufruft
  • Das dynaForm-Objekt wird erstellt oder wiederverwendet. Es wird entsprechend der Angabe im Attribut „scope“ aus der Sitzung abgerufen (Wiederverwendung) oder in die Sitzung eingefügt (Erstellung).
  • Seine Reset-Methode wird aufgerufen. Was soll sie tun? Normalerweise werden die Felder des ActionForm-Objekts auf Standardwerte zurückgesetzt. In diesem Fall tun wir dies jedoch nicht, da das dynaFormulaire-Objekt in die Sitzung eingefügt wird (scope="session"). Die Felder von dynaFormulaire müssen daher ihre Werte beibehalten. Wie lauten diese Werte bei der erstmaligen Erstellung des dynaFormulaire-Objekts? Es gibt zwei Fälle:
  • Das Feld hat einen in der Konfigurationsdatei angegebenen Anfangswert:
            <form-property name="opt" type="java.lang.String" initial="non"/>

In diesem Fall erstellt der Struts-Controller dieses Feld mit diesem Anfangswert.

  • Wenn für das Feld in der Konfiguration kein Anfangswert angegeben ist, gelten die Initialisierungsregeln von Java. Im Allgemeinen erhalten numerische Felder den Wert Null, Zeichenfolgen die leere Zeichenfolge und andere Objekte den Wert null.

Sehen wir uns die Anfangskonfiguration 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 dynaFormulaire-Felder nach der Erstellung lauten wie folgt:

Feld
Anfangswert
opt
"nein"
chk1, chk2, chk3
leere Zeichenfolge
Eingabefeld
leere Zeichenfolge
mdp
leere Zeichenfolge
Eingabefeld
leere Zeichenfolge
Kombinationsfeld
leere Zeichenfolge
einfache Liste
leere Zeichenkette
mehrere Listen
Array aus leeren Zeichenfolgen
Geheimnis
„xxx“
comboValues, singleList, multipleList
Array aus leeren Zeichenfolgen
  • Man könnte sich vorstellen, dass die Reset-Methode von dynaFormulaire den drei Arrays Werte zuweist, die die drei Listen in der Ansicht formulaire.jsp füllen. Dies wäre hier möglich, da die Daten in diesen drei Arrays willkürlich generiert werden. Das häufigste Szenario ist jedoch, dass diese Daten aus dem Anwendungsmodell stammen, dem M in MVC. Hier wählen wir einen Mittelweg – um das Beispiel einfach zu halten –, indem wir diese Werte von der Aktion InitFormulaireAction generieren lassen, also vom C in MVC.
  • Es ist nicht erforderlich, eine Reset-Methode in dynaFormulaire zu schreiben, da die ActionForm-Klasse, von der es abgeleitet ist, bereits über eine solche Methode verfügt, die nichts tut (keine Initialisierungen).
  • Sobald die Reset-Methode von dynaFormulaire aufgerufen wird, überprüft der Controller das „validate“-Attribut der Aktion. Hier hat es den Wert „false“. Die „validate“-Methode von dynaFormulaire wird nicht aufgerufen.
  • Das InitFormulaireAction-Objekt wird erstellt oder wiederverwendet, falls es bereits existierte, und seine execute-Methode 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 zeigt die Ansicht /vues/formulaire.jsp an, die über ein Forward-Tag aus der Aktion /init mit dem Schlüssel „afficherFormulaire“ verknüpft 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 [Submit] klickt. Der Browser sendet dann das vom Benutzer ausgefüllte Formular an den Struts-Controller.
  • Das dynaFormulaire-Objekt wird aus der Sitzung abgerufen
  • die Reset-Methode aufgerufen wird. Sobald dies geschehen ist, kopiert der Struts-Controller die vom Client übermittelten Werte der Formularfelder in die gleichnamigen Felder in dynaFormulaire. Sehen wir uns die Liste der Felder in dynaFormulaire an und schauen wir uns an, wie dieses Kopieren funktioniert:
Feld
Zugehöriger HTML-Code
Feldwert
nach dem Kopieren der Formularwerte
opt
<input type="radio" name="opt" value="yes">Ja
<input type="radio" name="opt" value="no" checked="checked">Nein
- „yes“ oder „no“, je nach ausgewähltem Optionsfeld
chk1
<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 aktiviert wurde
chk2
<input type="checkbox" name="chk2" value="on">
- „on“, wenn das Kontrollkästchen chk2 aktiviert wurde
- behält seinen vorherigen Wert bei, wenn das Kontrollkästchen chk2 nicht aktiviert wurde
chk3
<input type="checkbox" name="chk2" value="on">
- „on“, wenn das Kontrollkästchen chk3 aktiviert wurde
- behält seinen vorherigen Wert bei, wenn das Kontrollkästchen chk3 nicht aktiviert wurde
inputField
<input type="text" name="inputField" value="">
- vom Benutzer in inputField eingegebener Wert
Passwort
<input type="password" name="password" value="">
- vom Benutzer in „password“ eingegebener Wert
Eingabefeld
<textarea name="inputBox"></textarea>
- vom Benutzer in das Textfeld eingegebener Wert
combo
<select name="combo">...</select>
- vom Benutzer im Kombinationsfeld ausgewählter Wert
simpleList
<select name="simpleList" size="3">...</select>
- vom Benutzer in der simpleList ausgewählter Wert
multipleList
<select name="listeMultiple" multiple="multiple" size="5">
- Array von Zeichenfolgen, das die vom Benutzer in multipleList ausgewählten Werte enthält
secret
<input type="hidden" name="secret" value="xxx">
- „xxx“.

Es tritt ein Problem bei Feldern auf, die in der vom Browser gesendeten Anfrage nicht unbedingt einen Wert erhalten. Dies gilt für die Kontrollkästchen chk1 bis chk3 sowie die beiden Listen listeSimple und listeMultiple. In diesem Fall behalten diese Felder ihre vorherigen Werte bei – jene, die während des vorherigen Anfrage-Antwort-Zyklus erfasst wurden.

Betrachten wir zum Beispiel das Kontrollkästchen chk1 und nehmen wir an, dass der Benutzer dieses Kästchen im vorherigen Anfrage-Antwort-Zyklus aktiviert hatte. Der Browser hat daraufhin die Information chk1="on" in der Parameterzeichenfolge seiner Anfrage gesendet. Der Konstruktor hat daher dem Feld chk1 von dynaFormulaire 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. Infolgedessen behält das Feld chk1 in dynaFormulaire seinen Wert „on“ bei und weist somit einen Wert auf, der nicht dem vom Benutzer validierten Formular entspricht. Wir werden die reset-Methode von dynaFormulaire verwenden, um dieses Problem zu beheben. In dieser Methode setzen wir die drei Felder chk1, chk2 und chk3 auf „off“. In unserem chk1-Beispiel hat der Benutzer entweder:

  • das Kontrollkästchen chk1 aktivieren. In diesem Fall sendet der Browser die Information chk1="on" und das Feld chk1 in dynaFormulaire ändert sich auf „on“
  • oder er aktiviert das Kontrollkästchen chk1 nicht. 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 sowohl bei der simpleList- als auch bei der multiList-Liste auf. Wenn in diesen Listen keine Option ausgewählt wurde, sind sie nicht in den Anfrageparametern enthalten und behalten daher ihre vorherigen Werte bei. In der reset-Methode von dynaFormulaire setzen wir simpleList mit einer leeren Zeichenkette und multiList mit einem 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, zurück in die Felder von dynaFormulaire
  • Ein ForwardAction-Objekt wird erstellt oder wiederverwendet, und seine execute-Methode wird aufgerufen. ForwardAction ist eine vordefinierte Klasse, die ein ActionForward-Objekt zurückgibt, das auf die durch das „parameter“-Attribut der Aktion definierte Ansicht verweist, in diesem Fall /vues/confirmation.jsp.
  • Der Controller sendet diese Ansicht. Der Zyklus ist abgeschlossen.

Die /display

      <action
          path="/affiche"
          parameter="/vues/formulaire.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
  • Die Aktion /display wird durch Klicken auf den Link [Zurück zum Formular] in Ansicht Nr. 2 ausgelöst.
  • Hier ist der Aktion kein Formular zugeordnet. Wir fahren daher direkt mit der Ausführung der `execute`-Methode eines `ForwardAction`-Objekts fort, die ein `ActionForward`-Objekt 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:

        <message-resources 
          parameter="ApplicationResources"
            null="false"
      />    

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; andernfalls löst die Struts-Bean-Tag-Bibliothek, auf die wir später noch eingehen werden, einen Fehler aus. Diese Bibliothek wird von der Ansicht confirmation.jsp verwendet.

6.4. Der Code der Ansicht

6.4.1. Die Ansicht „formulaire.jsp“

Beachten Sie, dass diese Ansicht in zwei Fällen angezeigt wird:

  • wenn die Aktion /init während des ersten Anfrage-Antwort-Zyklus aufgerufen wird
  • wenn die Aktion /affiche während nachfolgender Zyklen aufgerufen wird

Der Code für die 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 JSP-Seite verwendet Tags aus der Struts-HTML-Bibliothek. Beachten Sie, dass Sie für die Verwendung einer Tag-Bibliothek Folgendes tun müssen:

  • 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>
  • Platzieren Sie den Code für diese Bibliothek an einer beliebigen Stelle im Anwendungsverzeichnisbaum, hier WEB-INF/struts-html.tld
  • Deklarieren Sie die Verwendung dieser Bibliothek am Anfang der JSP-Seiten, die sie nutzen:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

Die Ansicht „formulaire.jsp“ verwendet Tags, die wir nun erläutern werden:

Tag
<body background="<html:rewrite page="/images/standard.jpg"/>">
HTML-Übersetzung
<body background="/formulaire2/images/standard.jpg">
Erläuterung
Mit dem HTML-Tag „rewrite“ können Sie den Anwendungsnamen aus URLs weglassen. Es verfügt über ein Attribut:
page
Zu überschreibende URL
Wenn Sie also im obigen Beispiel beschließen, die Anwendung „form3“ zu nennen, muss der Code für das background-Attribut nicht umgeschrieben werden. Das `html:rewrite`-Tag generiert den neuen HTML-Code
background="/formulaire3/images/standard.jpg"
Tag
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
HTML-Übersetzung
<form name="dynaFormulaire" method="post" action="/formulaire2/confirmation.do">
Erläuterung
Das HTML-Tag „form“ generiert das HTML-Formular-Tag. Es verfügt über mehrere Attribute:
action
Struts-Aktion, an die das Formular gesendet werden soll – muss einer der in struts-config.xml definierten Aktionen entsprechen
name
optional – Name des ActionForm-Beans oder einer dessen Unterklasse, in das bzw. die die Werte des übermittelten Formulars geschrieben oder gelesen werden sollen. Wird dieses Attribut weggelassen, wird das Formular verwendet, das der durch das action-Attribut definierten Aktion zugeordnet ist. Diese Information findet sich in der Konfigurationsdatei (im name-Attribut der Aktion).
type
optional – Java-Klasse, die für das Formular instanziiert werden soll. Wird dieses Attribut weggelassen, wird die Klasse verwendet, die der durch das Attribut „action“ definierten Aktion zugeordnet ist. Diese Information ist in der Konfigurationsdatei zu finden (Attribut „type“ der Aktion).
Wir sehen, dass der generierte HTML-Code standardmäßig die POST-Methode verwendet. In diesem HTML-Code wurde die Aktions-URL so umgeschrieben, dass ihr der Anwendungsname vorangestellt und die Endung .do angehängt wird.
Tag
<html:radio name="dynaFormulaire" property="opt" value="yes">Ja</html:radio>
HTML-Übersetzung
<input type="radio" name="opt" value="yes">
Erläuterung
Das HTML-Tag „html:radio“ wird verwendet, um das HTML-Tag <input type="radio" ...> zu generieren. Es unterstützt verschiedene Attribute:
name
optional – Name des ActionForm-Beans oder eines abgeleiteten Beans, in dem der Wert des Feldes abgelegt oder gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
property
Name des Feldes in der Formular-Bean, das dem Optionsfeld zum Lesen und Schreiben zugeordnet ist.
Wert
optional – Wert, der dem HTML-Feld zugewiesen werden soll
Der Text zwischen dem Start- und dem End-Tag ist der Text, der neben dem Optionsfeld angezeigt wird.
Tag
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox>
HTML-Übersetzung
<input type="checkbox" name="chk1" value="on">
Erläuterung
Das HTML-Tag „html:checkbox“ wird verwendet, um das HTML-Tag <input type="checkbox" ...> zu generieren. Es unterstützt verschiedene Attribute:
name
optional – Name des ActionForm-Beans oder eines abgeleiteten Beans, in dem der Wert des Feldes abgelegt oder gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
property
Name des Feldes in der Formular-Bean, das mit dem Kontrollkästchen zum Lesen und Schreiben verknüpft ist.
Wert
optional – Wert, der dem HTML-Feld zugewiesen werden soll
Der Text zwischen dem Start- und dem End-Tag ist der Text, der neben dem Kontrollkästchen angezeigt wird.
Tag
<html:text name="dynaFormulaire" property="inputField" />
HTML-Übersetzung
<input type="text" name="inputField" value="">
Erläuterung
Das HTML-Tag „html:text“ wird verwendet, um das HTML-Tag <input type="text" ...> zu generieren. Es unterstützt verschiedene Attribute:
name
optional – Name des ActionForm-Beans oder eines davon abgeleiteten Beans, in das der Wert des Feldes geschrieben oder aus dem er gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
Eigenschaft
Name des Feldes in der Formular-Bean, das dem Lese-/Schreib-Eingabefeld zugeordnet ist.
Wert
optional – Wert, der dem HTML-Feld zugewiesen werden soll
Tag
<html:password name="dynaFormulaire" property="mdp" />
HTML-Übersetzung
<input type="password" name="mdp" value="">
Erläuterung
Das HTML-Tag „html:password“ wird verwendet, um das HTML-Tag <input type="password" ...> zu generieren. Es unterstützt verschiedene Attribute:
Tag
<html:textarea name="dynaFormulaire" property="boiteSaisie" />
HTML-Übersetzung
<textarea name="boiteSaisie"></textarea>
Erläuterung
Das HTML-Tag „textarea“ wird verwendet, um das HTML-Tag <textarea>...</textarea> zu generieren. Es unterstützt verschiedene Attribute:
name
optional – Name des ActionForm-Beans oder eines abgeleiteten Beans, in dem der Feldwert abgelegt oder gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
property
Name des Feldes in der Formular-Bean, das dem Passwortfeld zum Lesen und Schreiben zugeordnet ist.
Wert
optional – Wert, der dem HTML-Feld zugewiesen werden soll
Tag
<html:select name="dynaFormulaire" property="combo">....</html:select>
HTML-Übersetzung
<select name="combo">...</select>
Erläuterung
Das HTML-Tag `select` wird verwendet, um das HTML-Tag `<select>...</select>` zu generieren. Es unterstützt verschiedene Attribute:
name
optional – Name des ActionForm-Beans oder eines abgeleiteten Beans, in dem der Feldwert abgelegt oder gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
property
Name des Feldes in der Formular-Bean, das dem Lese-/Schreib-Eingabefeld zugeordnet ist.
Wert
optional – Wert, der dem HTML-Feld zugewiesen werden soll. Die Option der Kombinationsfelds mit diesem Wert wird ausgewählt.
Tag
<html:select name="dynaFormulaire" property="combo">
<html:options name="dynaFormulaire" property="comboValues"/>
</html:select>
HTML-Übersetzung
<option value="combo1">combo1</option>
<option value="combo2">combo2</option>

Erläuterung
Das HTML-Tag „options“ wird verwendet, um die HTML-Tags <option>...</option> innerhalb eines HTML-Tags <select> zu generieren. Es gibt verschiedene Möglichkeiten, anzugeben, wie die Werte zum Befüllen des Select-Elements ermittelt werden sollen. Hier haben wir die Attribute „name“ und „property“ verwendet:
name
optional – Name des ActionForm-Beans oder eines abgeleiteten Beans, in dem der Feldwert abgelegt oder gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
property
Name des Feldes in der Formular-Bean, das die Auswahlwerte enthält. Dies muss ein Array von Zeichenfolgen sein.

Die beiden anderen Listen werden auf ähnliche Weise wie die vorherige generiert:

          <html:select name="dynaFormulaire" property="listeSimple" size="3">
            <html:options name="dynaFormulaire" property="valeursListeSimple"/>            
        </html:select>

Oben geben wir ein size-Attribut ungleich 1 an, um eine Liste anstelle eines Kombinationsfelds zu erstellen.

<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
        <html:options name="dynaFormulaire" property="valeursListeMultiple"/>                
    </html:select>

Oben geben wir das Attribut multiple="true" an, um eine Liste mit Mehrfachauswahl zu erstellen.

Tag
<html:hidden name="dynaFormulaire" property="secret"/>
HTML-Übersetzung
<input type="hidden" name="secret" value="xxx">
Erläuterung
Das HTML-Tag „html:hidden“ wird verwendet, um das HTML-Tag <input type="hidden" ...> zu generieren.
name
optional – Name des ActionForm-Beans oder eines davon abgeleiteten Beans, in dem der Wert des Feldes abgelegt oder gelesen werden soll. Wird dieses Attribut weggelassen, wird das mit dem <html:form>-Tag verknüpfte Formular verwendet.
property
Name des Feldes in der Formular-Bean, das dem versteckten Feld zugeordnet ist. Der dem geheimen HTML-Feld zugewiesene Wert „xxx“ stammt aus der Formulardefinition in der Konfigurationsdatei. Dort wurde für das geheime Feld ein Anfangswert von „xxx“ definiert.

Um den Zusammenhang zwischen der Ansicht „formulaire.jsp“ und dem Bean „dynaFormulaire“, das sie im Speicher repräsentiert, vollständig zu verstehen, muss man bedenken, dass das Bean „dynaFormulaire“ sowohl zum Lesen als auch zum Schreiben verwendet wird:

Die Anfrage erfolgt, wenn der Benutzer auf die Schaltfläche [Submit] im Formular klickt. Der Browser „sendet“ dann das HTML-Formular an die Aktion /confirmation. Wir haben bereits erläutert, was dann geschieht, insbesondere dass die dynaFormulaire-Felder die Werte der gleichnamigen Felder im HTML-Formular erhalten.

Was geschieht, wenn der Controller als Antwort auf eine Anfrage die Anzeige der Seite formulaire.jsp anfordert? Schauen wir uns die Tags nacheinander genauer an:

Tag
<body background="<html:rewrite page="/images/standard.jpg"/>">
function
erzeugt den HTML-Code
<body background="/formulaire2/images/standard.jpg">
Tag
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
</html:form>
Funktion
erzeugt den HTML-Code
<form name="dynaFormulaire" method="post" action="/formulaire2/confirmation.do">
Tag
<html:radio name="dynaFormulaire" property="opt" value="yes">Ja</html:radio>
<html:radio name="dynaFormulaire" property="opt" value="no">Nein</html:radio>
function
Wenn das Feld „opt“ von dynaFormulaire den Wert „yes“ hat, generiere den HTML-Code
<input type="radio" name="opt" value="yes" checked="checked">Ja
<input type="radio" name="opt" value="no">Nein
Tag
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox>
<html:checkbox name="dynaForm" property="chk3">3</html:checkbox>
function
Wenn die Felder chk1 und chk3 von dynaFormulaire auf „on“ und das Feld chk2 auf „off“ gesetzt sind, generiere den HTML-Code
<input type="checkbox" name="chk1" value="on" checked="checked">1
<input type="checkbox" name="chk2" value="on">2
<input type="checkbox" name="chk3" value="on" checked="checked">3
Tag
<html:text name="dynaFormulaire" property="inputField" />
Funktion
Wenn das Eingabefeld auf „Dies ist ein Test“ gesetzt ist, generiere den HTML-Code
<input type="text" name="inputField" value="dies ist ein Test">
Tag
<html:password name="dynaFormulaire" property="password" />
Funktion
Wenn das Passwortfeld „azerty“ lautet, generiere den HTML-Code
<input type="password" name="password" value="azerty">
Tag
<html:password name="dynaFormulaire" property="mdp" />
Funktion
Wenn das Feld „mdp“ den Wert „azerty“ hat, generiere den HTML-Code
<input type="password" name="password" value="azerty">
Tag
<html:password name="dynaFormulaire" property="mdp" />
Funktion
Wenn das Feld „mdp“ den Wert „azerty“ hat, generiere den HTML-Code
<input type="password" name="password" value="azerty">
Tag
<html:select name="dynaFormulaire" property="combo">
<html:options name="dynaFormulaire" property="comboValues"/>
</html:select>
function
Wenn das Kombinationsfeld „combo2“ ist, generiert die Funktion den HTML-Code
<select name="combo">
    <option value="combo0">combo0</option>
    <option value="combo1">combo1</option>
    <option value="combo2" selected="selected">combo2</option>
    <option value="combo3">combo3</option>
    <option value="combo4">combo4</option>
</select>
Tag
<html:select name="dynaFormulaire" property="simpleList" size="3">
<html:options name="dynaFormulaire" property="simpleListValues"/>
</html:select>
function
Wenn das Feld „simpleList“ den Wert „simple1“ hat, wird der HTML-Code
<select name="simpleList" size="3">
    <option value="simple0">simple0</option>
    <option value="simple1" selected="selected">simple1</option>
    <option value="simple2">simple2</option>
...
</select>
Tag
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="multipleListValues"/>
</html:select>
function
Wenn das Feld listeMultiple das Array {"multiple0", "multiple2"} ist, wird der HTML-Code generiert
<select name="multipleList" multiple="multiple" size="5">
    <option value="multiple0" selected="selected">multiple0</option>
    <option value="multiple1">multiple1</option>
    <option value="multiple2" selected="selected">multiple2</option>
    <option value="multiple3">multiple3</option>
...
</select>
Tag
<html:hidden name="dynaFormulaire" property="secret"/>
Funktion
Wenn das geheime Feld den Wert „xxx“ hat, generiere den HTML-Code
<input type="hidden" name="secret" value="xxx">
Tag
<html:submit>Absenden</html:submit>
Funktion
erzeugt den HTML-Code
<input type="submit" value="Absenden">

Als Letztes soll der JavaScript-Code erläutert werden, der in die JSP-Seite eingebunden ist und mit den beiden [Clear]-Schaltflächen verknüpft ist, die die ausgewählten Elemente in den Listen „simpleList“ und „multipleList“ 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 HTML-Code:

<form name="dynaFormulaire" method="post" action="/formulaire2/confirmation.do">

Um den mit den [Clear]-Schaltflächen verbundenen JavaScript-Code zu verstehen, wollen wir uns ansehen, wie die verschiedenen Elemente eines Webdokuments innerhalb des JavaScript-Codes referenziert werden, der dieses Dokument verwendet:

Daten
Bedeutung
document
bezieht sich auf das gesamte Webdokument
document.forms
bezieht sich auf die Sammlung der im Dokument definierten Formulare
document.forms[i]
bezieht sich auf Formular Nummer i im Dokument
document.forms["formName"]
bezieht sich auf das Formular <form>, dessen Name-Attribut auf „formName“ gesetzt ist
document.formName
bezieht sich auf das <form>-Formular, dessen name-Attribut den Wert „formName“ hat
document.[form].elements
bezieht sich auf die Sammlung von Elementen, die zu dem durch den Ausdruck [form] bezeichneten Formular gehören. Diese Sammlung umfasst alle <input>-, <textarea>- und <select>-Tags im bezeichneten Formular.
document.[form].elements[i]
bezieht sich auf das Element Nummer i von [form]
document.[form].elements["componentName"]
bezieht sich auf das Element in [form], dessen Name-Attribut gleich componentName ist
document.[form]. componentName
bezieht sich auf das Element in [form], dessen Name-Attribut dem Wert „componentName“ entspricht
document.[form].[component].value
bezieht sich auf den Wert der Komponente [component] des Formulars [form], wenn deren HTML-Code ein value-Attribut haben kann (<input>, <textarea>)
document.[form].[select].selectedIndex
bezieht sich auf den Index der ausgewählten Option in einer Liste. Kann sowohl zum Lesen als auch zum Schreiben verwendet werden. Wenn diese Eigenschaft auf -1 gesetzt wird, werden alle Elemente in der Liste abgewählt.
document.[form].[select].options
bezieht sich auf das Array der Optionen, die mit einem <select>-Tag verknüpft sind
document.[form].[select].options[i]
bezieht sich auf die Option Nummer i des angegebenen <select>-Tags
document.[form].[select].options[i].selected
Ein boolescher Wert, der angibt, ob Option Nr. i des angegebenen [select]-Elements ausgewählt ist (true) oder nicht. Kann sowohl zum Lesen als auch zum Schreiben verwendet werden

Schauen wir uns noch einmal den JavaScript-Code für die beiden Schaltflächen an:

<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>                                
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>

Wenn auf die Schaltfläche geklickt wird, wird der mit dem Attribut „onclick“ verknüpfte Code ausgeführt. Hier handelt es sich um Inline-Code. Meistens schreiben wir onclick="function(...)", wobei function eine Funktion ist, die innerhalb eines <script language="javascript">...</script>-Tags definiert ist. Was bewirkt der obige Code? Schauen wir uns den Code für die erste Schaltfläche genauer an:

this
bezieht sich auf das Webdokument, in dem sich die Schaltfläche befindet
this.form
bezieht sich auf das Formular, in dem sich die Schaltfläche befindet
this.form.simpleList
bezieht sich auf die simpleList-Komponente des Formulars
this.form.simpleList.selectedIndex
bezieht sich auf den Index der ausgewählten Option in listeSimple. Wenn diese Eigenschaft auf -1 gesetzt wird, werden alle Optionen abgewählt.

6.4.2. Die Ansicht confirmation.jsp

Zur Erinnerung: Diese Ansicht wird nach der Aktion /confirmation angezeigt, d. h. 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>

Hier stellen wir zwei neue Tag-Bibliotheken vor: struts-bean und struts-logic. Die struts-bean-Bibliothek bietet Zugriff auf Objekte im Request-, Session- oder Anwendungskontext. Mit der struts-logic-Bibliothek können Sie Ausführungslogik mithilfe von Tags implementieren. Keine dieser Bibliotheken ist zwingend erforderlich. Wie wir gesehen haben, kann eine JSP-Seite:

  • Objekte aus der Anfrage (request.getAttribute(...)), der Sitzung (session.getAttribute(...)) oder dem Anwendungskontext abrufen
  • dynamische Elemente mithilfe von Variablen in den HTML-Code einbinden <%= variable %>
  • Java-Code enthalten <% Java-Code %>

Das Einfügen von Java-Code in JSP-Seiten stört diejenigen, die eine strikte Trennung zwischen Anwendungslogik (Java-Code) und Darstellung (Verwendung von Tags) bevorzugen. Aus diesem Grund wurden für sie Tag-Bibliotheken entwickelt.

Wir gehen genauso vor wie bei der Ansicht „formulaire.jsp“ und erläutern jedes der Tags im Code von „confirmation.jsp“, sofern diese nicht bereits in der Ansicht „formulaire.jsp“ behandelt wurden. Beachten Sie zunächst, 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 werden nun die Tags im Dokument formulaire.jsp erläutern:

Tag
<bean:write name="dynaFormulaire" scope="session" property="opt"/>
function
schreibt einen Wert in den aktuellen HTML-Stream. Das Bean:write-Tag unterstützt die folgenden Attribute:
name: Name des zu verwendenden Objekts
scope: Bereich (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. Die toString-Methode des Objekts wird verwendet.
Hier wird der Wert des Feldes „opt“ in dynaFormulaire geschrieben. Das Ergebnis ist entweder „yes“, wenn der Benutzer das Optionsfeld mit dem Attribut value="yes" ausgewählt hat, oder „no“, wenn er das Optionsfeld mit dem Attribut value="no" ausgewählt hat
Tag
<bean:write name="dynaFormulaire" scope="session" property="chk1"/>
Funktion
schreibt den Wert des Feldes chk1 in dynaFormulaire. Das Ergebnis ist entweder „on“, wenn der Benutzer das Kontrollkästchen aktiviert hat, oder andernfalls „off“. Dasselbe gilt für chk2 und chk3.
Tag
<bean:write name="dynaFormulaire" scope="session" property="inputField"/>
Funktion
schreibt den Wert des Feldes champSaisie in dynaFormulaire, d. h. den vom Benutzer in dieses Feld eingegebenen Text. Dasselbe gilt für mdp und boiteSaisie.
Tag
<bean:write name="dynaFormulaire" scope="session" property="combo"/>
Funktion
schreibt den Wert des Kombinationsfelds in dynaFormulaire. Dies ist das value-Attribut des vom Benutzer ausgewählten <option>-Elements.
Tag
<bean:write name="dynaFormulaire" scope="session" property="listeSimple"/>
Funktion
schreibt den Wert des Feldes „simpleList“ in dynaForm. Er enthält das „value“-Attribut des vom Benutzer ausgewählten <option>-Elements, sofern eines ausgewählt wurde. Andernfalls ist es eine leere Zeichenkette.
Tag
            <logic:iterate id="choice" indexId="index" name="dynaForm" property="multipleList">
          <tr>
          <td>multiple list[<bean:write name="index"/>]</td>
          <td><bean:write name="choice"/></td>
        </tr>
            </logic:iterate>
Funktion
Hier stellen wir Logik-Tags vor. Wir haben es mit einer Multiple-Choice-Liste zu tun. Der Wert des Feldes listeMultiple des dynaFormulaire-Objekts ist ein Array von Strings. In Java würden wir eine Schleife schreiben. Das logic:iterate-Tag ermöglicht es uns, dieselbe Schleife auszuführen, ohne Java-Code zu schreiben. In diesem Beispiel hat das logic:iterate-Tag die folgenden Attribute:
name="dynaFormulaire": Name des zu verwendenden Objekts
property="listeMultiple": Name der Eigenschaft in dem durch name angegebenen Objekt, die die Sammlung enthält, über die in der Schleife iteriert werden soll. Hier ist diese Sammlung das Array der in listeMultiple ausgewählten Werte. Dieses Array kann leer sein.
id="choix": Bezeichner, der bei jeder Iteration das aktuelle Element des Arrays angibt. 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 jeder Schleifeniteration den Index des aktuellen Array-Elements angibt. Bei der ersten Iteration hat index den Wert 0, bei der zweiten den Wert 1 und so weiter.
Der zwischen den Tags <logic:iterate ...> und </logic:iterate> enthaltene HTML-Code wird für jedes Element in der durch das (Name,Eigenschaft)-Paar bezeichneten Sammlung wiederholt. Der dynamische Teil dieses Codes lautet wie folgt:
          <td>multiple list[<bean:write name="index"/>]</td>
          <td><bean:write name="choice"/></td>
Basierend auf den vorherigen Ausführungen entspricht der generierte HTML-Code bei der Iteration Nummer i (i>=0) dem Folgenden:
          <td>multiple list[<%=i%>]</td>
          <td><%=multipleList[i]%></td>
Tag
    <html:link page="/affiche.do">
            Zurück zum Formular
        </html:link>
Funktion
erzeugt einen Link relativ zum Anwendungskontext, wodurch die Kenntnis des Kontexts entfällt. Der von diesem Tag generierte HTML-Code lautet wie folgt:
<a href="/formulaire2/affiche.do">Zurück zum Formular</a>

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 aus Ansicht Nr. 1, formulaire.jsp, enthält. Die Klasse InitFormulaireAction ist die Klasse, die die über die Schaltfläche [Submit] auf formulaire.jsp übermittelten Formularwerte verarbeitet.

6.5.1. Die Klasse DynaFormulaire

Um die Werte eines Formulars zu speichern, reicht ein Objekt vom Typ DynaActionForm aus, es sei denn, Sie müssen eine der Methoden „reset“ oder „validate“ dieser Klasse überschreiben. Hier muss die validate-Methode nicht überschrieben werden, da keine Datenvalidierung durchgeführt wird. Die reset-Methode muss jedoch überschrieben werden. Der Grund dafür ist, dass die Felder des DynaFormulaire-Objekts ihre Werte aus dem vom Web-Client übermittelten Formular erhalten. Einige 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 aktiviert wurde
  • eine Liste mit mehr als einer Option, bei der keine ausgewählt wurde

Bei Formularen, die diese Art von Komponente enthalten, muss die Reset-Methode

  • den Wert „off“ für das mit dem Kontrollkästchen verknüpfte Feld setzen
  • dem Feld, das mit einer Einfachauswahlliste verknüpft ist, die leere Zeichenkette zuweisen
  • dem Feld, das mit einer Mehrfachauswahlliste verknüpft ist, ein leeres String-Array 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ählte Elemente).

Der Code für die Klasse DynaFormulaire, eine Unterklasse von DynaActionForm, 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){
    // reset checkboxes - value off
    set("chk1","off");
    set("chk2","off");
    set("chk2","off");
    // reset listeSimple - empty string
    set("listeSimple","");
     // reset listeMultiple - empty table
    set("listeMultiple",new String[]{});
  }
}

6.5.2. Die Klasse InitFormAction

Die Klasse „InitFormAction“ 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 während der anfänglichen Erstellung des DynaForm-Objekts verwendet. Ihr Zweck ist es, Inhalte für die drei Kombinationslisten des Formulars bereitzustellen: simpleList, multipleList und dropdownList. Diese Inhalte werden in Form von drei Arrays bereitgestellt, die Eigenschaften des DynaForm-Objekts 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 Arrays valuesCombo, valuesSingleList** und valuesMultipleList durch InitFormAction initialisiert wurden, müssen sie nicht mehr initialisiert werden. Dies liegt daran, dass das dynaForm**-Objekt in der Sitzung abgelegt wird und somit seinen Wert über mehrere Anfrage-Antwort-Zyklen hinweg beibehält. Aus diesem Grund wird die Aktion /init nur einmal ausgeführt. Der Code für InitFormAction 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 {

     // prepares the form to be displayed

     // we put the information needed for the form in its bean
    DynaFormulaire formulaire = (DynaFormulaire) form;
    formulaire.set("valeursCombo", getValeurs(5, "combo"));
    formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
    formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
     // we give back
    return mapping.findForward("afficherFormulaire");
  } //execute

   // list of combo values
  private String[] getValeurs(int taille, String label) {
    String[] valeurs = new String[taille];
    for (int i = 0; i < taille; i++) {
      valeurs[i] = label + i;
    }
    return valeurs;
  }
}
  • Die Klasse erweitert die Action-Klasse. Dies ist zwingend erforderlich.
  • Der Struts-Controller verwendet ein Action-Objekt über dessen execute-Methode. Daher muss diese Methode neu definiert werden. Diese Methode erhält die folgenden Parameter:
    • ActionMapping mapping: ein Objekt, das die Anwendungskonfiguration in struts-config.xml repräsentiert
    • ActionForm form: das mit der Aktion verknüpfte Formular, sofern eines in der Konfiguration der Aktion definiert ist (das name-Attribut der Aktion).
    • HttpServletRequest request: die Client-Anfrage
    • HttpServletResponse: die Antwort an den Client
  • Die Klasse InitFormulaireAction muss das Formular dynaFormulaire initialisieren. Dieses wird als ActionForm-Formularparameter an die Methode execute übergeben. Zur Erinnerung: dynaFormulaire ist vom Typ DynaFormulaire, einer Klasse, die von der Klasse DynaActionForm abgeleitet ist, welche 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 set-Methode einem bestehenden Feld einen Wert zuweist. Sie kann nicht zum Erstellen neuer Felder verwendet werden. Aus diesem Grund ist es notwendig, die drei Felder valeursCombo, valeursListeSimple und valeursListeMultiple in der Definition des dynaFormulaire-Objekts in struts-config.xml zu definieren.
  • Die Methode „execute“ gibt abschließend den Schlüssel der anzuzeigenden Ansicht als Antwort an den Client an den Controller zurück. Hier handelt es sich um den 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:

  

Image

Image

Beachten Sie, dass die oben genannte Datei „ApplicationResources.properties“ von der Struts-Bean-Tag-Bibliothek benötigt wird. Wir wissen, dass diese Datei die Meldungen der Anwendung enthält. Diese sind für die Struts-Bean-Bibliothek zugänglich. In unserem Fall definiert die Anwendung keine Meldungen. Daher existiert die Datei „ApplicationResources.properties“, ist jedoch leer.

6.7. Fazit

In dieser Lektion haben wir detailliert beschrieben, wie die verschiedenen Komponenten eines HTML-Formulars verwaltet werden. Wir können nun komplexe Formulare in unseren Struts-Anwendungen verwenden.