Skip to content

2. Aplikacja strutspersonne

Wykorzystując klasyczną metodę, serwlet i strony JSP, zrealizowaliśmy aplikację dotyczącą osób. Zamierzamy wprowadzić Struts właśnie na przykładzie tej samej aplikacji.

2.1. Działanie aplikacji

Przypomnijmy sobie działanie aplikacji „person”, którą stworzyliśmy. Składa się ona z:

  • z serwletu głównego. To właśnie on odpowiada za całą logikę aplikacji.
  • trzech stron JSP: formulaire.personne.jsp, reponse.personne.jsp, erreurs.personne.jsp

Aplikacja działa w następujący sposób. Dostęp do niej uzyskuje się poprzez adres http://localhost:8080/personne/main. Pod tym adresem wyświetla się formularz dostarczany przez stronę formulaire.personne.jsp:

Image

Użytkownik wypełnia formularz i naciska przycisk typu „submit” o nazwie [Envoyer]. Przycisk [Rétablir] jest przyciskiem typu „reset”, c.a.d, który przywraca dokument do stanu, w jakim został otrzymany. Przycisk [Effacer] jest przyciskiem typu „button”. Użytkownik musi podać prawidłowe imię i wiek. Jeśli tak nie jest, wyświetlana jest strona błędów za pośrednictwem strony JSP erreurs.personne.jsp. Oto przykłady:

Transakcja nr 1

demande
réponse

Jeśli klikniemy link [Retour au formulaire], znajdziemy go w takim samym stanie, w jakim go zostawiliśmy:

Wymiana nr 2

demande
réponse

Jeśli użytkownik prześle poprawne dane, aplikacja wyśle mu odpowiedź za pośrednictwem strony JSP reponse.personne.jsp.

Wymiana nr 1

demande
réponse

Jeśli klikniemy link [Retour au formulaire], znajdziemy go w takim samym stanie, w jakim go zostawiliśmy:

Wymiana nr 2

demande
réponse

2.2. Architektura aplikacji oparta na Struts

Zastosujemy następującą architekturę Struts:

  • będą trzy widoki
  • kontrolerem będzie ten dostarczony przez Struts
  • FormulaireBean to klasa odpowiedzialna za przechowywanie wartości formularza przedstawionego przez widok formulaire.personne.jsp
  • FormulaireAction to klasa odpowiedzialna za przetwarzanie wartości z klasy FormulaireBean oraz wskazanie strony odpowiedzi, która ma zostać wysłana:
    • widok erreurs.personne.jsp, jeśli dane z formularza są błędne
    • widok reponse.personne.jsp w przeciwnym razie

Zadaniem programisty jest napisanie kodu:

  • trzech widoków
  • beanu FormulaireBean powiązanego z formularzem
  • klasy FormulaireAction odpowiedzialnej za przetwarzanie formularza

2.3. Kompilacja klas niezbędnych dla aplikacji Struts

Aby skompilować klasy niezbędne dla naszej aplikacji, użyjemy programu JBuilder. Program ten współpracuje z plikiem JDK, w którym nie ma klas niezbędnych dla aplikacji Struts. Program JBuilder można skonfigurować w następujący sposób:

  • opcja Tools (Narzędzia) / Configure JDKs (Konfiguruj JDK)

Image

  • należy użyć przycisku [Add/Ajouter], aby dodać do archiwum klas JBuilder pliki .jar dostarczone przez Struts. Jeśli archiwum Struts zostało rozpakowane na dysku, do JBuildera można dodać wszystkie pliki .jar z folderu <struts>/lib:

Image

Wszystkie powyższe pliki .jar można dodać do archiwów JBuilder. Widzieliśmy już, że Tomcat również potrzebuje dostępu do archiwów Struts. W przypadku Tomcata 4.x pliki .jar Struts można umieścić w katalogu <tomcat4>\common\lib. W przypadku Tomcata 5.x można je umieścić w katalogu <tomcat5>\shared\lib. Następnie można ustawić, aby JBuilder szukał plików .jar Struts w tym samym miejscu co Tomcat. Tak właśnie zrobiono na zrzucie ekranu przedstawiającym nieco wyżej pliki .jar JBuildera. Zostały one pobrane z katalogu <tomcat5>\shared\lib.

Jeśli więc podczas kompilacji klasy JBuilder zgłasza, że nie może znaleźć klasy Struts, należy sprawdzić dwie rzeczy:

  • pisownię nazwy klasy
  • pliki .jar używane przez JBuilder. Wszystkie pliki .jar Struts muszą się tam znajdować.

2.4. Widoki aplikacji strutspersonne

Trzy widoki aplikacji to:

  • formulaire.personne.jsp: wyświetla formularz do wprowadzania imienia i wieku osoby
  • reponse.personne.jsp: wyświetla wprowadzone wartości, jeśli są prawidłowe
  • erreurs.personne.jsp: wyświetla błędy, jeśli takie występują

2.4.1. Widok erreurs.personne.jsp

Ten widok, wyświetlający listę błędów, zostanie zdefiniowany w następujący sposób:

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

W tym kodzie znajdują się dwie nowości:

  1. obecność tagów <html:XX/>, które nie są tagami HTML. Można bowiem tworzyć biblioteki tagów JSP, które podczas przekształcania strony JSP w serwlet są przekształcane na kod Java.
  2. Strona JSP musi zadeklarować biblioteki znaczników, z których korzysta. Czyni to tutaj za pomocą wiersza
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

Wiersz ten zawiera dwie informacje:

  • uri: lokalizacja pliku określającego zasady korzystania z biblioteki. Plik struts-html.tld jest dostarczany w dystrybucji Struts. W powyższym przykładzie umieści się go w folderze WEB-INF.
  • prefix: identyfikator używany w kodzie jako prefiks dla tagów biblioteki. Pozwala to uniknąć konfliktów nazw, które mogłyby wystąpić podczas jednoczesnego korzystania z kilku bibliotek tagów. Możliwe jest bowiem, że w dwóch różnych bibliotekach znajdą się tagi o tej samej nazwie. Przypisując każdej bibliotece inny prefiks, eliminuje się wszelkie niejasności.
  • Tag <html:errors> wyświetla listę błędów przekazanych mu przez kontroler Struts.
  • Tag <html:link> generuje link kierujący do /C/page, gdzie
    • C oznacza kontekst aplikacji
    • page to URL wskazane w atrybucie page tego tagu

Tag

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

wygeneruje następujący kod HTML:

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

gdzie C oznacza kontekst aplikacji

2.4.2. Test widoku erreurs.personne.jsp

  • plik erreurs.personne.jsp zostanie umieszczony w folderze widoków aplikacji strutspersonne:

Image

  • plik struts-html.tld został pobrany z dystrybucji Struts (<struts>/lib) i umieszczony w WEB-INF:

Image

  • plik struts-config.xml zostaje zmodyfikowany w następujący sposób:
<?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>

W pliku konfiguracyjnym tworzymy nowy element URL /błędy, który ma być obsługiwany przez kontroler Struts. URL /erreurs.do zostanie przekierowany do widoku /vues/erreurs.personne.jsp. Plik struts-config.xml umieszczamy w folderze WEB-INF.

  • Uruchamiamy ponownie serwer Tomcat, aby uwzględnić nowy plik struts-config.xml, a następnie wpisujemy adres URL http://localhost:8080/strutspersonne/erreurs.do:

Image

Tag <html:errors/> nie wygenerował żadnej odpowiedzi. Jest to normalne, ponieważ akcja ForwardAction nie wygenerowała listy błędów oczekiwanej przez ten tag. Niemniej jednak powyższa odpowiedź pokazuje, że nasz widok JSP jest przynajmniej poprawny pod względem składniowym – w przeciwnym razie otrzymalibyśmy stronę z błędami. Sprawdźmy kod HTML odebrany przez przeglądarkę (Widok/Źródło):

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

Warto zwrócić uwagę na link wygenerowany przez tag <html:link>. Kontekst /strutspersonne został automatycznie uwzględniony w linku. Pozwala to na przeniesienie aplikacji z jednego kontekstu do drugiego (na przykład przy zmianie komputera) bez konieczności zmiany linków wygenerowanych przez <html:link>.

2.4.3. Widok reponse.personne.jsp

Widok ten, potwierdzający wartości wprowadzone w formularzu, wygląda następująco:

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

<%
     // pobieramy dane: imię, wiek
  //String imię = (String)request.getAttribute("imię");
  String nom="jean";

   //String imię = (String)request.getAttribute("imię"); 
  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>

Strona wyświetla dwie informacje: [nom] oraz [age], które zostaną jej przekazane przez kontroler w predefiniowanym obiekcie request. W tym przypadku przeprowadzamy test, w którym kontroler nie będzie miał możliwości ustalenia wartości [nom] i [age]. Dlatego też inicjujemy te dwa elementy danymi o dowolnych wartościach. Ponadto również w tym przypadku link powrotny do formularza jest generowany za pomocą tagu <html:link>.

2.4.4. Test widoku reponse.personne.jsp

  • Plik reponse.personne.jsp znajduje się w folderze „vues” aplikacji strutspersonne:

Image

  • plik struts-config.xml został zmodyfikowany w następujący sposób:
<?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>

W pliku konfiguracyjnym tworzymy nową odpowiedź URL, która ma być przetwarzana przez kontroler Struts. URL /reponse.do zostanie przekierowany do widoku /vues/reponse.personne.jsp. Plik struts-config.xml umieszczamy w folderze WEB-INF.

  • Uruchamiamy ponownie serwer Tomcat, aby nowy plik struts-config.xml został uwzględniony, a następnie wpisujemy adres URL http://localhost:8080/strutspersonne/erreurs.do:

Image

Otrzymujemy dokładnie to, czego oczekiwaliśmy.

2.4.5. Widok formulaire.personne.jsp

Ten widok przedstawia formularz służący do wprowadzania imienia i wieku użytkownika. Jego kod JSP jest następujący:

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

Ponownie pojawia się biblioteka znaczników struts-html.tld wykorzystywana w widoku błędów. Pojawiają się nowe znaczniki:

html:form
służy zarówno do wygenerowania tagu HTML <form>, jak i do przekazania informacji kontrolerowi, który będzie przetwarzał ten formularz:
action
adres URL, na który zostaną wysłane wartości z formularza
name
nazwa formularza HTML. Jest to również nazwa komponentu, który będzie przechowywał wartości tego formularza
type
nazwa klasy, która musi zostać zainicjowana w celu uzyskania bean’a przechowującego dane formularza
Należy zauważyć, że metoda przesyłania parametrów formularza (GET/POST) do kontrolera nie jest określona. Można to zrobić za pomocą atrybutu method. W przypadku jego braku domyślnie stosowana jest metoda POST.
html:text
służy do generowania tagu <input type="text" value="...">:
property
nazwa pola w bean formularza, które zostanie powiązane z polem wprowadzania danych. Podczas wysyłania formularza na serwer (klient → serwer) pole w bean przyjmie wartość z pola wprowadzania danych. Podczas wyświetlania formularza (serwer → klient) wartość zawarta w polu w bean jest wyświetlana w polu wprowadzania danych.
html:submit
służy do wygenerowania tagu HTML <input type="submit"...>
html:reset
służy do wygenerowania tagu HTML <input type="reset"...>
html:button
służy do wygenerowania tagu HTML <input type="button"...>

2.4.6. Bean powiązany z formularzem formulaire.personne.jsp

  • W Struts każdy formularz musi być powiązany z beanem odpowiedzialnym za zapamiętywanie wartości z formularza i przechowywanie ich w bieżącej sesji. Bean to klasa Java, która musi być zgodna z określoną składnią. Bean powiązany z formularzem musi pochodzić od klasy ActionForm zdefiniowanej w bibliotekach Struts:
public class FormulaireBean extends ActionForm {
  • nazwy atrybutów bean muszą odpowiadać polom formularza (atrybuty property tagów html:text w formularzu). Zgodnie z kodem poprzedniego formularza bean musi zatem posiadać dwa pola o nazwach nom i age.
  • Dla każdego pola XX w formularzu bean musi definiować dwie metody:
    • public void setXX(Type wartość): w celu przypisania wartości do atrybutu XX
    • Type getXX(): w celu pobrania wartości pola XX

Bean powiązany z powyższym formularzem mógłby wyglądać następująco:

package istia.st.struts.personne;

import org.apache.struts.action.ActionForm;

public class FormulaireBean extends ActionForm {
   // imię
  private String nom = null;
  public String getNom() {
    return nom;
  }
  public void setNom(String nom) {
    this.nom = nom;
  }

   // wiek
  private String age = null;
  public String getAge() {
    return age;
  }
  public void setAge(String age) {
    this.age = age;
  }
}

Klasę tę skompilujemy za pomocą JBuilder.

2.4.7. Test widoku formulaire.personne.jsp

Plik formulaire.personne.jsp znajduje się w folderze „vues” aplikacji Strutspersonne:

Image

  • Plik struts-config.xml został zmodyfikowany w następujący sposób:
<?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>

W pliku konfiguracyjnym tworzymy nowy formularz URL, który ma być przetwarzany przez kontroler Struts. URL /formulaire.do zostanie przekierowany do widoku /vues/formulaire.personne.jsp. Plik struts-config.xml umieszczamy w folderze WEB-INF.

  • Umieszczamy klasę FormulaireBean w folderze WEB-INF/classes:

Image

  • uruchamiamy ponownie Tomcat, aby uwzględnić nowy plik struts-config.xml, a następnie wywołujemy adres URL http://localhost:8080/strutspersonne/formulaire.do:

Image

Formularz wyświetla się poprawnie. Możemy z ciekawością sprawdzić, w jaki sposób „przetłumaczono” tagi <html:XX>, które pojawiały się w kodzie JSP formularza:

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

W uzyskanym formularzu działają przyciski [Przywróć] i [Effacer]. Przycisk typu submit o nazwie [Envoyer] przekierowuje do strony URL /strutspersonne/main.do. Zgodnie z plikiem web.xml aplikacji kontroler Struts zajmie się tym. Zgodnie z plikiem struts-config.html kontroler powinien przekierować żądanie do widoku /vues/main.html. Spróbujmy:

Image

Wszystko przebiega zgodnie z oczekiwaniami. Pozostaje nam jeszcze faktycznie przetworzyć wartości z formularza, c.a.d. Należy napisać klasę typu Action, która będzie odbierać dane z formularza do obiektu FormulaireBean.