Skip to content

4. Verwendung dynamischer Formulare

4.1. Deklaration des dynamischen Formulars

Wir haben gesehen, dass Struts Objekte vom Typ ActionForm verwendet, um die Werte der Formulare vom Typ HTML zu speichern, die von den verschiedenen Servlets der Anwendung verarbeitet werden. Für jedes Formular unserer Anwendung müssen wir eine von ActionForm abgeleitete Klasse erstellen. Dies kann schnell recht aufwendig werden, da wir für jedes Feld xx zwei Methoden – setXx und getXx – schreiben müssen. Struts bietet uns die Möglichkeit, Formulare zu verwenden,

  • zu verwenden, deren Struktur in der Datei struts-config.xml im Abschnitt <form-beans> deklariert ist
  • deklariert ist und die von der Struts-Umgebung entsprechend der deklarierten Struktur dynamisch erstellt werden

Somit könnte die Klasse, die zur Speicherung der Werte „name“ und „age“ der Anwendung „strutspersonne“ verwendet wird, wie folgt definiert werden:

    <form-beans>
        <form-bean name="frmPersonne" type="org.apache.struts.actions.DynaActionForm">
            <form-property name="nom" type="java.lang.String" initial=""/>
            <form-property name="age" type="java.lang.String" initial=""/>
        </form-bean>            
    </form-beans>

Für jedes Feld des Formulars wird ein <form-property>-Tag mit zwei Attributen definiert:

  • name: der Name des Feldes
  • type: sein Java-Typ

Da die von einem Web-Client übermittelten Werte eines Formulars Zeichenfolgen sind, sind die am häufigsten verwendeten Typen java.lang.String für Felder mit einem einzigen Wert und java.lang.String[] für Felder mit mehreren Werten (Kontrollkästchen mit demselben Namen, Listen mit Mehrfachauswahl usw.). Sowohl die Klasse DynactionForm als auch die Klasse ActionForm verfügen über eine validate-Methode, die nichts ausführt. Damit sie die Gültigkeit der Formularparameter überprüft, muss man die Klasse ableiten und die validate-Methode selbst implementieren. Die Deklaration des Formulars lautet daher wie folgt:

    <form-beans>
        <form-bean name="frmPersonne" type="istia.st.struts.personne.PersonneDynaForm">
            <form-property name="nom" type="java.lang.String" initial=""/>
            <form-property name="age" type="java.lang.String" initial=""/>
        </form-bean>            
    </form-beans>

Die Klasse istia.st.struts.personne.PersonneDynaForm muss von uns erstellt werden.

4.2. Erstellung der Klasse DynaActionForm, die mit dem dynamischen Formular verknüpft ist

Oben haben wir die Klasse istia.st.struts.personne.PersonneDynaForm dem Formular (Name, Alter) zugeordnet. Nun schreiben wir diese Klasse:

package istia.st.struts.personne;

import javax.servlet.http.*;
import org.apache.struts.action.*;

public class PersonneDynaForm extends DynaActionForm {
   // Validierung
  public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    // Fehlerbehandlung
    ActionErrors erreurs = new ActionErrors();
     // Der Name darf nicht leer sein
    String nom = (String)this.get("nom");
    if (nom == null || nom.trim().equals("")) {
      erreurs.add("nomvide", new ActionError("personne.formulaire.nom.vide"));
    }
     // Das Alter darf nicht leer sein
    String age = (String)this.get("age");
    if (age == null || age.trim().equals("")) {
      erreurs.add("agevide", new ActionError("personne.formulaire.age.vide"));
    }
    else {
      // Das Alter muss eine positive ganze Zahl sein
      if (!age.matches("^\\s*\\d+\\s*$")) {
        erreurs.add("ageincorrect", new ActionError("personne.formulaire.age.incorrect", age));
        // Die Fehlerliste wird ausgegeben
      }
    } //if
     // wird die Fehlerliste ausgegeben
    return erreurs;
  }
}//Klasse

Folgende Punkte sind zu beachten:

  • Die Klasse ist von DynaActionForm abgeleitet.
  • Die Methode „validate“ der Klasse DynaActionForm wurde neu geschrieben. Bei ihrer Ausführung durch den Struts-Controller wurde das Objekt PersonneDynaForm instanziiert. Es enthält ein Dictionary, dessen Schlüssel die Formularfelder „name“ und „age“ sind und dessen Werte die Werte dieser Felder sind. Um innerhalb der Methoden von DynaActionForm auf ein Feld zuzugreifen, wird die Methode `Object get(String nomDuChamp)` verwendet. Wenn man einem Feld einen Wert zuweisen möchte, kann man die Methode `void set(String nomDuChamp, Object Wert)` verwenden. Eine vollständige Definition findet sich in der Klassendefinition von DynaActionForm.
  • Nachdem die Werte der Felder „nom“ und „age“ des Formulars abgerufen wurden, unterscheidet sich die Methode „validate“ nicht von derjenigen, die geschrieben wurde, als das Formular einem Objekt vom Typ ActionForm zugeordnet war.

4.3. Die neue Klasse FormulaireAction

Die Konfigurationsdatei definiert die folgende Aktion /main:

...
    <form-beans>
        <form-bean name="frmPersonne" type="istia.st.struts.personne.PersonneDynaForm">
            <form-property name="nom" type="java.lang.String" initial=""/>
            <form-property name="age" type="java.lang.String" initial=""/>
        </form-bean>            
    </form-beans>
....
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          type="istia.st.struts.personne.FormulaireAction"
      >
            <forward name="reponse" path="/reponse.do"/>
        </action>

Diese Definition entspricht der in der Anwendung „strutspersonne“. Die Aktion /main wird von einem Objekt vom Typ FormulaireAction ausgeführt. Dieses Objekt erhielt die Werte des Formulars frmPersonne in einem Objekt vom Typ FormulaireBean. Nun erhält es diese in einem Objekt vom Typ PersonneDynaForm. Daher muss die Klasse umgeschrieben werden:

package istia.st.struts.personne;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import javax.servlet.ServletException;
import istia.st.struts.personne.PersonneDynaForm;

public class FormulaireAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form,
           HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException {

     // Das Formular ist gültig, sonst wären wir nicht bis hierher gekommen
    PersonneDynaForm formulaire=(PersonneDynaForm)form;
    request.setAttribute("nom",formulaire.get("nom"));
    request.setAttribute("age",formulaire.get("age"));
    return mapping.findForward("reponse");
  }//ausführen
}

Folgende Punkte sind zu beachten:

  • Wir müssen die Klasse PersonneDynaForm importieren, die die Formulardaten enthält, um Zugriff auf ihre Definition zu erhalten.
  • Die Methode „execute“ ruft die Werte der Formularparameter mit der Methode „[DynaActionForm].get“ ab.

Im Vergleich zur Klasse FormulaireAction der Anwendung „strutspersonne“ hat sich lediglich die Art und Weise geändert, wie auf die Formularwerte zugegriffen wird.

4.4. Bereitstellung und Test der Anwendung „strutspersonne1“

4.4.1. Erstellung des Kontexts

Wir haben diese neue Anwendung „strutspersonne1“ genannt. Wir erstellen eine neue Definition in der Tomcat-Datei <tomcat>\conf\serveur.xml von Tomcat 4.x:

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

Anschließend muss Tomcat neu gestartet werden. Die Gültigkeit des Kontexts lässt sich überprüfen, indem man die Seite URL aufruft:

http://localhost:8080/strutspersonne1/

Image

4.4.2. Die Ansichten

Wir kopieren den Ordner „vues“ der Anwendung „strutspersonne“ in den Ordner der Anwendung „strutspersonne1“. Die Ansichten haben sich nämlich nicht geändert.

Image

4.4.3. Kompilierung der Klassen

Wir müssen zwei Klassen erstellen: PersonneDynaForm und FormulaireAction, wobei die zweite die erste verwendet. Wir können sie mithilfe eines JBuilder-Projekts erstellen und kompilieren:

Image

4.4.4. Der Ordner WEB-INF

Wir kopieren den Ordner WEB-INF aus der Anwendung „strutspersonne“ in den Ordner der Anwendung „strutspersonne1“. Dabei ändern sich einige Dateien:

Image

Die Konfigurationsdatei struts-config.xml sieht nun 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="frmPersonne" type="istia.st.struts.personne.PersonneDynaForm">
            <form-property name="nom" type="java.lang.String" initial=""/>
            <form-property name="age" type="java.lang.String" initial=""/>
        </form-bean>            
    </form-beans>

    <action-mappings>
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          type="istia.st.struts.personne.FormulaireAction"
      >
            <forward name="reponse" path="/reponse.do"/>
        </action>
      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/reponse"
          parameter="/vues/reponse.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
    </action-mappings>

    <message-resources parameter="ressources.personneressources"/>    
</struts-config>

Diese Datei entspricht derjenigen der Anwendung „strutspersonne“, mit Ausnahme der dynamischen Definition des Formulars (eingerahmter Teil).

Im Ordner WEB-INF/classes werden die von JBuilder kompilierten Klassen abgelegt:

Image

Im Ordner „WEB-INF\classes\ressources“ wird die Meldungsdatei abgelegt. Sie hat sich nicht geändert.

personne.formulaire.nom.vide=<li>Vous devez indiquer un nom</li>
personne.formulaire.age.vide=<li>Vous devez indiquer un age</li>
personne.formulaire.age.incorrect=<li>L'âge [{0}] est incorrect</li>
errors.header=<ul>
errors.footer=</ul>

Image

4.5. Tests

Wir sind bereit für die Tests. Nachfolgend finden Sie einige Screenshots, die der Leser nachmachen soll.

Gefordert wird die Eingabe von URLhttp://localhost:8080/strutspersonne1/formulaire.do:

Image

Man klickt auf die Schaltfläche [Envoyer], ohne die Felder auszufüllen:

Image

Wir versuchen es erneut, wobei im Feld „age“ ein Fehler auftritt:

Image

Man erhält folgende Antwort:

Image

Wir versuchen es erneut und geben diesmal korrekte Werte ein:

Image

Man erhält folgende Antwort:

Image

4.6. Fazit

Die Verwendung dynamischer Formulare erleichtert das Schreiben von Klassen vom Typ ActionForm, die für die Speicherung der Formularwerte zuständig sind. Man kann die Verwaltung von Formularen noch weiter vereinfachen. In der Anwendung „strutspersonne1“ haben wir eine Klasse vom Typ PersonneDynaForm erstellt, um die Gültigkeit der Werte (Name, Alter) des Formulars zu überprüfen. In der Praxis kommen bestimmte Prüfungen häufig vor: Feld darf nicht leer sein, Feld muss einem bestimmten regulären Ausdruck entsprechen, Ganzzahlfeld, Datumsfeld usw. Diese Art von Standardüberprüfung kann dann in der Konfigurationsdatei struts-config.html festgelegt werden. Wenn alle durchzuführenden Überprüfungen „Standard“ sind, muss für das Formular keine Klasse mehr geschrieben werden. Das sehen wir uns nun an.