7. Aplikacja internetowa MVC [personne] – wersja 3
Zalecana lektura w [ref1]: rozdział 9
7.1. Introduction
Proponujemy dodanie kodu JavaScript do stron HTML wysyłanych do przeglądarki. To właśnie przeglądarka wykonuje kod JavaScript osadzony na wyświetlanej stronie. Technologia ta jest niezależna od tej wykorzystywanej przez serwer WWW do generowania dokumentu HTML (Java/serwlety/JSP, ASP.NET, ASP, PHP, Perl, Python, ...).
[formulaire.jsp]
Widok tej strony będzie wyglądał następująco:

Przyciski, których nazwy są otoczone ramką, wykorzystują kod JavaScript osadzony na stronie HTML:
Nazwa | Typ HTML | Funkcja |
<submit> | pełni funkcję przycisku [Envoyer] z poprzednich wersji: przesyła wprowadzone wartości do kontrolera | |
<button> | nowy przycisk – lokalnie sprawdza poprawność wprowadzonych danych przed przesłaniem ich do kontrolera | |
<reset> | przywraca formularz do stanu, w jakim został pierwotnie odebrany przez przeglądarkę | |
<button> | usuwa zawartość obu pól wprowadzania danych |
Oto przykład wykorzystania przycisków [Envoyer] i [Effacer]:
![]() | ![]() |
![]() | ![]() |
Wykorzystamy również kod JavaScript do obsługi linku [Retour au formulaire] w widokach [erreurs] i [réponse]. Weźmy na przykład widok [réponse]:
![]() | 1 ![]() |
Różnica polega na adresie URL wyświetlanym w widoku [1]. W poprzedniej wersji adres ten brzmiał:
W tym przypadku akcja nie jest już częścią adresu URL, ponieważ zostanie wysłana przez POST zamiast przez GET. W wyniku tej zmiany jedynym adresem URL wyświetlanym przez przeglądarkę będzie [http://localhost:8080/personne3/main], niezależnie od żądanej akcji.
7.2. Projekt Eclipse
Aby utworzyć projekt Eclipse [mvc-personne-03] dla aplikacji internetowej [/personne3], należy skopiować projekt [mvc-personne-02], postępując zgodnie z procedurą opisaną w paragrafie 6.2 na stronie 78.
![]() | ![]() |
7.3. Konfiguracja aplikacji internetowej [personne3]
Plik web.xml aplikacji /personne3 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-03</display-name>
<!-- ServletPersonne -->
<servlet>
<servlet-name>personne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletPersonne
</servlet-class>
<init-param>
<param-name>urlReponse</param-name>
<param-value>
/WEB-INF/vues/reponse.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlErreurs</param-name>
<param-value>
/WEB-INF/vues/erreurs.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlFormulaire</param-name>
<param-value>
/WEB-INF/vues/formulaire.jsp
</param-value>
</init-param>
<init-param>
<param-name>lienRetourFormulaire</param-name>
<param-value>
Retour au formulaire
</param-value>
</init-param>
</servlet>
<!-- Mapowanie ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
<!-- pliki startowe -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Plik ten jest identyczny z plikiem z poprzedniej wersji, z wyjątkiem kilku szczegółów:
- wiersz 6: nazwa wyświetlana aplikacji internetowej została zmieniona na [mvc-personne-03]
Zniknął parametr [urlControleur]. W poprzedniej wersji służył on do ustalenia docelowego adresu POST dla widoku [formulaire]. W tej nowej wersji docelowym adresem będzie pusty ciąg znaków, c.a.d. adres URL wyświetlany przez przeglądarkę. Wyjaśniliśmy, że będzie to zawsze [http://localhost:8080/personne3/main], czyli ten, którego potrzebujemy dla POST w widoku [formulaire].
Strona główna [index.jsp] zmienia się:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
response.sendRedirect("/personne3/main");
%>
- wiersz 5: strona [index.jsp] przekierowuje klienta na adres URL kontrolera [ServletPersonne] w aplikacji [/personne3].
7.4. Kod widoków
7.4.1. Widok [formulaire]
Widok ten wygląda teraz następująco:

Jest on generowany przez następujące strony: JSP i [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">
<%// pobieramy dane z szablonu
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
// -------------------------------
function effacer(){
// kasowanie pól wprowadzania danych
with(document.frmPersonne){
txtNom.value="";
txtAge.value="";
}//z
}//wyczyść
// -------------------------------
function envoyer(){
// weryfikacja parametrów przed wysłaniem
with(document.frmPersonne){
// nazwa nie może być pusta
champs=/^\s*$/.exec(txtNom.value);
if(champs!=null){
// nazwa jest pusta
alert("Vous devez indiquer un nom");
txtNom.value="";
txtNom.focus();
// powrót do interfejsu graficznego
return;
}//if
// wiek musi być dodatnią liczbą całkowitą
champs=/^\s*\d+\s*$/.exec(txtAge.value);
if(champs==null){
// wiek jest nieprawidłowy
alert("Age incorrect");
txtAge.focus();
// powrót do interfejsu graficznego
return;
}//if
// parametry są poprawne – wysyłamy je na serwer
submit();
}//with
}//wyślij
</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>
Zmiany:
- wiersz 56: formularz ma nazwę [frmPersonne]. Nazwa ta będzie używana w kodzie JavaScript. Należy zwrócić uwagę na brak atrybutu [action], co powoduje, że formularz [frmPersonne] zostanie wysłany na adres URL wyświetlany przez przeglądarkę.
- wiersz 70: przycisk [Submit] pełni rolę przycisku [Envoyer] z poprzednich wersji
- wiersz 71: kliknięcie przycisku [Envoyer] typu [Button] powoduje wykonanie funkcji JavaScript [envoyer] zdefiniowanej w wierszu 24
- wiersz 72: przycisk [Rétablir] nie zmienił funkcji
- wiersz 73: kliknięcie przycisku [Effacer] typu [Button] powoduje wykonanie funkcji JavaScript [effacer] zdefiniowanej w wierszu 16
Zanim przejdziemy do omówienia kodu JavaScript, przypomnijmy kilka zasad notacji:
JavaScript obsługuje wyświetlaną stronę i jej zawartość jako drzewo obiektów, którego korzeniem jest obiekt [document]. W tym dokumencie może znajdować się jeden lub więcej formularzy. [document.frmPersonne] oznacza formularz o nazwie [frmPersonne] zdefiniowany w wierszu 56. Formularz ten również zawiera obiekty. Należą do nich pola wprowadzania danych. Tak więc [document.frmPersonne.txtNom] oznacza obiekt obrazu pola wprowadzania danych HTML zdefiniowanego w wierszu 60. Obiekt [txtNom] posiada różne właściwości, w tym właściwość [value], która określa zawartość pola wprowadzania danych. Zatem [document.frmPersonne.txtNom.value] określa zawartość pola wprowadzania danych [txtNom].
- wiersze 16–22: funkcja JavaScript [effacer] umieszcza pusty ciąg znaków w polach wprowadzania danych [txtNom, txtAge].
- wiersze 24–49: funkcja JavaScript [envoyer] sprawdza poprawność wartości w polach wprowadzania danych [txtNom, txtAge] przed ich wysłaniem. Wykorzystuje do tego wyrażenia regularne.
- wiersz 28: sprawdza, czy wartość pola wprowadzania danych [txtNom] odpowiada wzorcowi /s*, co oznacza 0 lub więcej spacji. Jeśli odpowiedź brzmi „tak”, oznacza to, że użytkownik nie podał nazwiska. W przypadku zgodności z wzorcem zmienna champs będzie miała wartość inną niż wskaźnik null, w przeciwnym razie przyjmie wartość null.
- wiersz 29: jeśli występuje zgodność z szablonem
- wiersz 30: wyświetla się komunikat dla użytkownika
- wiersz 32: w polu [txtNom] umieszczamy pusty ciąg znaków (może tam występować ciąg spacji)
- wiersz 33: ustawia się migający kursor na polu [txtNom]
- wiersz 34: przerywamy działanie funkcji. W ten sposób na serwerze nie ma pola POST z wprowadzonymi wartościami.
- wiersze 38–45: podobną procedurę stosuje się w przypadku pola [txtAge]
- wiersz 47: jeśli dotarliśmy do tego miejsca, oznacza to, że wprowadzone wartości są poprawne. Następnie wysyłamy (submit) formularz [frmPersonne] na serwer WWW. Wszystko przebiega wtedy tak, jakbyśmy kliknęli przycisk o nazwie [Submit].
7.4.2. Widok [reponse]
Ten widok wyświetla wartości wprowadzone w formularzu, o ile są one prawidłowe:
![]() | ![]() |
W porównaniu z poprzednią wersją nowość pojawia się dopiero po kliknięciu linku [Retour au formulaire] w widoku [réponse]:
![]() | ![]() |
Różnica polega na adresie URL wyświetlanym w widoku [1]. W poprzedniej wersji adres ten brzmiał:
W tym przypadku akcja nie jest już częścią adresu URL, ponieważ zostanie wysłana przez POST zamiast przez GET. Nowa strona JSP [reponse.jsp] to lqqqaaaaaaaaaqqAAAaaa
następująca:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// pobieramy dane z modelu
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<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>
<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:
- wiersze 35–37: link [Retour au formulaire] zawiera kod JavaScript. Kliknięcie tego linku powoduje wykonanie kodu JavaScript z atrybutu [href]. Jak widzieliśmy podczas analizy [formulaire.jsp], wiemy, że kod ten wysyła wartości pól typu <input>, <select> itp. z formularza [frmPersonne].
- wiersze 32–34: definiują formularz [frmPersonne]. Formularz ten zawiera tylko jedno pole typu <input type="hidden" ...>, a więc pole ukryte. To pole [action] służy do przekazania kontrolerowi nazwy akcji do wykonania, w tym przypadku [retourFormulaire].
7.4.3. Widok [erreurs]
Ten widok sygnalizuje błędy wprowadzonych danych w formularzu. Wprowadzona zmiana jest taka sama jak w przypadku widoku [réponse]:
![]() | ![]() |
Różnica polega na adresie URL wyświetlanym w widoku [1]. W poprzedniej wersji brzmiał on:
W tym przypadku akcja nie jest już częścią adresu URL, ponieważ zostanie wysłana przez POST zamiast przez GET. Nowa strona JSP [reponse.jsp] jest następująca:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>
<%
// pobieramy dane z modelu
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<%
for(int i=0;i<erreurs.size();i++){
out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
}//dla
%>
</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:
- wiersze 30–32: nowe obsługa kliknięcia w link. Wyjaśnienia na ten temat zawarte w analizie pliku [réponse.jsp] mają zastosowanie również w tym przypadku.
7.5. Testy widoków
Aby przeprowadzić testy poprzednich widoków, duplikujemy ich strony JSP w folderze /WebContent/JSP projektu Eclipse:

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");
%>
<%// pobieramy dane z szablonu
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
Dodano wiersze 4–5 w celu utworzenia szablonu wymaganego przez stronę w wierszach 9–10.
[reponse.jsp]:
...
<%
// -- test: tworzymy szablon strony
request.setAttribute("nom","milou");
request.setAttribute("age","10");
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// pobieramy dane z szablonu
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
...
Wiersze 4–6 zostały dodane w celu utworzenia szablonu wymaganego przez stronę w wierszach 11–13.
[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");
%>
<%
// pobieranie danych z szablonu
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
Wiersze 4–8 zostały dodane w celu utworzenia szablonu wymaganego przez stronę w wierszach 13–14.
Uruchom Tomcat, jeśli jeszcze tego nie zrobiłeś, a następnie wywołaj następujące adresy URL:
![]() | ![]() |
![]() |
Otrzymujemy oczekiwane widoki.
7.6. Kontroler [ServletPersonne]
Kontroler [ServletPersonne] aplikacji internetowej [/personne3] będzie obsługiwał następujące akcje:
nr | żądanie | źródło | przetwarzanie |
1 | [GET /personne3/main] | adres URL wpisany przez użytkownika | - wyślij pusty widok [formulaire] |
2 | [POST /personne3/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 /personne3/main] z parametrami [action=retourFormulaire] po | kliknięcie linku [Powrót do formularza] w widokach [réponse] i [erreurs]. | - wysłać widok [formulaire] wstępnie wypełniony najnowszymi wprowadzonymi wartościami |
Mamy zatem nową akcję do przetworzenia: [POST /personne3/main] z przesłanym parametrem [action=retourFormulaire], która zastępuje poprzednią akcję [GET /personne3/main?action=retourFormulaire].
7.6.1. Szkielet kontrolera
Szkielet kontrolera [ServletPersonne] jest identyczny jak w poprzedniej wersji.
Nowości:
- w wierszu 11 tablica [paramètres] nie zawiera już parametru [urlControleur], który został usunięty z pliku [web.xml].
Metody [init, doValidationFormulaire] pozostają bez zmian. Metody [doGet, doInit, doRetourFormulaire] ulegają niewielkim zmianom.
7.6.2. Metoda [doGet]
Metoda [doGet] musi przetwarzać akcję [POST /personne3/main] z przesłanym parametrem [action=retourFormulaire]:
- wiersze 6–9: przetwarzanie akcji [POST /personne3/main] z przesłanym parametrem [action=retourFormulaire]
7.6.3. Metoda [doInit]
Metoda ta przetwarza żądanie nr 1 [GET /personne3/main]. Jej kod jest następujący:
Nowością jest to, że widok [formulaire] wyświetlany w wierszu 8 nie zawiera już elementu [action] w swoim szablonie.
7.6.4. Metoda [doRetourFormulaire]
Metoda ta przetwarza zapytanie nr 1 [POST /personne3/main], w którym wśród wysłanych elementów znajduje się [action=retourFormulaire]. Jej kod jest następujący:
Nowością jest to, że widok [formulaire] wyświetlany w wierszu 14 nie zawiera już elementu [action] w swoim szablonie.
7.7. Tests
Uruchom lub ponownie uruchom Tomcat po dodaniu do niego projektu Eclipse [personne-mvc-03]. Wprowadź adres URL [http://localhost:8080/personne3], a następnie powtórz testy przedstawione jako przykład w paragrafie 7.1.















