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:

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
![]() | ![]() |
Jeśli klikniemy link [Retour au formulaire], znajdziemy go w takim samym stanie, w jakim go zostawiliśmy:
Wymiana nr 2
![]() | ![]() |
Jeśli użytkownik prześle poprawne dane, aplikacja wyśle mu odpowiedź za pośrednictwem strony JSP reponse.personne.jsp.
Wymiana nr 1
![]() | ![]() |
Jeśli klikniemy link [Retour au formulaire], znajdziemy go w takim samym stanie, w jakim go zostawiliśmy:
Wymiana nr 2
![]() | ![]() |
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)

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

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:
- 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.
- Strona JSP musi zadeklarować biblioteki znaczników, z których korzysta. Czyni to tutaj za pomocą wiersza
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
wygeneruje następujący kod HTML:
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:

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

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

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:

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

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:
służy zarówno do wygenerowania tagu HTML <form>, jak i do przekazania informacji kontrolerowi, który będzie przetwarzał ten formularz:
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. | |||||||
służy do generowania tagu <input type="text" value="...">:
| |||||||
służy do wygenerowania tagu HTML <input type="submit"...> | |||||||
służy do wygenerowania tagu HTML <input type="reset"...> | |||||||
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:
- 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:

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

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

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:

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.








