10. Веб-додаток MVC [personne] — версія 5
10.1. Introduction
У цій версії ми внесли дві зміни:
Перша стосується способу, яким клієнт повідомляє серверу про дію, яку він бажає виконати. Дотепер це вказувалося за допомогою параметра під назвою [action] у запиті GET або POST від клієнта. У цьому випадку дія буде вказана останнім елементом URL-адреси, яку запитує клієнт, як показано в наступній послідовності:

У [1] URL-адреса, на яку було відправлено форму, — це [/personne5/do/validationFormulaire]. Саме останній елемент URL-адреси — [validationFormulaire] — дозволив контролеру розпізнати дію, яку потрібно виконати. У [2] POST, викликаний посиланням [Retour au formulaire], було виконано за URL-адресою [/personne5/do/retourFormulaire]. І знову останній елемент URL-адреси [retourFormulaire] вказує контролеру, яку дію потрібно виконати.
Ми вносимо цю зміну, оскільки саме такий підхід використовується в найпоширеніших фреймворках для веб-розробки, таких як Struts або Spring MVC.
Усі URL-адреси додатка матимуть вигляд [/personne5/do/action]. Файл [web.xml] додатка [/personne5] вказуватиме, що цей додаток підтримує URL-адреси у форматі [/do/*]:
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
Контролер отримає назву дії, яку потрібно виконати, таким чином:
Метод [getPathInfo] об’єкта [request] повертає останній елемент URL-адреси запиту.
Друга зміна стосується способу збереження даних, введених користувачем між двома циклами запит/відповідь. Наразі ця інформація зберігається в сесії. Такий підхід може мати недоліки, якщо користувачів багато, а даних, які потрібно зберегти для кожного з них, також багато. Адже кожен користувач має свою особисту сесію. Крім того, сесія залишається активною певний час після виходу користувача, якщо тільки не передбачено опцію виходу з системи. Таким чином, 1000 сесій по 1000 байтів займуть 1 МБ пам’яті. Це все ще помірна вимога, і мало які додатки мають 1000 активних сесій одночасно.
Проте існують альтернативи сеансам, які вимагають менше пам’яті, і про них варто знати. Тут ми використаємо метод файлів cookie. Проілюструємо це на прикладі.
Крок 1: користувач підтверджує форму:
![]() |
Цей цикл запит/відповідь призводить до таких обмінів HTTP між клієнтом і сервером:
[1] : [demande du client]
Це класичний POST. Тут немає нічого особливого, крім того, що, хоча сесія не використовується, веб-сервер все одно її створює. Про це свідчить токен сесії, який браузер відправляє серверу в рядку 11 і який він раніше отримав від сервера.
[2] : [réponse du serveur]
Бачимо, що в рядках 3 і 4 заголовки HTTP та [Set-Cookie] були надіслані до клієнтського браузера: один — для імені (рядок 3), а інший — для віку (рядок 4). Значення цих файлів cookie відповідають значенням, відправленим у рядку 14 вищезазначених POST та [1].
Крок 2: Повернення до форми

Цей цикл запит/відповідь призводить до наступного обміну даними HTTP між клієнтом і сервером:
[1] : [demande du client]
Тут ми бачимо POST, викликаний кліком на посилання [Retour au formulaire]. У рядку 11 ми бачимо, що браузер повертає серверу отримані ним файли cookie [nom, age, JSESSIONID] за допомогою заголовка Http [Cookie]. У цьому полягає принцип роботи файлів cookie. Клієнт повертає серверу файли cookie, які той йому надіслав. У цьому прикладі контролер отримає значення [pauline, 18], які він повинен розмістити в полях [txtNom, txtAge] подання [formulaire], що відображається в [2].
[2] : [réponse du serveur]
Тут немає нічого особливого, крім того, що в цій відповіді сервер не надіслав файлів cookie. Це не завадить браузеру під час наступного обміну надіслати всі файли cookie, які він отримав від сервера, навіть якщо це не має сенсу. Таким чином, ми зменшуємо навантаження на доступну пам'ять сервера ціною збільшення потоку символів під час обміну даними між клієнтом і сервером.
10.2. Проєкт Eclipse
Щоб створити проект Eclipse [mvc-personne-05] для веб-додатку [/personne5], потрібно продублювати проект [mvc-personne-04], дотримуючись процедури, описаної в розділі 6.2.
![]() | ![]() |
10.3. Налаштування веб-додатку [personne5]
Файл web.xml додатка /personne5 має такий вигляд:
<?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-05</display-name>
<!-- ServletPersonne -->
<servlet>
<servlet-name>personne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletPersonne
</servlet-class>
...
</servlet>
<!-- Маппінг ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
<!-- файли-шаблони -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Цей файл ідентичний файлу попередньої версії, за винятком кількох деталей:
- рядок 6: ім’я для відображення веб-додатка змінилося на [mvc-personne-05]
- рядок 18: URL-адреси, що обробляються додатком, мають вигляд [/do/*]. Раніше оброблялася лише URL-адреса [/main]. Тепер кількість URL-адрес дорівнює кількості дій, що підлягають обробці.
Головна сторінка [index.jsp] змінюється:
<%@ 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="/do/formulaire"/>
- рядок 5: сторінка [index.jsp] перенаправляє клієнта на URL-адресу [/personne5/do/formulaire], що еквівалентно запиту до контролера виконати дію [formulaire].
10.4. Код переглядів
Види [formulaire, réponse, erreurs] майже не змінюються. Єдина зміна полягає в тому, що дія, яку потрібно виконати, більше не вказується так, як раніше, коли вона визначалася у прихованому полі з назвою [action] у відправлених формах. Тепер вона визначається в цільовому URL-адресі відправлених форм, c.a.d, в атрибуті [action] тегу <form>:
[formulaire.jsp]:
...
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
...
</script>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form name="frmPersonne" action="validationFormulaire" method="post">
...
</form>
</center>
</body>
</html>
- рядок [13]: параметр [action] форми знову з’являється після того, як на деякий час зник у попередніх версіях. Щоб зрозуміти значення цього атрибута в даному випадку, слід пам’ятати, що всі URL-адреси, які обробляє додаток, мають вигляд [/do/action]. У рядку [13] атрибут [action] має значення відносного URL-адреси (що не починається з /). Тому браузер доповнить її URL-адресою поточної сторінки, тобто обов’язково URL-адресою у форматі [/do/action]. Останній елемент буде замінено на відносний URL-адресу атрибута [action] тегу <form>, щоб отримати URL-адресу [/do/validationFormulaire] як ціль для POST.
- Приховане поле [action] зникло
[réponse.jsp]:
...
<html>
...
<body>
...
<form name="frmPersonne" action="retourFormulaire" method="post">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
- рядок [7]: ціллю POST стане [/do/retourFormulaire]
- приховане поле [action] зникло у формі рядків 7–8.
[erreurs.jsp]:
...
<html>
...
<body>
...
<form name="frmPersonne" action="retourFormulaire" method="post">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
- рядок [6]: цільовим елементом для POST стане [/do/retourFormulaire]
- приховане поле [action] зникло у формі рядків 6–7.
Читачеві пропонується протестувати ці нові подання за принципом, розглянутим у попередніх версіях.
10.5. Контролер [ServletPersonne]
Контролер [ServletPersonne] веб-додатку [/personne5] оброблятиме такі дії:
№ | запит | джерело | обробка |
1 | [GET /personne5/do/formulaire] | URL-адреса, введена користувачем | - надіслати порожній вигляд [formulaire] |
2 | [POST /personne5/do/validationFormulaire] з параметрами [txtNom, txtAge] , опублікованих | натискання на кнопку [Envoyer] у вікні [formulaire] | - перевірити значення параметрів [txtNom, txtAge] - якщо вони неправильні, надіслати вигляд [erreurs(erreurs)] - якщо вони правильні, надіслати вигляд [reponse(nom,age)] |
3 | [POST /personne5/do/retourFormulaire] без переданих параметрів | натисніть на посилання [Повернутися до формуляр] переглядів [réponse] та [erreurs]. | - надіслати попередньо заповнений вигляд [formulaire] з останніми введеними значеннями |
Структура контролера [ServletPersonne] ідентична структурі попередньої версії. Ми розглянемо зміни, внесені до методів [doValidationFormulaire, doRetourFormulaire, doGet], оскільки методи [init, doInit, doPost] не зазнали змін.
10.5.1. Метод [doGet]
Метод [doGet] не отримує дію, яку потрібно виконати, так само, як у попередніх версіях:
- рядок 12: отримується дія, яку потрібно виконати. Вона має вигляд [/action].
- рядки 18–22: обробка дії [/formulaire], запитаної у запиті GET
- рядки 23–27: обробка дії [/validationFormulaire], запитаної запитом POST
- рядки 28–32: обробка дії [/retourFormulaire], ініційованої запитом POST
10.5.2. Метод [doValidationFormulaire]
Цей метод обробляє запит № 2 [POST /personne5/do/validationFormulaire] разом із [txtNom, txtAge] у відправлених елементах. Його код такий:
Нові можливості:
- метод [doValidationFormulaire] у відповідь надсилає один із видів [réponse, erreurs]. Незалежно від змісту цієї відповіді, контролер додає до неї два файли cookie (рядки 8–9). Файл cookie представлений об’єктом [Cookie], конструктор якого приймає два параметри: ключ файлу cookie та значення, пов’язане з ним.
- рядок 8: значення, введене для імені, записується у файл cookie з ключем «nom»
- рядок 9: значення, введене для поля «вік», записується у файл cookie з ключем «age»
- файл cookie додається до відповіді HTTP, що надсилається клієнту за допомогою методу [response.addCookie]. Ця відповідь тут лише готується. Фактично вона буде надіслана лише під час виконання сторінки JSP з подання, надісланого клієнту.
10.5.3. Метод [doRetourFormulaire]
Цей метод обробляє запит № 2 [POST /personne5/do/retourFormulaire] без переданих елементів. Його код такий:
Нові можливості:
Метод [doRetourFormulaire] повинен відображати попередньо заповнену форму з останніми введеними даними. У попередній версії ці дані зберігалися в сесії. У цій версії для збереження даних між двома обмінами між клієнтом і сервером більше не використовується сесія, а використовуються файли cookie. Коли клієнт надіслав запит на підтвердження форми, він отримав у відповідь сторінку [réponse] або [erreurs] (залежно від випадку) разом із двома файлами cookie з іменами «nom» та «age». При натисканні на посилання [Retour au formulaire] у цих двох сторінках, що викликає перехід на сторінку POST за URL-адресою [/do/retourFormulaire], браузер відправляє серверу обидва отримані файли cookie.
- рядки 4–18: отримуємо значення файлів cookie з іменами «nom» та «age». Досить дивно, але не існує методу, який би дозволяв отримати значення файлу cookie на основі його ключа. Тому доводиться переглядати кожен із отриманих файлів cookie.
- Після цього обидва отримані значення поміщаються в шаблон подання [formulaire] (рядки 20–21), щоб він їх відобразив.
10.6. Tests
Запустіть або перезапустіть Tomcat після інтеграції в нього проекту Eclipse [personne-mvc-05], а потім введіть URL-адресу [http://localhost:8080/personne5].


