7. Веб-додаток MVC [personne] — версія 3
Рекомендовані матеріали в [ref1]: розділ 9
7.1. Introduction
Ми пропонуємо додати код JavaScript на сторінки HTML, що надсилаються до браузера. Саме браузер виконує код JavaScript, вбудований у сторінку, яку він відображає. Ця технологія не залежить від тієї, яку використовує веб-сервер для генерації документа HTML (Java/сервлети/JSP, ASP.NET, ASP, PHP, Perl, Python тощо).
[formulaire.jsp]
Вигляд, отриманий з цієї сторінки, буде таким:

Кнопки, написи на яких виділені рамкою, використовують код JavaScript, вбудований у сторінку HTML:
Назва | Тип HTML | Функція |
<submit> | виконує роль кнопки [Envoyer] з попередніх версій: надсилає введені значення до контролера | |
<button> | нова кнопка — локально перевіряє правильність введених даних перед їх надсиланням до контролера | |
<reset> | відновлює форму до того стану, в якому вона була спочатку отримана браузером | |
<button> | очищає вміст обох полів введення |
Ось приклад використання кнопок [Envoyer] та [Effacer]:
![]() | ![]() |
![]() | ![]() |
Ми також будемо використовувати код JavaScript для управління посиланням [Retour au formulaire] у поданнях [erreurs] та [réponse]. Розглянемо приклад подання [réponse]:
![]() | 1 ![]() |
Різниця полягає в URL-адресі, що відображається у [1]. У попередній версії вона була такою:
Тут дія більше не входить до складу URL-адреси, оскільки вона буде надіслана за допомогою POST замість GET. Ця зміна призведе до того, що єдиним URL-адресою, яка відображатиметься у браузері, буде [http://localhost:8080/personne3/main] незалежно від запитуваної дії.
7.2. Проєкт Eclipse
Щоб створити проект Eclipse [mvc-personne-03] для веб-додатка [/personne3], потрібно продублювати проект [mvc-personne-02], дотримуючись процедури, описаної в розділі 6.2 на сторінці 78.
![]() | ![]() |
7.3. Налаштування веб-додатку [personne3]
Файл web.xml додатка /personne3 має такий вигляд:
<?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>
<!-- Мапування ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
<!-- файли-шаблони -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Цей файл ідентичний файлу попередньої версії, за винятком кількох деталей:
- рядок 6: ім’я для відображення веб-додатку змінилося на [mvc-personne-03]
Параметр [urlControleur] зник. У попередній версії він використовувався для визначення цільового об’єкта POST для подання [formulaire]. У цій новій версії цільовим об’єктом буде порожній рядок — c.a.d. URL-адреса, що відображається браузером. Ми пояснили, що вона завжди буде [http://localhost:8080/personne3/main] — саме та, яка нам потрібна для POST у поданні [formulaire].
Головна сторінка [index.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">
<%
response.sendRedirect("/personne3/main");
%>
- рядок 5: сторінка [index.jsp] перенаправляє клієнта на URL-адресу контролера [ServletPersonne] додатка [/personne3].
7.4. Код подання
7.4.1. Вигляд [formulaire]
Цей вигляд тепер виглядає так:

Вона генерується наступною сторінкою 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">
<%// витягуються дані з шаблону
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
// -------------------------------
function effacer(){
// очищення полів введення
with(document.frmPersonne){
txtNom.value="";
txtAge.value="";
}//з
}//очищення
// -------------------------------
function envoyer(){
// перевірка параметрів перед відправкою
with(document.frmPersonne){
// ім'я не повинно бути порожнім
champs=/^\s*$/.exec(txtNom.value);
if(champs!=null){
// ім'я порожнє
alert("Vous devez indiquer un nom");
txtNom.value="";
txtNom.focus();
// повернення до графічного інтерфейсу
return;
}//if
// вік має бути додатним цілим числом
champs=/^\s*\d+\s*$/.exec(txtAge.value);
if(champs==null){
// вік вказано неправильно
alert("Age incorrect");
txtAge.focus();
// повернутися до візуального інтерфейсу
return;
}//if
// параметри правильні — надсилаємо їх на сервер
submit();
}//with
}//надіслати
</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>
Зміни:
- рядок 56: форма має ім’я [frmPersonne]. Це ім’я буде використовуватися в коді JavaScript. Зверніть увагу на відсутність атрибута [action], завдяки чому форма [frmPersonne] буде відправлена на URL-адресу, що відображається браузером.
- рядок 70: кнопка [Submit] виконує роль кнопки [Envoyer] з попередніх версій
- рядок 71: натискання кнопки [Envoyer] типу [Button] запускає виконання функції JavaScript [envoyer], визначеної в рядку 24
- рядок 72: функція кнопки [Rétablir] не змінилася
- рядок 73: натискання кнопки [Effacer] типу [Button] запускає функцію JavaScript [effacer], визначену в рядку 16
Перш ніж коментувати код JavaScript, нагадаємо деякі позначення:
JavaScript обробляє відображену сторінку та її вміст як дерево об’єктів, коренем якого є об’єкт [document]. У цьому документі може бути одна або кілька форм. [document.frmPersonne] позначає форму з іменем [frmPersonne], визначену в рядку 56. Ця форма також містить об’єкти. До них належать поля введення даних. Так, [document.frmPersonne.txtNom] позначає об’єкт зображення поля введення даних HTML, визначеного в рядку 60. Об’єкт [txtNom] має різні властивості, серед яких властивість [value], що позначає вміст поля введення. Таким чином, [document.frmPersonne.txtNom.value] позначає вміст поля введення [txtNom].
- рядки 16–22: функція JavaScript [effacer] вставляє порожній рядок у поля введення [txtNom, txtAge].
- рядки 24–49: функція JavaScript [envoyer] перевіряє правильність значень полів введення [txtNom, txtAge] перед їх відправкою. Для цього вона використовує регулярні вирази.
- рядок 28: перевіряє, чи значення поля введення [txtNom] відповідає шаблону /s*, що означає 0 або більше пробілів. Якщо відповідь «так», це означає, що користувач не вказав ім’я. Якщо є збіг із шаблоном, змінна champs матиме значення, відмінне від покажчика null; в іншому випадку вона матиме значення null.
- рядок 29: якщо є збіг із шаблоном
- рядок 30: відображається повідомлення для користувача
- рядок 32: у поле [txtNom] вноситься порожній рядок (там міг бути ряд пробілів)
- рядок 33: курсор, що блимає, встановлюється на полі [txtNom]
- рядок 34: функція переривається. У такому разі на сервер не надсилаються введені значення для поля POST.
- рядки 38–45: аналогічна процедура виконується з полем [txtAge]
- рядок 47: якщо ми дійшли до цього місця, це означає, що введені значення правильні. Тоді ми відправляємо (submit) форму [frmPersonne] на веб-сервер. Далі все відбувається так, ніби ми натиснули кнопку з написом [Submit].
7.4.2. Вигляд [reponse]
Цей вигляд відображає значення, введені у форму, якщо вони є правильними:
![]() | ![]() |
На відміну від попередньої версії, нововведення з’являється лише тоді, коли використовується посилання [Retour au formulaire] з вікна [réponse]:
![]() | ![]() |
Різниця полягає в URL-адресі, що відображається в [1]. У попередній версії вона була такою:
Тут дія більше не входить до складу URL-адреси, оскільки вона буде надіслана за допомогою POST замість GET. Нова сторінка JSP [reponse.jsp] — це lqqqaaaaaaaaaqqAAAaaa
така:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// отримуємо дані з моделі
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>
Нові зміни:
- рядки 35–37: посилання [Retour au formulaire] містить JavaScript. Клік на це посилання викликає виконання JavaScript-коду з атрибута [href]. Як ми бачили під час розгляду [formulaire.jsp], ми знаємо, що цей код відправляє значення полів типу <input>, <select> тощо з форми [frmPersonne].
- рядки 32–34: визначають форму [frmPersonne]. Вона має лише одне поле типу <input type="hidden" ...>, тобто приховане поле. Це поле [action] слугує для передачі контролеру назви дії, яку потрібно виконати, у даному випадку [retourFormulaire].
7.4.3. Вигляд [erreurs]
Цей вигляд повідомляє про помилки введення даних у формі. Зміни, внесені до нього, такі самі, як і для виду [réponse]:
![]() | ![]() |
Відмінність полягає в URL-адресі, що відображається у [1]. У попередній версії вона була такою:
Тут дія більше не входить до складу URL-адреси, оскільки вона буде надіслана за допомогою POST замість GET. Наступна нова сторінка JSP [reponse.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">
<%@ page import="java.util.ArrayList" %>
<%
// отримуємо дані з моделі
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");
}//для
%>
</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>
Нововведення:
- рядки 30–32: нове оброблення кліка на посилання. Пояснення з цього приводу, наведені в дослідженні [réponse.jsp], дійсні також і тут.
7.5. Тестування переглядів
Щоб провести тестування попередніх видів, ми дублюємо їхні сторінки JSP у папці /WebContent/JSP проекту Eclipse:

Потім у папці JSP сторінки змінюються наступним чином:
[formulaire.jsp]:
...
<%
// -- тест: створюємо шаблон сторінки
session.setAttribute("nom","tintin");
session.setAttribute("age","30");
%>
<%// отримуємо дані з шаблону
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
Рядки 4–5 було додано для створення шаблону, необхідного для сторінки, рядки 9–10.
[reponse.jsp]:
...
<%
// -- тест: створюємо шаблон сторінки
request.setAttribute("nom","milou");
request.setAttribute("age","10");
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// отримуємо дані з шаблону
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
...
Рядки 4–6 було додано для створення шаблону, необхідного для сторінки рядків 11–13.
[erreurs.jsp]:
<%
// -- тест: створюємо шаблон сторінки
ArrayList<String> erreurs1=new ArrayList<String>();
erreurs1.add("erreur1");
erreurs1.add("erreur2");
request.setAttribute("erreurs",erreurs1);
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// отримуємо дані з шаблону
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
Рядки 4–8 було додано для створення шаблону, необхідного для сторінки, що міститься в рядках 13–14.
Запустіть Tomcat, якщо це ще не зроблено, а потім завантажте такі URL-адреси:
![]() | ![]() |
![]() |
Ми отримуємо саме ті результати, на які розраховували.
7.6. Контролер [ServletPersonne]
Контролер [ServletPersonne] веб-додатку [/personne3] оброблятиме такі дії:
№ | запит | джерело | обробка |
1 | [GET /personne3/main] | URL-адреса, введена користувачем | - надіслати порожній вигляд [formulaire] |
2 | [POST /personne3/main] з параметрами [txtNom, txtAge, action=validationFormulaire] опубліковані | натискання на кнопку [Envoyer] у вікні [formulaire] | - перевірити значення параметрів [txtNom, txtAge] - якщо вони неправильні, надіслати вигляд [erreurs(erreurs)] - якщо вони правильні, надіслати вигляд [reponse(nom,age)] |
3 | [POST /personne3/main] з параметрами [action=retourFormulaire] натиснути | натисніть на посилання [Повернутися до форму] переглядів [réponse] та [erreurs]. | - надіслати попередньо заповнений вигляд [formulaire] з останніми введеними значеннями |
Отже, у нас з’явилася нова дія, яку потрібно обробити: [POST /personne3/main] із переданим параметром [action=retourFormulaire] замість попередньої дії [GET /personne3/main?action=retourFormulaire].
7.6.1. Скелет контролера
Скелет контролера [ServletPersonne] ідентичний скелету попередньої версії.
Нововведення:
- у рядку 11 масив [paramètres] більше не містить параметра [urlControleur], який було видалено з файлу [web.xml].
Методи [init, doValidationFormulaire] залишилися без змін. Методи [doGet, doInit, doRetourFormulaire] дещо змінилися.
7.6.2. Метод [doGet]
Метод [doGet] повинен обробляти дію [POST /personne3/main] із переданим параметром [action=retourFormulaire]:
- рядки 6–9: обробка дії [POST /personne3/main] із переданим параметром [action=retourFormulaire]
7.6.3. Метод [doInit]
Цей метод обробляє запит № 1 [GET /personne3/main]. Його код такий:
Нововведення полягає в тому, що у поданні [formulaire], яке відображається у рядку 8, у моделі більше немає елемента [action].
7.6.4. Метод [doRetourFormulaire]
Цей метод обробляє запит № 1 [POST /personne3/main] із [action=retourFormulaire] у відправлених елементах. Його код такий:
Нововведення полягає в тому, що у поданні [formulaire], яке відображається у рядку 14, у моделі більше немає елемента [action].
7.7. Tests
Запустіть або перезапустіть Tomcat після інтеграції в нього проекту Eclipse [personne-mvc-03]. Запитайте URL-адресу [http://localhost:8080/personne3], а потім повторіть тести, наведені як приклад у розділі 7.1.















