Skip to content

3. Verwerking van het formulier door de controller

We richten ons nu op de verwerking van de formulierwaarden door de controller wanneer de gebruiker op de knop [Envoyer] in het formulier klikt.

3.1. Het bestand struts-config.xml

Het nieuwe configuratiebestand struts-config.xml van de Struts-controller ziet er als volgt uit:

<?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.FormulaireBean"
        />
    </form-beans>

    <action-mappings>
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />
      <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>

We hebben de wijzigingen gemarkeerd:

  • er verschijnt een <form-beans>-sectie. Deze dient om de klassen te definiëren die bij elk formulier van de applicatie horen. Er moeten evenveel <form-bean>-tags zijn als er verschillende formulieren in de applicatie zijn. Hier hebben we slechts één formulier, dus slechts één <form-bean>-sectie. Voor elk formulier moeten we het volgende definiëren:
    • de naam (attribuut name)
    • de naam van de klasse die is afgeleid van ActionForm en die verantwoordelijk is voor het opslaan van de formulierwaarden (attribuut type)

Deze twee attributen kunnen niet willekeurig worden gekozen. Ze moeten identiek zijn aan die welke worden gebruikt in de <html:form>-tag van de HTML-code van het formulier. Laten we deze nog eens bekijken voor het formulier (naam, leeftijd):

      <html:form action="/main" name="frmPersonne" type="istia.st.struts.personne.FormulaireBean">

Het formulier moet op dezelfde manier worden opgegeven in het bestand struts-config.html. Dat gebeurt hier als volgt:

        <form-bean 
            name="frmPersonne" 
            type="istia.st.struts.personne.FormulaireBean"
        />
  • De configuratie van de actie /main is gewijzigd. Deze actie is verantwoordelijk voor het verwerken van de waarden uit het formulier. Daarom moeten we de benodigde informatie hierin opgeven:
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

De servlet /main verwerkt een formulier waaraan een naam moet worden toegekend. Dit gebeurt via het attribuut name. Deze naam moet verwijzen naar het attribuut name van een van de <form-bean>-secties, in dit geval frmPersonne.

Het attribuut scope="session" geeft aan dat de waarden van het formulier in de sessie moeten worden opgeslagen. Dit is niet altijd nodig. In dit geval is het dat wel. In de weergaven /reponse.do en /erreurs.do vinden we namelijk links die terugleiden naar het formulier. In beide gevallen willen we het formulier weergeven met de waarden die de gebruiker tijdens een eerdere client-server-uitwisseling heeft ingevoerd. Vandaar dat het formulier in de sessie moet worden opgeslagen.

Het attribuut validate geeft aan of de methode validate van het object **frmPersonne al dan niet moet worden aangeroepen. Deze methode dient om de geldigheid van de formuliergegevens te controleren. Hier geven we aan dat de gegevens moeten worden gecontroleerd, wat inhoudt dat we een methode validate moeten schrijven in de klasse FormulaireBean. De validate-methode van het formulier wordt door de Struts-controller aangeroepen voordat de servlet /main wordt aangeroepen. Deze methode retourneert een object van het type ActionErrors, dat overeenkomt met een foutenlijst. Als deze lijst bestaat en niet leeg is, stopt de Struts-controller hier en stuurt als antwoord de weergave die is aangegeven door het attribuut input. De weergave ontvangt in de verzoekde gegevens de lijst ActionErrors, die zij kan weergeven met de tag <html:errors>. Hierboven stellen we dat de servlet /main in geval van fouten de weergave /erreurs.do moet verzenden. Ter herinnering: deze weergave is gekoppeld aan de volgende URL /vues/erreurs.reponse.jsp**:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
        <html:errors/>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>      
    </body>
</html>

De weergave maakt goed gebruik van de tag <html:errors>, waarmee de lijst met fouten kan worden weergegeven. In deze foutenlijst staan geen foutmeldingen, maar identificatiecodes van meldingen die aanwezig zijn in het bestand waarnaar de tag <message-resources> verwijst (let op: resources met één s):

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

De onderstaande tag geeft aan dat het bestand met de door de applicatie gebruikte berichten zich bevindt in het bestand WEB-INF/classes/ressources/personneressources.properties:

Image

Wat staat er in dit bestand? Het is een eigenschappenbestand dat overeenkomt met de Java-klasse **Properties**, dat wil zeggen een reeks regels in de vorm sleutel=waarde:

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

Dit berichtenbestand heeft ten minste twee functies:

  • het maakt het mogelijk om de berichten van de applicatie te wijzigen zonder deze opnieuw te hoeven compileren
  • het maakt de internationalisering van Struts-applicaties mogelijk. Er kunnen namelijk meerdere bronbestanden worden aangemaakt, één per taal. Struts gebruikt automatisch het juiste berichtenbestand, mits bepaalde normen voor de naamgeving van deze bestanden worden nageleefd.
  • Als de validate-methode van het formulier een lege foutenlijst retourneert, roept de Struts-controller de execute-methode van de servlet ForwardAction aan. Het is belangrijk om hier te begrijpen dat wanneer de `execute`-methode van de servlet wordt uitgevoerd, dit betekent dat de gegevens van het formulier als geldig zijn beschouwd (mits ze natuurlijk zijn gecontroleerd via `validate="true"`). Het is in de `execute`-methode van de servlet die aan de actie is gekoppeld dat de ontwikkelaar het formulier daadwerkelijk verwerkt. Daar bevindt zich de kern van de verwerking (applicatielogica, gebruik van businessklassen en klassen voor gegevenstoegang). Uiteindelijk retourneert de methode een resultaat van het type ActionForward, dat de constructor aangeeft welke weergave als antwoord naar de client moet worden verzonden. Hier hebben we de vooraf gedefinieerde actie ForwardAction van Struts gebruikt. De methode `execute` daarvan geeft simpelweg een ActionForward terug die verwijst naar de URL die wordt aangegeven door het attribuut `parameter`:
      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

Als de gegevens in het formulier dus geldig zijn, zal de actie /main de weergave /vues/main.html retourneren, die we al eerder hebben gebruikt.

3.2. De nieuwe klasse FormulaireBean

We hebben al een eerste versie gemaakt van de klasse FormulaireBean, die bedoeld is om de gegevens (naam, leeftijd) van het formulier formulaire.personne.jsp op te slaan. Deze versie controleerde de geldigheid van de gegevens niet. Nu moeten we dat wel doen, aangezien we in het bestand struts-config.xml hebben aangegeven dat de gegevens van het formulier moeten worden gecontroleerd (validate="true") voordat ze worden doorgegeven aan de servlet ForwardAction. De code van de klasse ziet er nu als volgt uit:

package istia.st.struts.personne;

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

public class FormulaireBean
  extends ActionForm {
   // naam
  private String nom = null;
  public String getNom() {
    return nom;
  }

  public void setNom(String nom) {
    this.nom = nom;
  }

   // leeftijd
  private String age = null;
  public String getAge() {
    return age;
  }

  public void setAge(String age) {
    this.age = age;
  }

   // validatie
  public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    // foutbeheer
    ActionErrors erreurs = new ActionErrors();
     // de achternaam mag niet leeg zijn
    if (nom == null || nom.trim().equals("")) {
      erreurs.add("nomvide", new ActionError("personne.formulaire.nom.vide"));
       // de leeftijd moet een positief geheel getal zijn
    }
    if (age == null || age.trim().equals("")) {
      erreurs.add("agevide", new ActionError("personne.formulaire.age.vide"));
    }
    else {
      // de leeftijd moet een positief geheel getal zijn
      if (!age.matches("^\\s*\\d+\\s*$")) {
        erreurs.add("ageincorrect", new ActionError("personne.formulaire.age.incorrect", age));
        // de lijst met fouten wordt weergegeven
      }
    } //if
     // de lijst met fouten wordt weergegeven
    return erreurs;
  }
}

Het nieuwe zit hem in de implementatie van de methode validate. Deze wordt aangeroepen door de Struts-controller nadat deze de waarden van de gelijknamige velden uit het formulier heeft toegewezen aan de attributen nom en age van de klasse. De methode moet de geldigheid van de attributen nom en age controleren. De bovenstaande code is vrij eenvoudig te begrijpen:

  • er wordt een lege foutenlijst (ActionErrors fouten) aangemaakt
  • het veld ‘naam’ wordt gecontroleerd. Als het leeg is, wordt er een fout toegevoegd aan de foutenlijst met behulp van de methode ActionErrors.add("sleutel", ActionError).
  • Hetzelfde gebeurt als het veld ‘leeftijd’ geen geheel getal is.
  • De methode validate geeft de foutenlijst (ActionErrors fouten) terug aan de Struts-controller. Als fouten gelijk is aan null of als erreurs.size() gelijk is aan 0, gaat de controller ervan uit dat er geen fouten zijn opgetreden. Vervolgens laat hij de methode `execute` van de Action-klasse uitvoeren die aan de actie is gekoppeld (type="org.apache.struts.actions.ForwardAction"). Anders stuurt hij de weergave terug die is gekoppeld aan het geval van fouten in het formulier (input="/erreurs.do").

We voegen een fout toe aan de lijst ActionErrors fouten via ActionErrors.add("cléErreur", new ActionError("cléMessage"[,param0, param1, param2, param3])). De eerste parameter "cléErreur" dient om een element ActionError in de lijst ActionErrors op unieke wijze aan te duiden, een beetje zoals in een woordenboek. Deze kan willekeurig zijn. ActionError is een object dat aan een foutmelding wordt gekoppeld met behulp van de constructor ActionError(String cléMessage[,String param0, String param1, String param2, String param3]), waarbij cléMessage de identificatiecode is van de aan de fout gekoppelde melding en er maximaal 4 optionele parameters kunnen worden opgegeven. De identificatiecode cléMessage is niet zomaar een willekeurige code. Het is een van de identificatiecodes die te vinden zijn in het bestand dat wordt aangeduid door de tag <message-resources> in het bestand struts-config.xml:

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

Ter herinnering: dit bestand (in werkelijkheid WEB-INF/classes/ressources/personneressources.properties) bevat de volgende sleutels:

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

We kunnen controleren of de berichtcodes die worden gebruikt door de methode validate van de klasse FormulaireBean inderdaad in het bovenstaande bestand voorkomen. Voor elk foutbericht is de tag HTML <li> gebruikt, zodat de tag <html:errors> deze als een lijst HTML weergeeft. We hebben gezien dat het object ActionError niet alleen met een berichtcode kan worden aangemaakt, maar ook met aanvullende parameters:

public ActionError(String cléMessage[,String param0, String param1, String param2, String param3])

Als een ActionError is geconstrueerd met extra parameters (maximaal vier), zijn deze in de tekst van het bericht toegankelijk via de notatie {0} tot en met {3}. Zo genereert de methode validate van FormulaireBean een ActionError met de sleutel personne.formulaire.age.incorrect en de extra parameter param0:

      erreurs.add("age", new ActionError("personne.formulaire.age.incorrect",age));

Het bericht dat in het .properties-bestand van de berichten aan de sleutel personne.formulaire.age.incorrect is gekoppeld, luidt

personne.formulaire.age.incorrect=<li>L'âge [{0}] est incorrect</li>

De {0} wordt vervangen door de leeftijd. Ten slotte worden de berichten met de sleutels errors.header en errors.footer respectievelijk vóór en na de foutenlijst geschreven. Hier dienen deze twee sleutels om de tags HTML <ul> en </ul> op te nemen, die de tags <li> moeten omringen.

3.3. De validatietests van het formulier

We zijn klaar voor de validatietests van het formulier. Hieronder geven we nogmaals aan waar de verschillende onderdelen van de applicatie moeten worden geplaatst:

les vues
les fichiers de configuration
le fichier des messages
les classes

3.3.1. Test 1

Laten we Tomcat opnieuw opstarten zodat het de nieuwe configuratiebestanden leest, en vervolgens de URL-http://localhost:8080/strutspersonne/formulaire.do opvragen:

Image

Toelichting:

  • in struts-config.html is de volgende sectie misbruikt:
      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />

Als we de code HTML van de ontvangen pagina bekijken, zien we dat de tag <form> van de pagina als volgt is:

      <form name="frmPersonne" method="post" action="/strutspersonne/main.do">

De knop [Envoyer], die van het type ‘submit’ is, zal de gegevens van het formulier dus verzenden naar URL /strutspersonne/main.do.

3.3.2. Test 2

Laten we de knop [Envoyer] gebruiken en de invoervelden leeg laten. We krijgen dan de volgende reactie:

Image

Uitleg:

  • zoals hierboven aangegeven, zijn de gegevens van het formulier verzonden naar de URL /strutspersonne/main.do. De volgende secties van het bestand struts-config.xml zijn vervolgens gebruikt:
        <form-bean 
            name="frmPersonne" 
            type="istia.st.struts.personne.FormulaireBean"
            scope="session"
        />
....
      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

De actie /main is geactiveerd. Deze maakt gebruik van het formulier frmPersonne (name="frmPersonne"). De Struts-controller heeft daarom, indien nodig, een object van de klasse FormulaireBean geïnstantieerd (type="istia.st.struts.personne.FormulaireBean" in de form-bean-tag). Hij heeft de attributen ‘naam’ en ‘leeftijd’ van dit object gevuld met de velden met dezelfde naam uit het formulier HTML:

          <table>
            <tr>
              <td>Nom</td>
            <td><html:text property="nom" size="20"/></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><html:text property="age" size="3"/></td>
          </tr>
            <tr>
        </table>

Toen dit was gebeurd, riep de Struts-controller de methode validate van het object **FormulaireBean aan, omdat het attribuut validate van de actie **/main in het configuratiebestand op true is ingesteld:

      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

De validate-methode van de klasse FormulaireBean is als volgt:

  // validatie
  public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    // foutafhandeling
    ActionErrors erreurs = new ActionErrors();
     // de naam mag niet leeg zijn
    if (nom == null || nom.trim().equals("")) {
      erreurs.add("nomvide", new ActionError("personne.formulaire.nom.vide"));
       // de leeftijd moet een positief geheel getal zijn
    }
    if (age == null || age.trim().equals("")) {
      erreurs.add("agevide", new ActionError("personne.formulaire.age.vide"));
    }
    else {
      // de leeftijd moet een positief geheel getal zijn
      if (!age.matches("^\\s*\\d+\\s*$")) {
        erreurs.add("ageincorrect", new ActionError("personne.formulaire.age.incorrect", age));
        // de lijst met fouten wordt weergegeven
      }
    } //if
     // wordt de lijst met fouten weergegeven
    return erreurs;
  }

Aangezien de velden [nom] en [age] leeg waren, genereerde de hierboven beschreven validatiemethode een lijst met twee fouten, die vervolgens werd teruggestuurd naar de Struts-controller. Omdat er fouten waren, stuurde de controller vervolgens de weergave die bij het input-attribuut hoorde terug naar de client. Om te achterhalen om welke weergave het ging, gebruikte hij het volgende gedeelte uit zijn configuratiebestand:

      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />

Uiteindelijk heeft hij dus de weergave /vues/erreurs.personne.jsp verzonden. Deze heeft de volgende code:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
        <html:errors/>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

De tag <html:errors> geeft eenvoudigweg de lijst weer met berichten die de Struts-controller naar deze tag heeft gestuurd. Hierbij wordt gebruikgemaakt van het berichtenbestand dat is opgegeven door de tag <message-resources>:

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

Daarin staan de volgende sleutels en berichten:

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>
  • het bericht dat hoort bij de sleutel errors.header wordt geschreven
  • de berichten die gekoppeld zijn aan de verschillende sleutels in de ontvangen lijst ActionErrors worden geschreven
  • het bericht dat bij de sleutel errors.footer hoort, wordt geschreven

3.3.3. Test 3

Laten we de link [Retour au formulaire] op de foutpagina gebruiken. We krijgen de volgende pagina te zien:

Image

Toelichting:

  • de link [Retour au formulaire] heeft de volgende code: HTML:
    <a href="/strutspersonne/formulaire.do">Retour au formulaire</a>

De Struts-controller heeft het volgende gedeelte uit zijn configuratiebestand gebruikt:

      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />

Het heeft dus de weergave /vues/formulaire.personne.jsp teruggestuurd.

3.3.4. Test 4

We vullen het volgende formulier in en klikken vervolgens op de knop [Envoyer]:

Image

We krijgen het volgende antwoord:

Image

Uitleg: deze is hetzelfde als bij test nr. 2.

3.3.5. Test 5

We gebruiken de bovenstaande link [Retour au formulaire]. We krijgen de volgende pagina te zien:

Image

We zien dat het formulier er nog precies zo uitziet als toen we het hebben verzonden.

Toelichting: deze is dezelfde als bij test nr. 3, met een aanvullende opmerking:

  • het weergegeven formulier HTML bevat de volgende tags:
          <table>
            <tr>
              <td>Nom</td>
            <td><html:text property="nom" size="20"/></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><html:text property="age" size="3"/></td>
          </tr>
            <tr>
        </table>

De <html:text>-tags hebben twee functies:

  • bij het verzenden van de formulierwaarden van de client naar de server worden de waarden van de invoervelden van het formulier toegewezen aan de velden met dezelfde naam in het object FormulaireBean
  • wanneer de server de code HTML van het weer te geven formulier naar de client verzendt, worden de value-attributen van de invoervelden die aan de <html:text>-tags zijn gekoppeld, geïnitialiseerd met de waarden van de velden met dezelfde naam in het object FormulaireBean.

We hebben hier te maken met twee verschillende client-server-uitwisselingen:

  • in de eerste heeft de gebruiker het formulier ingevuld en naar de server verzonden
  • in de tweede heeft de gebruiker de link [Retour au formulaire] gebruikt om terug te keren naar het formulier.

De enige manier waarop het formulier in de tweede interactie opnieuw kan worden weergegeven met de oorspronkelijke waarden, is door deze in de sessie van de klant op te slaan. Dit is wat is gevraagd in het gedeelte waarin de actie /main wordt geconfigureerd:

      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

Als we scope="request" hadden ingesteld, zouden de gegevens van het formulier niet in de sessie zijn opgeslagen en zouden we de waarden ervan bij de tweede uitwisseling niet hebben teruggevonden.

3.3.6. Test 6

Laten we teruggaan naar het formulier om deze keer geldige gegevens in te voeren:

Image

Laten we het formulier verzenden. We krijgen het volgende resultaat:

Image

Uitleg:

  • aangezien de knop [Envoyer] de waarden van het formulier naar de pagina URL /strutspersonne/main.do verstuurt, gelden dezelfde uitleg als in test nr. 2 tot aan de terugkeer naar de Struts-controller van het resultaat ActionErrors van de methode validate van FormulaireBean. Maar hier is deze lijst leeg. De controller gebruikt dan een nieuw deel van de configuratie van de actie /main:
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

De Struts-controller maakt, indien nodig, een object aan van het type dat wordt aangegeven door het attribuut type. De methode execute van deze klasse wordt uitgevoerd en moet een object van het type **ActionForward retourneren, dat aangeeft welke weergave de controller als antwoord naar de client moet sturen. Hier verwijst het attribuut type naar de vooraf gedefinieerde klasse ForwardAction. De methode execute van deze klasse doet niets en retourneert alleen een object van het type **ActionForward dat verwijst naar de weergave die is gedefinieerd door het attribuut **parameter**, in dit geval de weergave **/vues/main.html**. Dit is inderdaad de weergave die de controller heeft teruggestuurd.

3.3.7. Test 7

We vragen de weergave /formulaire.do opnieuw op:

Image

We zien het formulier terug zoals we het hebben gevalideerd. De uitleg hiervoor is al gegeven. Door de configuratie (scope="session") hebben we aangegeven dat het formulier in de sessie moet blijven. De waarden ervan worden dus behouden tijdens de communicatie tussen client en server.

We zijn bijna klaar. We moeten nu nog een echte actie maken voor het geval de gegevens van het formulier geldig zijn. Tot nu toe hebben we de vooraf gedefinieerde actie ForwardAction gebruikt om onze demonstratie te vereenvoudigen.

3.4. Nieuwe configuratie van de actie /main

We wijzigen het huidige configuratiebestand struts-config.xml niet, behalve om de sectie /main als volgt aan te passen:

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

Het type-attribuut verwijst nu naar een andere klasse, genaamd FormulaireAction, die we nog moeten aanmaken. De methode execute van deze klasse wordt uitgevoerd als de gegevens van het formulier frmPersonne geldig zijn. We hebben aangegeven dat de methode execute deed wat ze moest doen en een object van het type **ActionForward retourneerde, dat de weergave aangeeft die de controller naar de client moest terugsturen. Er zijn vaak meerdere weergaven mogelijk, afhankelijk van het resultaat van de verwerking van het formulier. De lijst met de verschillende mogelijke weergaven wordt vermeld in de <forward>-tags die zijn opgenomen in de <action**>-tag. De syntaxis van een dergelijke tag is als volgt:

            <forward name="clé" path="/vue" />
clé
willekeurige naam die een weergave uniek identificeert
vue
URL van de weergave die aan de sleutel is gekoppeld

3.5. De klasse FormulaireAction

Het schrijven van de klasse FormulaireAction komt in wezen neer op het schrijven van de methode execute:

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;

public class FormulaireAction extends Action {

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

     // het formulier is geldig, anders zouden we hier niet zijn gekomen
    FormulaireBean formulaire=(FormulaireBean)form;
    request.setAttribute("nom",formulaire.getNom());
    request.setAttribute("age",formulaire.getAge());
    return mapping.findForward("reponse");
  }//uitvoeren
}

De methode **execute** ontvangt vier parameters:

  1. ActionMapping-mapping: een "afbeelding"-object van de configuratie van de actie die momenteel wordt uitgevoerd, dus in dit geval een afbeelding van de volgende configuratie:
      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          type="istia.st.struts.personne.FormulaireAction"
      >
            <forward name="reponse" path="/reponse.do"/>
        </action>

Zo heeft de actie toegang tot de sleutels die aan de weergaven zijn gekoppeld en die aan het einde van de actie naar de client kunnen worden teruggestuurd. De methode die wordt uitgevoerd, moet een van deze sleutels terugsturen.

  1. ActionForm form: het bean-object waarin de waarden van het formulier zijn opgeslagen dat door de huidige actie wordt gebruikt. Hier is dat het object frmPersonne van het type FormulaireBean. Zo heeft de actie toegang tot de waarden van het formulier.
  2. HttpServletRequest request: het verzoek van de client dat door verschillende servlets kan zijn aangevuld. De actie heeft dus toegang tot alle parameters van het oorspronkelijke verzoek (request.getParameter) en tot alle attributen die aan dit oorspronkelijke verzoek zijn toegevoegd (request.getAttribute). In ons voorbeeld vult de methode `execute` het verzoek aan door de naam en de leeftijd toe te voegen. Dit is hier volstrekt overbodig, aangezien deze twee waarden er al in staan, maar dan als parameters en niet als attributen. De code is hier louter ter illustratie.
  3. HttpServletResponse response: het antwoord dat naar de client wordt verzonden. De actie zou dit antwoord kunnen aanvullen. Hier doet ze dat niet.

Hier hebben we te maken met een speciaal geval. De methode execute hoeft vrijwel niets te doen. Ze moet alleen aangeven dat de volgende weergave de weergave **/reponse.do is en in het verzoek vermelden dat deze weergave de gegevens ‘naam’ en ‘leeftijd’ ontvangt die deze weergave moet weergeven. Dit doet ze met behulp van de methode findForward van de klasse ActionMapping, die als parameter een van de sleutels accepteert die in de forward-tags** van de configuratie van de actie staan. Hier is er slechts één dergelijke tag:

            <forward name="reponse" path="/reponse.do"/>

Onze methode execute retourneert dus een **ActionForward met "reponse" als sleutel om aan te geven dat de weergave /reponse.do** moet worden verzonden.

3.6. Tests van FormulaireAction

We compileren de vorige klasse met JBuilder en plaatsen het gegenereerde .class-bestand in WEB-INF/classes:

Image

We passen de weergave /vues/reponse.personne.jsp aan:

<%
     // we halen de gegevens naam en leeftijd op
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age"); 
%>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td><%= nom %>
      </tr>
        <tr>
          <td>Age</td>
        <td><%= age %>
      </tr>
    </table>      
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

De weergave haalt de gegevens 'naam' en 'leeftijd' op uit de attributen van de verzoek die het ontvangt. We vragen het formulier op bij de URL http://localhost:8080/strutspersonne/formulaire.do en vullen het vervolgens in:

Image

We gebruiken de knop [Envoyer] en krijgen het volgende antwoord:

Image

Toelichting:

  • We zullen de uitleg die voor test nr. 2 is gegeven, gebruiken voor het begin van het proces. Laten we de configuratie van de actie /main nog eens bekijken:
      <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>
  • nadat het formulier naar de controller bij URL /main.do was verzonden, heeft deze een object frmPersonne van het type FormulaireBean aangemaakt of hergebruikt en daarin de waarden van het formulier geplaatst
  • de methode validate van het object frmPersonne is aangeroepen. Aangezien de gegevens geldig waren, heeft de methode validate een lege lijst ActionErrors geretourneerd.
  • Er is een object FormulaireAction aangemaakt of hergebruikt en de methode `execute` ervan is aangeroepen. Deze methode heeft een object ActionForward met de sleutel "reponse" geretourneerd.
  • De controller heeft vervolgens de weergave verzonden die gekoppeld is aan de sleutel „reponse“, namelijk c.a.d. /reponse.do en dus /vues/reponse.personne.jsp.
  • De weergave reponse.personne.jsp werd weergegeven met de waarden die via de methode `execute` van het object FormulaireAction in het verzoek waren opgegeven.

3.7. Conclusie

We hebben een complete maar eenvoudige applicatie gebouwd. Wanneer men deze daadwerkelijk implementeert met Struts, Tomcat en JBuilder, zijn er talrijke mogelijkheden om fouten te maken, met name in de configuratiebestanden van de applicatie, zoals XML. Op het eerste gezicht lijkt het misschien eenvoudiger om deze applicatie zonder Struts te bouwen met een servlet en JSP-pagina’s. Voor de beginner is dat waarschijnlijk ook zo. Naarmate je meer ervaring opdoet, wordt het echter eenvoudiger om met Struts te ontwikkelen. Veel bedrijven schrijven de Struts-methodologie voor bij hun webontwikkelingen om de volgende redenen:

  • Struts volgt het MVC-model
  • wanneer alle ontwikkelaars op dezelfde manier werken, wordt het onderhoud van applicaties eenvoudiger omdat ze een standaardarchitectuur hebben.