Skip to content

9. Aplikacja internetowa MVC [personne] – wersja 4

Ta wersja korzysta z biblioteki znaczników JSTL przedstawionej wcześniej.

9.1. Projekt Eclipse

Aby utworzyć projekt Eclipse [mvc-personne-04] dla aplikacji internetowej [/personne4], należy skopiować projekt [mvc-personne-03], postępując zgodnie z procedurą opisaną w punkcie 6.2 na stronie 78.

9.2. Konfiguracja aplikacji internetowej [personne4]

Plik web.xml aplikacji /personne4 ma następującą treść:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>mvc-personne-04</display-name>
    ...

Plik ten jest identyczny z plikiem z poprzedniej wersji, z wyjątkiem wiersza 6, w którym nazwa wyświetlana aplikacji internetowej została zmieniona na [mvc-personne-04].

Strona główna [index.jsp] zmienia się na:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<c:redirect url="/main"/>
  • wiersz 5: strona [index.jsp] przekierowuje klienta na adres URL [/main], który prowadzi do kontrolera [ServletPersonne] aplikacji [/personne4]. Tag <c:redirect> należy do biblioteki JSTL / Core. Jego cechą charakterystyczną jest uzupełnianie adresu URL podanego w atrybucie [url] poprzez dodanie:
  • prefiks [/contexte], gdzie [contexte] to kontekst aplikacji, w tym przypadku [personne4].
  • sufiks [?jsessionid=id_session], jeśli przeglądarka wysyłająca żądanie nie przesłała pliku cookie sesji. Identyfikator [jsessionid] oznacza identyfikator tokenu sesji wysyłanego przez serwer WWW do swoich klientów. Zależy on od serwera WWW. W tym przypadku jest to identyfikator serwera Tomcat. [id_session] to sam token sesji.

Zatem rzeczywisty adres URL przekierowania z linii 5, [index.jsp], to adres [/personne4/main?jsessionid=XX], gdzie XX jest tokenem sesji. Właśnie to pokazuje poniższa strona, uzyskana po początkowym wywołaniu adresu URL [http://localhost:8080/personne4]:

Image

Związek między tagiem <c:redirect> a tokenem sesji jest dość subtelny. Jego analiza w tym miejscu byłaby przedwczesna, ale będziemy mieli okazję do powrotu do tego tematu.

9.3. Kod widoków

9.3.1. Widok [formulaire]

Ten widok nie uległ zmianie:

Image

Jest on generowany przez następującą stronę: JSP [formulaire.jsp]:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
  <head>
    <title>Personne - formulaire</title>
    <script language="javascript">
...
      </script>
  </head>
  <body>
    <center>
      <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" method="post">
        <table>
          <tr>
            <td>Nom</td>
            <td><input name="txtNom" value="${nom}" type="text" size="20"></td>
          </tr>
          <tr>
            <td>Age</td>
            <td><input name="txtAge" value="${age}" type="text" size="3"></td>
          </tr>
          <tr>
        </table>
        <table>
          <tr>
            <td><input type="submit" value="Submit"></td>
            <td><input type="button" value="[Envoyer]" onclick="envoyer()"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" value="[Effacer]" onclick="effacer()"></td>
          </tr>
        </table>
        <input type="hidden" name="action" value="validationFormulaire">
      </form>
    </center>
  </body>
</html>

Nowości:

  • wiersz 4: deklaracja biblioteki znaczników JSTL / Core
  • wiersze 21, 25: pobieranie atrybutów [nom, age] z szablonu strony. Przypomnijmy, że atrybuty te będą wyszukiwane kolejno w zapytaniu [request], sesji [session] oraz aplikacji [application] strony JSP. W naszym przypadku kontroler umieści je w sesji.
  • Na początku strony JSP nie ma już kodu Java służącego do pobrania szablonu strony ze względu na poprzedni przebieg operacji.

9.3.2. Widok [reponse]

Ten widok nie uległ zmianie:

Nowa strona JSP [reponse.jsp] wygląda następująco:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td>${nom}</td>
      </tr>
        <tr>
          <td>Age</td>
        <td>${age}</td>
      </tr>
    </table>      
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      ${lienRetourFormulaire}
    </a>
  </body>
</html>

Nowości:

  • wiersz 4: deklaracja biblioteki znaczników JSTL / Core
  • wiersze 16, 20, 28: pobieranie atrybutów [nom, age, lienRetourFormulaire] w szablonie strony. Na początku strony nie ma już kodu Java JSP służącego do ich pobierania.

9.3.3. Widok [erreurs]

Ten widok nie uległ zmianie:

Nowa strona JSP [erreurs.jsp] wygląda następująco:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      ${lienRetourFormulaire}
    </a>
  </body>
</html>

Nowości:

  • wiersz 4: deklaracja biblioteki tagów JSTL / Core
  • wiersze 13–15: wyświetlanie listy błędów za pomocą JSTL
  • na początku strony nie ma już kodu Java JSP służącego do pobrania jej szablonu.

9.4. Testowanie widoków

Aby przeprowadzić testy powyższych widoków, duplikujemy ich strony JSP w folderze /WebContent/JSP projektu Eclipse:

Image

Następnie w folderze JSP strony są modyfikowane w następujący sposób:

[formulaire.jsp]:


...
<%
  // -- test: tworzymy szablon strony
  session.setAttribute("nom","tintin");
  session.setAttribute("age","30");
%>

<html>
  <head>

Dodano wiersze 4–5 w celu utworzenia szablonu wymaganego przez stronę.

[reponse.jsp]:


...
<%
  // -- test: tworzymy szablon strony
  request.setAttribute("nom","milou");
  request.setAttribute("age","10");
  request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>


<html>
  <head>

...

Wiersze 4–6 zostały dodane w celu utworzenia szablonu wymaganego przez stronę.

[erreurs.jsp]:



<%
  // -- test: tworzymy szablon strony
  ArrayList<String> erreurs1=new ArrayList<String>();
  erreurs1.add("erreur1");
  erreurs1.add("erreur2");
  request.setAttribute("erreurs",erreurs1);
  request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>

<html>
  <head>

Wiersze 4–8 zostały dodane w celu utworzenia szablonu wymaganego przez stronę.

Uruchom Tomcat, jeśli jeszcze tego nie zrobiłeś, a następnie wywołaj następujące adresy URL:

 

Otrzymujemy oczekiwane widoki.

9.5. Kontroler [ServletPersonne]

Kontroler [ServletPersonne] aplikacji internetowej [/personne3] będzie obsługiwał następujące akcje:

nr
żądanie
źródło
przetwarzanie
1
[GET /personne4/main]
adres URL wpisany przez użytkownika
- wyślij pusty widok [formulaire]
2
[POST /personne4/main]
z parametrami [txtNom,
txtAge,
action=validationFormulaire]
wysłane
po kliknięciu przycisku
[Envoyer] w widoku
[formulaire]
- sprawdź wartości parametrów [txtNom, txtAge]
- jeśli są nieprawidłowe, wyślij widok [erreurs(erreurs)]
- jeśli są prawidłowe, wyślij widok [reponse(nom,age)]
3
[POST /personne4/main]
z parametrami
[action=retourFormulaire]
opublikowane
kliknięcie linku [Powrót do
formularza] w widokach
[réponse] i [erreurs].
- wysłanie widoku [formulaire] z wstępnie wypełnionymi najnowszymi wprowadzonymi wartościami

Szkielet kontrolera [ServletPersonne] jest identyczny jak w poprzedniej wersji. Omówimy zmiany wprowadzone w metodach [doInit, doValidationFormulaire, doRetourFormulaire], ponieważ metody [init, doGet, doPost] pozostały bez zmian.

9.5.1. Metoda [doInit]

Metoda ta przetwarza żądanie nr 1 [GET /personne4/main]. Jej kod wygląda następująco:

1
2
3
4
5
6
     // wyświetlanie pustego formularza
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
}

Nowości:

  • wiersz 3: wyświetlany jest widok [formulaire]. W swoim szablonie oczekuje on atrybutów „nazwa” i „wiek”. Nie znajdzie ich tam, ponieważ kontroler ich tam nie umieszcza. W takim przypadku biblioteka JSTL pobierze wskaźniki null dla tych atrybutów. Nie powoduje to żadnych błędów, a dla elementów ${nom} i ${age} w widoku [formulaire] wyświetlane będą puste wartości. To nam odpowiada. W ten sposób unikamy konieczności inicjalizacji modelu widoku [formulaire].

9.5.2. Metoda [doValidationFormulaire]

Metoda ta przetwarza zapytanie nr 2 [POST /personne4/main] z [action, txtNom, txtAge] w przesłanych elementach. Jej kod wygląda następująco:

     // walidacja formularza
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
                 // pobieramy parametry
        String nom = request.getParameter("txtNom");
        String age = request.getParameter("txtAge");
         // i zapisujemy je w sesji
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", nom);
        session.setAttribute("age", age);
         // weryfikacja parametrów
...
         // parametry są poprawne – wysyłamy stronę odpowiedzi
        request.setAttribute("lienRetourFormulaire", (String)params.get("lienRetourFormulaire"));
        getServletContext().getRequestDispatcher((String)params.get("urlReponse")).forward(request,
                response);
        return;
    }

Nowości:

  • wiersz 15: metoda [doValidationFormulaire] wysyła w odpowiedzi widok [réponse]. Widok ten zawiera w swoim szablonie elementy [nom, age, lienRetourFormulaire]. Element [lienRetourFormulaire] jest umieszczany w szablonie w wierszu 14 za pośrednictwem zapytania. Elementy [nom,age] są natomiast umieszczane w modelu w wierszach 8–10 za pośrednictwem sesji. W poprzedniej wersji elementy [nom, age] umieszczano również w żądaniu podczas wysyłania widoku [réponse], ponieważ widok ten oczekiwał ich właśnie tam. W tym przypadku, korzystając z biblioteki JSTL, wiemy, że różne konteksty (żądanie, sesja, aplikacja) zostaną przeszukane w celu znalezienia elementów modelu. Zostaną one zatem znalezione w sesji, ponieważ kontroler umieścił je właśnie tam (wiersze 8–10).

9.5.3. Metoda [doRetourFormulaire]

Ta metoda przetwarza żądanie nr 3 [POST /personne4/main] z [action=retourFormulaire] w przesłanych elementach. Jej kod wygląda następująco:

1
2
3
4
5
6
7
     // wyświetlenie wstępnie wypełnionego formularza
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         // wyświetlanie formularza
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

Nowości:

  • wiersz 4: wyświetlany jest widok [formulaire]. W swoim modelu oczekuje on atrybutów „nazwa” i „wiek”. Znajdzie je w sesji, ponieważ umieściła je tam metoda [doValidationFormulaire], a metoda ta jest z konieczności wykonywana przed metodą [doRetourFormulaire]. Nie ma zatem potrzeby inicjalizowania modelu [formulaire] przed jego wyświetleniem w wierszu 4. W związku z tym metody [doInit] i [doRetourFormulaire] są identyczne i można by usunąć akcję [retourFormulaire], zastępując ją akcją [init]. Metoda [doRetourFormulaire] zniknęłaby wówczas.

9.6. Tests

W tej nowej wersji zmieniają się jedynie widoki. Kontroler [ServletPersonne] pozostaje bez zmian. Wykorzystanie akcji JSTL pozwoliło nam po prostu w prostszy sposób wykorzystać na stronach JSP model zbudowany przez kontroler.

Uruchom lub ponownie uruchom serwer Tomcat po dodaniu do niego projektu Eclipse o nazwie [personne-mvc-04]. Wywołaj adres URL [http://localhost:8080/personne4].