Skip to content

2. De Struts-toepassing ‘personeel’

We hebben op de klassieke manier, met servlets en JSP-pagina’s, een ‘persoon’-applicatie behandeld. We willen Struts introduceren aan de hand van dezezelfde applicatie.

2.1. De werking van de applicatie

Laten we hier nog even de werking van de 'persoon'-applicatie die we hebben ontwikkeld in herinnering brengen. Deze bestaat uit:

  • een hoofd-servlet. Deze zorgt voor de volledige logica van de applicatie.
  • drie JSP-pagina's: formulaire.personne.jsp, reponse.personne.jsp, erreurs.personne.jsp

De applicatie werkt als volgt. Ze is toegankelijk via de URL http://localhost:8080/personne/main. Op deze URL verschijnt een formulier dat wordt aangereikt door de pagina formulaire.personne.jsp:

Image

De gebruiker vult het formulier in en klikt op de knop [Envoyer] van het type ‘submit’. De knop [Rétablir] is van het type ‘reset’, c.a.d, waarmee het document wordt teruggezet in de staat waarin het werd ontvangen. De knop [Effacer] is van het type ‘button’. De gebruiker moet een geldige naam en leeftijd opgeven. Als dat niet het geval is, wordt er een foutpagina naar hem verzonden via de pagina JSP erreurs.personne.jsp. Hier volgen enkele voorbeelden:

Transactie nr. 1

demande
réponse

Als we de link [Retour au formulaire] volgen, vinden we deze terug in de staat waarin we hem hebben achtergelaten:

Uitwisseling nr. 2

demande
réponse

Als de gebruiker correcte gegevens verstuurt, stuurt de applicatie hem een antwoord via de pagina JSP reponse.personne.jsp.

Uitwisseling nr. 1

demande
réponse

Als we de link [Retour au formulaire] volgen, vinden we deze terug in de staat waarin we hem hebben achtergelaten:

Uitwisseling nr. 2

demande
réponse

2.2. De Struts-architectuur van de applicatie

We zullen de volgende Struts-architectuur hanteren:

  • Er zullen drie weergaven zijn
  • de controller is die welke door Struts wordt geleverd
  • FormulaireBean is de klasse die verantwoordelijk is voor het opslaan van de waarden van het formulier dat wordt weergegeven door de weergave formulaire.personne.jsp
  • FormulaireAction is de klasse die de waarden van FormulaireBean verwerkt en aangeeft welke responspagina moet worden verzonden:
    • de weergave erreurs.personne.jsp als de gegevens van het formulier onjuist zijn
    • de weergave reponse.personne.jsp in het andere geval

Voor de ontwikkelaar bestaat de taak uit het schrijven van de code:

  • van de drie weergaven
  • van de bean FormulaireBean die aan het formulier is gekoppeld
  • van de klasse FormulaireAction die het formulier verwerkt

2.3. De klassen compileren die nodig zijn voor de Struts-toepassing

Om de klassen te compileren die nodig zijn voor onze applicatie, gebruiken we JBuilder. Dit programma werkt met een JDK waarin de klassen die nodig zijn voor Struts-applicaties niet aanwezig zijn. We kunnen JBuilder als volgt configureren:

  • optie Tools (Extra) / Configure JDKs (JDK configureren)

Image

  • gebruik de knop [Add/Ajouter] om de door Struts meegebrachte .jar-bestanden toe te voegen aan de klassenarchieven van JBuilder. Als het Struts-archief op de schijf is uitgepakt, kunnen alle .jar-bestanden uit de map <struts>/lib aan JBuilder worden toegevoegd:

Image

Alle bovengenoemde .jar-bestanden kunnen aan de JBuilder-archieven worden toegevoegd. We hebben al gezien dat ook Tomcat toegang moet hebben tot de Struts-archieven. Voor Tomcat 4.x kun je de .jar-bestanden van Struts in <tomcat4>\common\lib plaatsen. Voor Tomcat 5.x kun je ze in <tomcat5>\shared\lib plaatsen. Vervolgens kun je instellen dat JBuilder de Struts-jar-bestanden op dezelfde locatie vindt als Tomcat. Dit is wat er is gedaan in de schermafbeelding hierboven, waarin de JBuilder-jar-bestanden te zien zijn. Ze zijn opgehaald uit <tomcat5>\shared\lib.

Als JBuilder bij het compileren van een klasse aangeeft dat het een Struts-klasse niet kan vinden, controleer dan twee dingen:

  • de spelling van de klasse
  • de .jar-bestanden die door JBuilder worden gebruikt. Alle Struts-jar-bestanden moeten hierin aanwezig zijn.

2.4. De weergaven van de strutspersonne-applicatie

De drie weergaven van de applicatie zijn de volgende:

  • formulaire.personne.jsp: toont het formulier voor het invoeren van de naam en leeftijd van een persoon
  • reponse.personne.jsp: toont de ingevoerde waarden als deze geldig zijn
  • erreurs.personne.jsp: toont de fouten, indien aanwezig

2.4.1. De weergave erreurs.personne.jsp

Deze weergave, die een lijst met fouten toont, wordt als volgt gedefinieerd:

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

Er zijn twee nieuwe elementen in deze code:

  1. de aanwezigheid van <html:XX/>-tags, die geen HTML-tags zijn. Men kan namelijk bibliotheken met JSP-tags aanmaken die bij de omzetting van de pagina JSP in een servlet worden omgezet in Java-code.
  2. De pagina JSP moet de tagbibliotheken aangeven die zij gebruikt. Dit gebeurt hier met de regel
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

Deze regel geeft twee gegevens weer:

  • uri: de locatie van het bestand waarin de gebruiksregels van de bibliotheek zijn vastgelegd. Het bestand struts-html.tld wordt meegeleverd in de Struts-distributie. In het bovenstaande voorbeeld wordt het in de map WEB-INF geplaatst.
  • prefix: de identificatiecode die in de code wordt gebruikt als voorvoegsel voor de tags van de bibliotheek. Dit voorkomt naamconflicten die kunnen ontstaan bij het gelijktijdig gebruik van meerdere tagbibliotheken. Het is namelijk mogelijk dat er in twee verschillende bibliotheken tags met dezelfde naam voorkomen. Door elke bibliotheek een ander voorvoegsel te geven, wordt elke dubbelzinnigheid weggenomen.
  • De tag <html:errors> geeft de lijst met fouten weer die de Struts-controller aan deze tag doorgeeft.
  • De tag <html:link> genereert een link die verwijst naar /C/page, waarbij
    • C de context van de applicatie is
    • page de URL is die is opgegeven in het page-attribuut van de tag

De tag

    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>

genereert de volgende HTML-code:

<a href="/C/formulaire.do">Retour au formulaire</a>

waarbij C de context van de applicatie is

2.4.2. Test van de weergave erreurs.personne.jsp

  • het bestand erreurs.personne.jsp wordt in de map ‘views’ van de StrutsPersonne-applicatie geplaatst:

Image

  • het bestand struts-html.tld wordt uit de Struts-distributie (<struts>/lib) gehaald en in WEB-INF geplaatst:

Image

  • het bestand struts-config.xml wordt als volgt gewijzigd:
<?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>
    <action-mappings>
      <action
          path="/main"
          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-mappings>
</struts-config>

We maken in het configuratiebestand een nieuwe URL /fouten aan, bedoeld om door de Struts-controller te worden verwerkt. De URL /erreurs.do wordt doorgestuurd naar de weergave /vues/erreurs.personne.jsp. Het bestand struts-config.xml wordt in de map WEB-INF geplaatst.

  • We starten Tomcat opnieuw op zodat het nieuwe bestand struts-config.xml wordt herkend, en vervolgens roepen we de URL http://localhost:8080/strutspersonne/erreurs.do op:

Image

De tag <html:errors/> heeft niets opgeleverd. Dat is normaal, want de actie ForwardAction heeft niet de foutenlijst gegenereerd die de tag verwachtte. Toch blijkt uit het bovenstaande antwoord dat onze weergave JSP in ieder geval syntactisch correct is; anders zouden we een foutpagina hebben gekregen. Laten we de code HTML controleren die door de browser is ontvangen (View/Source):

<html>
    <head>
      <title>Personne - erreurs</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>        
    <a href="/strutspersonne/formulaire.do">Retour au formulaire</a>    
  </body>
</html>

Let op de link die door de tag <html:link> wordt gegenereerd. De context /strutspersonne is automatisch in de link opgenomen. Hierdoor kan de applicatie van de ene context naar de andere worden verplaatst (bijvoorbeeld bij een wisseling van computer) zonder dat de door <html:link> gegenereerde links hoeven te worden aangepast.

2.4.3. De weergave reponse.personne.jsp

Deze weergave, die de in het formulier ingevoerde waarden bevestigt, ziet er als volgt uit:

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

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

   //String naam = (String)request.getAttribute("naam"); 
  String age="24"; 
%>

<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>      
    <br>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

De pagina geeft twee gegevens weer: [nom] en [age], die door de controller in het vooraf gedefinieerde object **request worden doorgegeven. Hier voeren we een test uit waarbij de controller geen kans krijgt om de waarden van [nom] en [age] vast te leggen. Daarom initialiseren we deze twee gegevens met willekeurige waarden. Ook hier wordt de teruglink naar het formulier gegenereerd door een <html:link**>-tag.

2.4.4. Test van de weergave reponse.personne.jsp

  • Het bestand reponse.personne.jsp wordt in de map ‘vues’ van de applicatie strutspersonne geplaatst:

Image

  • het bestand struts-config.xml wordt als volgt gewijzigd:
<?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>
    <action-mappings>
      <action
          path="/main"
          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-mappings>
</struts-config>

We maken in het configuratiebestand een nieuwe URL /reponse aan, bedoeld om door de Struts-controller te worden verwerkt. De URL /reponse.do wordt doorgestuurd naar de weergave /vues/reponse.personne.jsp. Het bestand struts-config.xml wordt in de map WEB-INF geplaatst.

  • We starten Tomcat opnieuw op zodat het nieuwe bestand struts-config.xml wordt herkend, en vervolgens roepen we de URL http://localhost:8080/strutspersonne/erreurs.do op:

Image

We krijgen inderdaad het verwachte resultaat.

2.4.5. De weergave formulaire.personne.jsp

Deze weergave toont het formulier voor het invoeren van de naam en leeftijd van de gebruiker. De code JSP is als volgt:

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

<html>
    <meta http-equiv="pragma" content="no-cache"> 
    <head>
      <title>Personne - formulaire</title>
    <script language="javascript">
        function effacer(){
          with(document.frmPersonne){
            nom.value="";
          age.value="";
        }
      }
    </script>
  </head>

  <body>
      <center>
        <h2>Personne - formulaire</h2>
      <hr>
      <html:form action="/main" name="frmPersonne" type="istia.st.struts.personne.FormulaireBean">
          <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>
        <table>
            <tr>
              <td><html:submit value="Envoyer"/></td>
            <td><html:reset value="Rétablir"/></td>
            <td><html:button property="btnEffacer" value="Effacer" onclick="effacer()"/></td>
          </tr>
        </table>
      </html:form>
    </center>
  </body>
</html>

We zien de tagbibliotheek struts-html.tld terug die in het foutenscherm wordt gebruikt. Er verschijnen nieuwe tags:

html:form
wordt zowel gebruikt om de tag HTML <form> te genereren als om informatie te verstrekken aan de controller die dit formulier moet verwerken:
action
URL waarnaar de waarden van het formulier worden verzonden
name
naam van het formulier HTML. Dit is ook de naam van de bean die de waarden ervan zal opslaan
type
naam van de klasse die moet worden geïnstantieerd om de opslag-bean van het formulier te verkrijgen
Merk op dat de methode voor het verzenden van de formulierparameters (GET/POST) naar de controller niet is gespecificeerd. Dit zou kunnen worden gedaan met het attribuut method. Als dit ontbreekt, wordt standaard de methode POST gebruikt.
html:text
wordt gebruikt om de tag <input type="text" value="..."> te genereren:
property
naam van het veld in de formulier-bean dat aan het invoerveld wordt gekoppeld. Bij het verzenden van het formulier naar de server (client -> server) neemt het veld in de bean de waarde van het invoerveld over. Bij het weergeven van het formulier (server -> client) wordt de waarde in het veld van de bean weergegeven in het invoerveld.
html:submit
wordt gebruikt om de tag HTML <input type="submit"...> te genereren
html:reset
wordt gebruikt om de tag HTML <input type="reset"...> te genereren
html:button
wordt gebruikt om de tag HTML <input type="button"...> te genereren

2.4.6. De bean die aan het formulier is gekoppeld: formulaire.personne.jsp

  • Bij Struts moet elk formulier worden gekoppeld aan een bean die de waarden van het formulier opslaat en deze in de huidige sessie bewaart. Een bean is een Java-klasse die aan een specifieke syntaxis moet voldoen. De bean die aan een formulier is gekoppeld, moet zijn afgeleid van de klasse ActionForm die in de Struts-bibliotheken is gedefinieerd:
public class FormulaireBean extends ActionForm {
  • De namen van de attributen van de bean moeten overeenkomen met de velden van het formulier (property-attributen van de html:text-tags van het formulier). Op basis van de code van het vorige formulier moet de bean dus twee velden hebben met de namen ‘nom’ en ‘age’.
  • Voor elk veld XX van het formulier moet de bean twee methoden definiëren:
    • public void setXX(Type waarde): om een waarde toe te wijzen aan het attribuut XX
    • Type getXX(): om de waarde van het veld XX op te halen

De bean die aan het vorige formulier is gekoppeld, zou er als volgt uit kunnen zien:

package istia.st.struts.personne;

import org.apache.struts.action.ActionForm;

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

We zullen deze klassen compileren met JBuilder.

2.4.7. Test van de weergave formulaire.personne.jsp

Het bestand formulaire.personne.jsp wordt in de map ‘views’ van de StrutsPersonne-applicatie geplaatst:

Image

  • Het bestand struts-config.xml wordt als volgt gewijzigd:
<?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>
    <action-mappings>
      <action
          path="/main"
          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>
</struts-config>

We maken in het configuratiebestand een nieuw URL /formulier aan dat door de Struts-controller moet worden verwerkt. De URL /formulaire.do wordt doorgestuurd naar de weergave /vues/formulaire.personne.jsp. Het bestand struts-config.xml wordt in de map WEB-INF geplaatst.

  • we plaatsen de klasse FormulaireBean in WEB-INF/classes:

Image

  • We starten Tomcat opnieuw op zodat het nieuwe bestand struts-config.xml wordt herkend, en vervolgens roepen we de URL http://localhost:8080/strutspersonne/formulaire.do op:

Image

Het formulier wordt inderdaad weergegeven. Misschien zijn we wel benieuwd hoe de tags <html:XX> die in de JSP-code van het formulier verspreid stonden, zijn ‘vertaald’:

<html>
    <meta http-equiv="pragma" content="no-cache"> 
    <head>
      <title>Personne - formulaire</title>
    <script language="javascript">
        function effacer(){
          with(document.frmPersonne){
            nom.value="";
          age.value="";
        }
      }
    </script>
  </head>

  <body>
      <center>

        <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" method="post" action="/strutspersonne/main.do">
          <table>
            <tr>
              <td>Nom</td>
            <td><input type="text" name="nom" size="20" value=""></td>
          </tr>

          <tr>
              <td>Age</td>
            <td><input type="text" name="age" size="3" value=""></td>
          </tr>
            <tr>
        </table>
        <table>
            <tr>

              <td><input type="submit" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" name="btnEffacer" value="Effacer" onclick="effacer()"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>

In het verkregen formulier werken de knoppen [Herstellen] en [Effacer]. De knop [Envoyer] van het type 'submit' verwijst naar de pagina URL /strutspersonne/main.do. Volgens het bestand web.xml van de applicatie zal de Struts-controller dit afhandelen. Volgens het bestand struts-config.html moet de controller het verzoek doorsturen naar de weergave /vues/main.html. Laten we het eens proberen:

Image

Alles verloopt zoals verwacht. Nu moeten we de waarden van het formulier nog daadwerkelijk verwerken, c.a.d. We schrijven de Action-klasse die de gegevens van het formulier in een object FormulaireBean zal ontvangen.