6. Форми HTML
До цього моменту ми використовували єдину форму, що містила лише два поля введення. Тут ми пропонуємо створити та обробити форму, використовуючи звичайні графічні компоненти (перемикачі, прапорці, поля введення, комбіновані списки, списки).
6.1. Види додатка
Додаток матиме лише два види. Перший відображає порожню форму:
QZXW2HTMLP000547ZQX 1 - formulaire

Цей перший вигляд, який називається formulaire.jsp, дозволить нам реалізувати різні теги з бібліотеки struts-html. Користувач заповнює форму:

Кнопка [Envoyer] дозволяє отримати підтвердження введених значень. Це буде другий екран:

Цей другий вигляд дозволить нам використовувати ще дві бібліотеки тегів — struts-bean та struts-logic. Посилання [Retour au formulaire] дозволяє повернутися до форми в тому вигляді, в якому її було заповнено. Ми знову потрапляємо на перший вигляд.
6.2. Архітектура додатка
![]() |
- Форма (представлення 1) буде представлена динамічним об’єктом Struts під назвою dynaFormulaire, тип якого походить від DynaActionForm. Вона відображатиметься за допомогою представлення formulaire.jsp.
- Дія Struts InitFormulaireAction призначена для отримання даних, необхідних для відображення форми
- заповнена форма буде оброблена дією ForwardAction, яка лише перенаправить запит до другого виду confirmation.jsp. Цей вид відповідатиме за відображення значень форми.
6.3. Налаштування додатка
6.3.1. Файл server.xml
Контекст додатка матиме назву /formulaire2. Тому до файлу server.xml у Tomcat додамо такий рядок:
Після цього, за необхідності, перезапустимо Tomcat, щоб він врахував новий контекст. Ми можемо перевірити його правильність, звернувшись до URL http://localhost:8080/formulaire2 :

6.3.2. Файл web.xml
Файл конфігурації web.xml додатка матиме такий вигляд:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
Щодо конфігураційних файлів web.xml, з якими ми вже стикалися, ми вносимо кілька змін:
- ми додаємо дві нові бібліотеки тегів — struts-bean та struts-logic. Вони будуть використовуватися у подачі confirmation.jsp. Подача formulaire.jsp, у свою чергу, використовуватиме бібліотеку struts-html.
6.3.3. Файл struts-config.xml
Файл struts-config.xml матиме такий вигляд:
<?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>
<form-beans>
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
</form-beans>
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
<message-resources
parameter="ApplicationResources"
null="false"/>
</struts-config>
Тут містяться три основні розділи:
- опис форм у розділі <form-beans>
- описання дій у розділі <action-mappings>
- описання файлу ресурсів у розділі <message-ressources>
6.3.4. Об’єкти (біни) форм додатка
Об’єкти, що використовуються для представлення форм HTML у додатку, є об’єктами типу ActionForm або його похідними (DynaActionForm, DynaValidatorForm, ...). Їх називають «бінами», оскільки їхня побудова відповідає правилам JavaBeans. У нашому додатку є лише один «бін» форми, який називається dynaFormulaire і є похідним від типу DynaActionForm. Він використовуватиметься в таких ситуаціях:
- для зберігання даних, необхідних для відображення подання № 1
- отримувати значення з форми виду № 1, коли користувач підтвердить її (submit)
- містити дані, необхідні для відображення виду № 2
Структура біна dynaFormulaire тісно пов’язана з формою подання № 1. Розглянемо її:
![]() |
№ | Тип HTML | Роль |
<input name="opt" type="radio" value="так"> <input name="opt" type="radio" value="ні"> | група пов'язаних між собою перемикачів (однакова назва) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | групи прапорців (не однакові назви) | |
<input type="text" name="champSaisie" > | поле введення | |
<input type="password " name="mdp" > | поле для введення пароля | |
<textarea name="boiteSaisie">...</textarea> | поле для введення тексту з кількома рядками | |
<select name="combo" size="1">..</select> | список | |
<select name="listeSimple" size="3">..</select> | список з одним варіантом вибору | |
<select name="listeMultiple" size="3" multiple>..</select> | список із можливістю вибору декількох елементів | |
<input type="button" value="Очистити" onclick='effacerListe("listeSimple")'> | кнопка для скасування вибору вибрані елементи в listeSimple (7) | |
<input type="button" value="Очистити" onclick='effacerListe("listeMultiple")'> | кнопка, що дозволяє скасувати вибір вибраних елементів у listeMultiple (8) | |
<input type="submit" value="Надіслати"> | кнопка відправки форми | |
<input type="hidden" name="secret" value="..."> | приховане поле |
Розрізнимо кілька випадків:
- об'єкт dynaFormulaire використовується для зберігання значень форми HTML, наведеної вище, яка буде відправлена за допомогою кнопки [Envoyer]. Тому він повинен мати ті самі поля, що й у формі HTML. Тип поля визначається за таким правилом:
- якщо поле HTML надає лише одне значення, то поле dynaFormulaire матиме тип java.lang.String
- якщо поле HTML містить кілька значень, то поле dynaFormulaire матиме тип java.lang.String[]
У наведеному вище бланку HTML лише поле listeMultiple може бути пов’язане з кількома значеннями (вибраними користувачем). Отже, перше визначення об’єкта dynaFormulaire буде таким:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
</form-bean>
Як відбуватиметься заповнення поля dynaFormulaire значеннями з форми HTML, надісланими веб-клієнтом?
поле opt отримає значення «так», якщо було позначено поле HTML <input type="radio" name="opt" value="так">, і значення «ні», якщо було позначено поле <input type="radio" name="opt" value="ні">. | |
поле chk1 отримає значення «on», якщо було позначено поле HTML <input name="chk1" type="radio" value="1">, інакше — ні. В останньому випадку поле chk1 збереже своє попереднє значення. | |
те саме | |
те саме | |
поле champSaisie отримає текст, введений користувачем у полі HTML <input type="text" name="champSaisie">. Цей текст може бути порожнім рядком. | |
поле mdp отримає текст, введений користувачем у полі HTML <input type="password" name="mdp">. Цей текст може бути порожнім. | |
У поле boiteSaisie буде введено текст, який користувач ввів у поле HTML <textarea name="boiteSaisie">...</textarea>. Цей текст утворює єдиний рядок, що складається з рядків, введених користувачем, розділених між собою послідовністю символів «\r\n». Отриманий текст може бути порожнім рядком. | |
поле комбінованого списку отримає опцію, вибрану користувачем у полі HTML <select name="combo" size="1">..</select>. Вибраною вважається та опція, яка відображається у комбінованому списку. Якщо вибраний варіант HTML має тип <option value="XX">YY</option>, поле комбінованого списку отримає значення «XX». Якщо вибрана опція HTML має тип <option>YY</option>, поле зі списком отримає значення «YY». | |
поле listeSimple отримає опцію, обрану користувачем у полі HTML <select name="listeSimple" size="..">..</select>, якщо така є. Якщо її немає, поле listeSimple не отримає жодного значення і збереже своє попереднє значення. Значення, яке фактично присвоюється полю listeSimple, відповідає правилам, зазначеним для комбінованого списку. | |
поле listeMultiple типу String[] отримає опції, вибрані користувачем у полі HTML <select name="listeMultiple" size=".." multiple>..</select>, якщо такі є. Якщо їх немає, масив listeMultiple не отримає жодного значення, і його вміст залишиться незмінним. Значення, що фактично присвоюються масиву listeMultiple, відповідають правилам, зазначеним для комбінованого списку. | |
поле secret отримає значення XX з поля HTML <input type="hidden" name="secret" value="XX">. Цей текст може бути порожнім рядком. |
- Об’єкт dynaFormulaire використовується для надання початкового вмісту подання № 1. Значення попередніх полів будуть використовуватися для таких цілей:
повинен мати значення «так» або «ні», щоб браузер знав, яку опцію потрібно вибрати | |
якщо chk1 має значення «on», то поле буде позначено, інакше — ні | |
те саме | |
те саме | |
значення поля буде відображено в полі введення champSaisie | |
значення поля буде відображено в полі введення пароля | |
значення поля буде відображено в полі введення boiteSaisie | |
значення цього поля вказує, який елемент комбінованого списку має бути вибраний під час відображення форми | |
те саме | |
значення таблиці listeMultiple вказують, які елементи списку з кількома варіантами мають бути вибрані під час відображення форми | |
значення поля буде присвоєно атрибуту value поля HTML secret. |
Вид № 1 потребує додаткової інформації:
- список значень, які потрібно відобразити у комбінованому списку
- список значень, які потрібно відобразити у списку listeSimple
- список значень, які потрібно відобразити у списку listeMultiple
Існує кілька способів передати цю інформацію до подання. Наприклад, для цього підійдуть масиви, розміщені у запиті, що передається до подання. У цьому випадку ми розміщуємо ці масиви у біні dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Форма dynaFormulaire буде ініціалізована дією /init, яка викличе об’єкт, похідний від Action, під назвою InitFormulaireAction. Саме цей об’єкт буде відповідати за створення трьох масивів, необхідних для відображення трьох списків, та їх розміщення у біні dynaFormulaire. Файл конфігурації надає цьому bean-у область дії, що дорівнює сесії. Це означає, що контролер Struts розмістить цей bean у сесії. Таким чином, нам не доведеться його перегенерувати між двома циклами «запит-відповідь». Отже, дія /init буде викликана лише один раз.
- Об’єкт dynaFormulaire також використовується для надання вмісту подання № 2. Воно лише відображає його значення.
6.3.5. Дії додатка
Дії виконуються об’єктами типу Action або його похідними. Налаштування дій здійснюється всередині тегів <action-mappings>:
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
Зауважимо, що не завжди до дії прив’язана форма. Це стосується, зокрема, дії /affiche, наведеної вище. Перш ніж детально розглянути кожну дію, нагадаємо, як працює пара «дія-форма» у тезі <action>:
- дія починається із запиту від веб-клієнта і завершується відправленням сторінки-відповіді. Це цикл «запит-відповідь» між веб-клієнтом і веб-сервером. Запит приймається контролером Struts типу ActionServlet або його похідним. Цей самий контролер і відправляє відповідь.
- біан форми типу ActionForm або його похідного створюється, якщо його ще не існує. Контролер перевіряє, чи може він знайти об’єкт з іменем name у області дії, вказаній атрибутом scope. Якщо так, він використовує його. Якщо ні, він створює його та розміщує в області дії, вказаній атрибутом scope, пов’язавши з атрибутом, вказаним атрибутом name.
Наприклад, у випадку дії /init контролер виконає виклик request.getSession().getAttribute("dynaFormulaire"), щоб перевірити, чи об’єкт dynaFormulaire вже створено. Якщо це не так, він створить його та додасть до сесії за допомогою інструкції на кшталт request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- Контролер також шукатиме об’єкт Action типу, вказаного атрибутом type. Якщо він його не знайде, то створить його, інакше — використає.
- Буде викликано метод reset біна форми. Цей бін, за винятком моменту його початкового створення, піддається рециркуляції. Отже, він містить дані, які, можливо, потрібно «очистити». Це робиться в методі reset біна ActionForm або його похідного.
- якщо дія є ціллю відправленої форми, то значення форми, що містяться у запиті клієнта, копіюються в поля з відповідними іменами у біні форми. Слід зауважити, що перед цим копіюванням було викликано метод reset.
- Якщо в конфігурації вказано атрибут `validate="true"`, буде викликано метод `validate` біна форми. Цей метод повинен перевірити дані біна. Така перевірка найчастіше відбувається лише тоді, коли форма щойно отримала нові дані через відправлену форму і потрібно перевірити їхню правильність. Цей метод повертає контролеру можливий список помилок у об’єкті ActionErrors.
- Якщо об’єкт ActionErrors не порожній, контролер відображає представлення, вказане атрибутом input дії.
- якщо перевірка даних не вимагається або якщо вона пройшла успішно, контролер запускає метод execute об’єкта типу Action або його похідного, пов’язаного з поточною дією. Саме в цьому методі обробляється запит веб-клієнта. Метод execute повертає об’єкт ActionForward, індексований ключами типу символьного рядка. Ці ключі — це ті, що оголошені тегами forward налаштованої дії. У нашому прикладі дія /init має лише один тег forward. Він пов’язує ключ «afficherFormulaire» із видом formulaire.jsp.
- контролер відображає вигляд, якому відповідає отриманий ключ. Цей вигляд може бути, власне, дією, і в цьому випадку попередній процес повторюється.
Дія /init
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
- Дія /init зазвичай виконується один раз під час першого циклу «запит-відповідь», коли користувач запитує URL http://localhost:8080/formulaire2/init.do
- об’єкт dynaFormulaire створюється або повторно використовується. Він підбирається (повторне використання) або розміщується (створення) у сесії відповідно до атрибута scope.
- Викликається його метод reset. Що він повинен зробити? Зазвичай поля об’єкта ActionForm скидаються до значень за замовчуванням. Однак у цьому випадку ми цього не зробимо, оскільки об’єкт dynaFormulaire розміщується в сесії (scope="session"). Отже, поля dynaFormulaire повинні зберегти свої значення. Якими є ці значення під час початкового створення об’єкта dynaFormulaire? Існують два випадки:
- поле має початкове значення, вказане у файлі конфігурації:
У цьому випадку контролер Struts створить це поле з цим початковим значенням.
- поле не має початкового значення за конфігурацією: застосовуються правила ініціалізації Java. Як правило, числові поля матимуть значення нуль, символьні рядки — порожній рядок, а інші об’єкти — значення null.
Розглянемо початкову конфігурацію dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Початкові значення полів dynaFormulaire після його створення будуть такими:
Поле | Початкове значення |
«ні» | |
порожній рядок | |
порожній рядок | |
порожній рядок | |
порожній рядок | |
порожній рядок | |
порожній рядок | |
масив порожніх рядків | |
"xxx" | |
масив порожніх рядків |
- можна уявити, що метод reset класу dynaFormulaire присвоює значення трьом масивам, які мають заповнювати три списки у поданні formulaire.jsp. Це було б можливо в даному випадку, оскільки дані цих трьох масивів генеруються довільним чином. Проте найчастіше ці дані походять із моделі додатка, тобто з M у MVC. Тут ми оберемо проміжний варіант, щоб не ускладнювати приклад, і згенеруємо ці значення за допомогою дії InitFormulaireAction, тобто за допомогою C з MVC.
- Немає обов’язку писати метод reset у dynaFormulaire, оскільки клас ActionForm, від якого він походить, має такий метод, який нічого не робить (не виконує ініціалізацій).
- Після виклику методу reset класу dynaFormulaire контролер перевіряє атрибут validate дії. У цьому випадку він має значення «false». Метод validate класу dynaFormulaire не буде викликаний.
- Об’єкт InitFormulaireAction створюється або переробляється, якщо він уже існував, і запускається його метод `execute`. Саме цей метод присвоїть довільні значення трьом масивам dynaFormulaire: valeursCombo, valeursListeSimple та valeursListeMultiple. Метод повертає ActionForward із ключем «afficherFormulaire».
- контролер відображає перегляд /vues/formulaire.jsp, який був пов’язаний із ключем «afficherFormulaire» за допомогою тегу forward дії /init.
Дія /confirmation
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- Дія /confirmation відбувається, коли користувач натискає кнопку [Envoyer] у вікні № 1. Після цього браузер «відправляє» контролеру Struts заповнену користувачем форму.
- Об’єкт dynaFormulaire береться із сесії
- викликається його метод reset. Після його виклику контролер Struts скопіює значення полів форми, надісланої клієнтом, у поля з такими самими іменами в об’єкті dynaFormulaire. Повернімося до списку полів цього об’єкта та розглянемо, як відбувається це копіювання:
Поле | Відповідний код HTML | Значення поля після копіювання значень з форми |
<input type="radio" name="opt" value="oui">Так <input type="radio" name="opt" value="no" checked="checked">Ні | - «так» або «ні» залежно від того, яка опція обрана | |
<input type="checkbox" name="chk1" value="on"> | - «on», якщо встановлено прапорець chk1 - зберігає попереднє значення, якщо поле chk1 не відмічено | |
<input type="checkbox" name="chk2" value="on"> | - «on», якщо поле chk2 було відмічено - зберігає попереднє значення, якщо поле chk2 не відмічено | |
<input type="checkbox" name="chk2" value="on"> | - «on», якщо поле chk3 було позначено - зберігає попереднє значення, якщо поле chk3 не відмічено | |
<input type="text" name="champSaisie" value=""> | - значення, введене користувачем у полі champSaisie | |
<input type="password" name="mdp" value=""> | - значення, введене користувачем у полі mdp | |
<textarea name="boiteSaisie"></textarea> | - значення, введене користувачем у поле boiteSaisie | |
<select name="combo">...</select> | - значення, вибране користувачем у combo | |
<select name="listeSimple" size="3">...</select> | - значення, вибране користувачем у listeSimple | |
<select name="listeMultiple" multiple="multiple" size="5"> | - масив рядків, що містить значення, вибрані користувачем у listeMultiple | |
<input type="hidden" name="secret" value="xxx"> | - «xxx». |
Виникає проблема з полями, які не завжди отримують значення у запиті, надісланому браузером. Це стосується прапорців chk1–chk3 та двох списків listeSimple і listeMultiple. У цьому випадку ці поля зберігають своє попереднє значення, отримане під час попереднього циклу запит-відповідь.
Розглянемо, наприклад, прапорець chk1 і припустимо, що в попередньому циклі «запит-відповідь» користувач встановив цей прапорець. Тоді браузер надіслав у рядку параметрів свого запиту інформацію chk1="on". Отже, розробник присвоїв значення «on» полю chk1 у dynaFormulaire. Тепер припустимо, що в поточному циклі користувач не встановлює прапорець chk1. У цьому випадку в рядку параметрів нового запиту браузер не надсилає щось на кшталт chk1="off", а не надсилає нічого. Як наслідок, поле chk1 у dynaFormulaire збереже значення «on» і, отже, матиме значення, яке не відповідає тому, що вказано у формі, підтвердженій користувачем. Для вирішення цієї проблеми ми використаємо метод reset у dynaFormulaire. У цьому методі ми встановимо для трьох полів chk1, chk2, chk3 значення «off». У нашому прикладі з chk1, якщо користувач:
- позначить прапорець chk1. У цьому випадку браузер надсилає інформацію chk1="on", і поле chk1 у dynaFormulaire перейде у стан «on»;
- не встановлює прапорець chk1. Тоді браузер не надсилає значення для поля chk1, яке збереже своє попереднє значення «off». В обох випадках значення, записане в полі chk1 dynaFormulaire, є правильним.
Проблема є аналогічною для обох списків listeSimple та listeMultiple. Якщо в цих списках не було обрано жодного параметра, вони не будуть присутні в параметрах запиту і, отже, збережуть свої попередні значення. У методі reset об’єкта dynaFormulaire ми скинемо значення listeSimple, присвоївши йому порожній рядок, а listeMultiple — масив рядків довжиною 0.
- Після виклику методу reset об’єкта dynaFormulaire контролер копіює в поля об’єкта dynaFormulaire інформацію, яка була надіслана йому у запиті клієнта
- Створюється або повторно використовується об’єкт ForwardAction, і викликається його метод `execute`. ForwardAction — це попередньо визначений клас, який повертає об’єкт ActionForward, що вказує на представлення, визначене атрибутом «parameter» дії, у даному випадку /vues/confirmation.jsp.
- Контролер відправляє цей вигляд. Цикл завершено.
Дія /affiche
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- Дія /affiche запускається при активації посилання [Retour vers le formulaire] у вікні № 2.
- Тут немає форми, пов’язаної з цією дією. Тому ми одразу переходимо до виконання методу execute об’єкта ForwardAction, який поверне об’єкт ActionForward, що вказує на вигляд /vues/formulaire.jsp.
6.3.6. Файл повідомлень додатка
Третій розділ файлу struts-config.xml — це файл повідомлень:
Файл ApplicationResources.properties розміщується в папці WEB-INF/classes. Він буде порожнім. Навіть порожній, він все одно має бути вказаний у файлі конфігурації, інакше бібліотека тегів struts-bean, яку ми розглянемо трохи пізніше, видасть помилку. Ця бібліотека використовується у подачі confirmation.jsp.
6.4. Код подань
6.4.1. Вигляд formulaire.jsp
Нагадаємо, що цей вигляд відображається у двох випадках:
- під час виклику дії /init у першому циклі «запит-відповідь»
- під час виклику дії /affiche у наступних циклах
Код подання formulaire.jsp має такий вигляд:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
<title>formulaire</title>
</head>
<body background='<html:rewrite page="/images/standard.jpg"/>'>
<h3>Formulaire Struts</h3>
<hr>
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<table border="0">
<tr>
<td>bouton radio</td>
<td>
<html:radio name="dynaFormulaire" property="opt" value="oui">Oui</html:radio>
<html:radio name="dynaFormulaire" property="opt" value="non">Non</html:radio>
</td>
</tr>
<tr>
<td>Cases à cocher</td>
<td>
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk3">3</html:checkbox>
</td>
</tr>
<tr>
<td>Champ de saisie</td>
<td>
<html:text name="dynaFormulaire" property="champSaisie" />
</td>
</tr>
<tr>
<td>Mot de passe</td>
<td>
<html:password name="dynaFormulaire" property="mdp" />
</td>
</tr>
<tr>
<td>Boîte de saisie multilignes</td>
<td>
<html:textarea name="dynaFormulaire" property="boiteSaisie" />
</td>
</tr>
<tr>
<td>Combo</td>
<td>
<html:select name="dynaFormulaire" property="combo">
<html:options name="dynaFormulaire" property="valeursCombo"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection unique</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
</td>
</tr>
</table>
<td>
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection multiple</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
</td>
</tr>
</table>
</td>
<td>
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
</td>
</tr>
</table>
<html:hidden name="dynaFormulaire" property="secret"/>
<br>
<hr>
<html:submit>Envoyer</html:submit>
</html:form>
</body>
</html>
Ця сторінка JSP використовує теги з бібліотеки struts-html. Нагадаємо, що для використання бібліотеки тегів необхідно:
- задекларувати її у файлі web.xml додатка за допомогою тегу <tag-lib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- розмістіть код цієї бібліотеки десь у дереві каталогів додатка, тут WEB-INF/struts-html.tld
- оголосіть використання цієї бібліотеки на початку сторінок JSP, які її використовують:
Вигляд formulaire.jsp використовує теги, які ми зараз пояснимо:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
тег html:rewrite дозволяє обійти ім'я додатка в URL. Він має один атрибут:
Отже, як показано вище, якщо вирішити назвати додаток «formulaire3», код атрибута background не потрібно переписувати. Тег html:rewrite згенерує новий код HTML background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
Тег html:form дозволяє створити тег HTML form. Він має кілька атрибутів:
Бачимо, що за замовчуванням згенерований код HTML використовує метод POST. У цьому ж коді HTML код дії URL було переписано таким чином, щоб перед ним стояв префікс із назвою додатка, а наприкінці — суфікс .do. |
<html:radio name="dynaFormulaire" property="opt" value="так">Так</html:radio> | |||||||
тег html:radio використовується для генерації тегу HTML <input type="radio" ...>. Він підтримує різні атрибути:
Текст між тегами початку та кінця — це текст, який буде відображатися поруч із перемикачем. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
тег html:checkbox використовується для генерації тегу HTML <input type="checkbox" ...>. Він підтримує різні атрибути:
Текст між тегами початку та кінця — це текст, який буде відображатися поруч із прапорцем. |
<html:text name="dynaFormulaire" property="champSaisie" /> | |||||||
тег html:text використовується для генерації тегу HTML <input type="text" ...>. Він підтримує різні атрибути:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
тег html:password використовується для генерації тегу HTML <input type="password" ...>. Він підтримує різні атрибути: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
Тег html:textarea використовується для генерації тегу HTML <textarea>...</textarea>. Він підтримує різні атрибути:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
тег html:select використовується для генерації тегу HTML <select>...</select>. Він підтримує різні атрибути:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |||||
Тег html:options використовується для генерації тегів HTML <option>...</option> всередині тегу HTML <select>. Існують різні способи вказати, як знайти значення для заповнення списку вибору. Тут ми використали атрибути name та property:
|
Два інші списки генеруються аналогічно до попереднього:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
У наведеному вище прикладі вказано атрибут size, значення якого відрізняється від 1, щоб отримати список замість комбінованого списку.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
Вище вказано атрибут multiple="true", щоб отримати список із можливістю множинного вибору.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
тег html:hidden використовується для генерації тегу HTML <input type="hidden" ...>.
|
Щоб добре зрозуміти зв’язок між представленням formulaire.jsp та біном dynaFormulaire, який представляє його в пам’яті, слід пам’ятати, що бін dynaFormulaire використовується як для читання, так і для запису:
![]() |
Запит надсилається, коли користувач натискає кнопку [Envoyer] у формі. Після цього браузер «відправляє» форму HTML на дію /confirmation. Ми вже пояснювали, що відбувається в цей момент, зокрема те, що поля dynaFormulaire отримають значення полів з такими самими іменами з форми HTML.
Що відбувається, коли контролер запитує відображення подання formulaire.jsp у відповідь на запит? Розглянемо теги по черзі:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
генерує код HTML |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
генерує код HTML |
<html:radio name="dynaFormulaire" property="opt" value="так">Так</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">Ні</html:radio> | |
Якщо значення поля opt у dynaFormulaire дорівнює «так», генерується код HTML |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> <html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox> <html:checkbox name="dynaFormulaire" property="chk3">3</html:checkbox> | |
Якщо поля chk1 і chk3 у dynaFormulaire мають значення «on», а поле chk2 — «off», згенеруйте код HTML |
<html:text name="dynaFormulaire" property="champSaisie" /> | |
якщо значення поля champSaisie дорівнює «це тест», генерується код HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
якщо значення поля mdp дорівнює "azerty", генерує код HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
якщо значення поля mdp дорівнює «azerty», генерує код HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
якщо значення поля mdp дорівнює "azerty", генерує код HTML |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |
якщо значення поля комбінованого списку дорівнює «combo2», генерує код HTML |
<html:select name="dynaFormulaire" property="listeSimple" size="3"> <html:options name="dynaFormulaire" property="valeursListeSimple"/> </html:select> | |
якщо значення поля listeSimple дорівнює «simple1», генерується код HTML |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="valeursListeMultiple"/> </html:select> | |
якщо поле listeMultiple є масивом {"multiple0","multiple2"}, генерує код HTML |
<html:hidden name="dynaFormulaire" property="secret"/> | |
якщо поле secret має значення "xxx", генерує код HTML |
<html:submit>Надіслати</html:submit> | |
генерує код HTML |
Останнє, що слід пояснити, — це код JavaScript, включений на сторінку JSP і пов’язаний із двома кнопками [Effacer], які скасовують вибір елементів, виділених у списках listeSimple та listeMultiple:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Тег
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
генерує такий код HTML:
Щоб зрозуміти код JavaScript, пов’язаний із кнопками [Effacer], нагадаємо, як позначаються різні елементи веб-документа в коді JavaScript, що використовує цей документ:
Дані | Значення |
позначає весь веб-документ | |
позначає сукупність форм, визначених у документі | |
позначає форму № i у документі | |
позначає формуляр <form>, атрибут name якого дорівнює "nomFormulaire" | |
позначає форму <form>, атрибут name якої дорівнює "nomFormulaire" | |
позначає сукупність елементів, що входять до форми, позначеної виразом [formulaire]. Ця сукупність включає всі теги <input>, <textarea>, <select> зазначеної форми. | |
позначає елемент № i з [formulaire] | |
позначає елемент [formulaire], у якого атрибут name дорівнює nomComposant | |
позначає елемент [formulaire], у якого атрибут name дорівнює nomComposant | |
позначає значення компонента [composant] форми [formulaire], коли код HTML цієї форми може мати атрибут value (<input>, <textarea>) | |
позначає індекс опції, обраної у списку. Використовується для читання та запису. Встановлення цього властивості на -1 скасовує вибір усіх елементів списку. | |
позначає масив опцій, пов’язаних із тегом <select> | |
позначає опцію № i вказаного тегу <select> | |
булеве значення, що вказує, чи обрано (true) опцію № i вказаного тегу [select]. Може використовуватися як для читання, так і для запису |
Повернемося до JavaScript-коду двох кнопок:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
При натисканні на кнопку виконується код, пов'язаний з атрибутом «onclick». У цьому випадку це вбудований код. Найчастіше пишуть onclick="функція(...)", де функція — це функція, визначена в тезі <script language="javascript">...</script>. Що робить наведений вище код? Прокоментуємо код першої кнопки:
позначає веб-документ, у якому знаходиться кнопка | |
позначає форму, у якій знаходиться кнопка | |
позначає компонент listeSimple форми | |
позначає індекс опції, вибраної в listeSimple. Встановлення цього параметра на -1 призводить до скасування вибору всіх опцій. |
6.4.2. Вигляд confirmation.jsp
Нагадаємо, що цей вигляд відображається після виконання дії /confirmation, c.a.d, після того, як форма, що міститься у вигляді formulaire.jsp, була відправлена веб-клієнтом. Його єдиною метою є відображення значень, введених користувачем. Його код такий:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
<title>Confirmation</title>
</head>
<body background="<html:rewrite page="/images/standard.jpg"/>">
<h3>Confirmation des valeurs saisies</h3>
<hr/>
<table border="1">
<tr>
<td>Bouton radio</td>
<td><bean:write name="dynaFormulaire" scope="session" property="opt"/></td>
</tr>
<tr>
<td>Case à cocher chk1</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk1"/></td>
</tr>
<tr>
<td>Case à cocher chk2</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk2"/></td>
</tr>
<tr>
<td>Case à cocher chk3</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk3"/></td>
</tr>
<tr>
<td>Champ de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="champSaisie"/></td>
</tr>
<tr>
<td>Mot de passe</td>
<td><bean:write name="dynaFormulaire" scope="session" property="mdp"/></td>
</tr>
<tr>
<td>Boîte de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="boiteSaisie"/></td>
</tr>
<tr>
<td>combo</td>
<td><bean:write name="dynaFormulaire" scope="session" property="combo"/></td>
</tr>
<tr>
<td>liste simple</td>
<td><bean:write name="dynaFormulaire" scope="session" property="listeSimple"/></td>
</tr>
<logic:iterate id="choix" indexId="index" name="dynaFormulaire" property="listeMultiple">
<tr>
<td>liste multiple[<bean:write name="index"/>]</td>
<td><bean:write name="choix"/></td>
</tr>
</logic:iterate>
</table>
<br>
<html:link page="/affiche.do">
Retour au formulaire
</html:link>
</body>
</html>
Тут ми вводимо дві нові бібліотеки тегів: struts-bean та struts-logic. Бібліотека struts-bean дозволяє отримати доступ до об’єктів, розміщених у запиті, сесії або контексті додатка. Бібліотека struts-logic дає змогу впроваджувати логіку виконання за допомогою тегів. Ці дві бібліотеки аж ніяк не є обов’язковими. Як ми вже бачили, сторінка JSP може:
- отримувати об’єкти із запиту (request.getAttribute(...)), сесії (session.getAttribute(...)) або контексту додатка
- включати динамічні елементи в код HTML за допомогою змінних <%= змінна %>
- містити код Java <% код Java %>
Включення коду Java у сторінки JSP заважає всім, хто прагне суворого розділення між логікою додатка (кодом Java) та представленням (використанням тегів). Тому для них були створені бібліотеки тегів.
Ми будемо діяти так само, як і для подання formulaire.jsp, і пояснимо кожну з тегів, присутніх у коді confirmation.jsp, якщо вони ще не зустрічалися у поданні formulaire.jsp. Насамперед зауважимо, що сторінка починається з оголошення трьох бібліотек тегів, які вона використовуватиме:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
Нагадаємо також, що ці три бібліотеки мають бути оголошені у файлі web.xml додатка. Тепер прокоментуємо теги документа formulaire.jsp:
записує значення в поточний потік HTML. Тег bean:write підтримує такі атрибути: name: ім’я об’єкта, який потрібно використати scope: область дії (request, session, context), в якій слід шукати цей об’єкт property: поле об’єкта, позначеного атрибутом name, властивість якого потрібно записати. Це поле може бути об’єктом будь-якого типу. Використовуватиметься метод toString цього об’єкта. Тут записується значення поля opt об’єкта dynaFormulaire. Буде «так», якщо користувач встановив прапорець з атрибутом value="так", або «ні», якщо він встановив прапорець з атрибутом value="ні" |
записує значення поля chk1 з dynaFormulaire. Буде або «on», якщо користувач встановив прапорець, або «off» в іншому випадку. Те саме стосується полів chk2 та chk3. |
записує значення поля champSaisie з dynaFormulaire, тобто текст, введений користувачем у це поле. Те саме стосується mdp, boiteSaisie. |
записує значення поля комбінованого списку dynaFormulaire. Ми отримаємо атрибут value елемента <option>, вибраного користувачем. |
записує значення поля listeSimple з dynaFormulaire. Якщо користувач вибрав елемент <option>, то буде використано його атрибут value. В іншому випадку буде використано порожній рядок. |
Тут ми вводимо логічні теги. Ми маємо справу зі списком з кількома варіантами вибору. Значенням поля listeMultiple об’єкта dynaFormulaire є масив рядків. У Java ми б написали цикл. Тег logic:iterate дозволяє нам виконати цей самий цикл без написання коду на Java. У наведеному прикладі тег logic:iterate має такі атрибути: name="dynaFormulaire": ім’я об’єкта, який потрібно використовувати property="listeMultiple": ім’я властивості, яка в об’єкті, вказаному в атрибуті name, містить колекцію, що буде обходитися в циклі. У даному випадку ця колекція — це масив значень, вибраних у listeMultiple. Цей масив може бути порожнім. id="choix": ідентифікатор, що позначає поточний елемент масиву на кожному циклі. Під час першої ітерації «choix» буде дорівнювати listeMultiple[0], під час другої — listeMultiple[1] і так далі. indexID="index": ідентифікатор, що позначає індекс поточного елемента масиву під час кожного проходу циклу. Під час першої ітерації index матиме значення 0, під час другої — 1 і так далі. Код HTML, що міститься між тегами <logic:iterate ...> та </logic:iterate>, повторюється для кожного елемента колекції, позначеної парою (name,property). Динамічна частина цього коду виглядає так:
З огляду на вищесказане, під час ітерації № i (i>=0) згенерований код HTML еквівалентний такому коду: |
генерує посилання, пов'язане з контекстом додатка, що дозволяє обійтися без знання цього контексту. Код HTML, згенерований цим тегом, виглядає так: |
6.5. Класи Java
Файл конфігурації struts-config.xml посилається на два класи Java:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
Клас DynaFormulaire — це клас, який міститиме значення подання № 1 formulaire.jsp. Клас InitFormulaireAction — це клас, який оброблятиме значення форми, надісланої за допомогою кнопки [Envoyer] з formulaire.jsp.
6.5.1. Клас DynaFormulaire
Для зберігання значень форми достатньо об’єкта типу DynaActionForm, за винятком випадків, коли потрібно перевизначити один із методів reset або validate цього класу. У даному випадку метод validate перевизначати не потрібно, оскільки перевірка даних не здійснюється. Однак метод reset потрібно перевизначити. Справа в тому, що поля об’єкта DynaFormulaire отримуватимуть свої значення з форми, надісланої веб-клієнтом. Однак деякі поля можуть не отримати значення, якщо їх немає у запиті. Це трапляється в таких випадках:
- поле для позначки, яке користувач не позначив
- список, що містить більше ніж 1 елемент, або жоден варіант не було обрано
Для форм, що містять цей тип компонента, метод reset повинен
- присвоювати значення «off» полю, пов’язаному з прапорцем
- присвоїти порожній рядок полю, пов’язаному зі списком з одним варіантом вибору
- присвоїти масив символьних рядків нульового розміру полю, пов’язаному зі списком з можливістю множинного вибору
Таким чином, якщо ці поля не отримують значення із запиту, вони зберігають значення, присвоєне методом reset, яке відповідає стану компонента у формі, затвердженій користувачем (поле не відмічене, список без жодного вибраного елемента).
Код класу DynaFormulaire, похідного від класу DynaActionForm, є таким:
package istia.st.struts.formulaire;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
public class DynaFormulaire extends DynaActionForm {
public void reset(ActionMapping mapping, HttpServletRequest request){
// скидання прапорців — значення «off»
set("chk1","off");
set("chk2","off");
set("chk2","off");
// скидання listeSimple — порожній рядок
set("listeSimple","");
// скидання listeMultiple — порожній масив
set("listeMultiple",new String[]{});
}
}
6.5.2. Клас InitFormulaireAction
Клас InitFormulaireAction у файлі struts-config.xml пов'язаний з дією /init:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
Дія /init використовується лише один раз під час початкового створення об’єкта DynaFormulaire. Її метою є заповнення вмісту трьох списків комбінованого поля: listeSimple, listeMultiple. Цей вміст надається у вигляді трьох масивів, які є властивостями об’єкта dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Після того як масиви valeursCombo, valeursListeSimple, valeursListeMultiple будуть ініціалізовані за допомогою InitFormulaireAction, їх більше не потрібно буде ініціалізувати. Адже об’єкт dynaFormulaire розміщується в сесії і, отже, зберігає своє значення протягом циклів «запит-відповідь». Саме тому дія /init виконується лише один раз. Код InitFormulaireAction виглядає так:
package istia.st.struts.formulaire;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class InitFormulaireAction
extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// підготовка форми до відображення
// необхідну інформацію про форму заносимо в її bean
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
// повертаємо контроль
return mapping.findForward("afficherFormulaire");
} //виконується
// список значень комбінованого списку
private String[] getValeurs(int taille, String label) {
String[] valeurs = new String[taille];
for (int i = 0; i < taille; i++) {
valeurs[i] = label + i;
}
return valeurs;
}
}
- Клас є похідним від класу Action. Це обов'язково.
- Контролер Struts використовує об’єкт Action через його метод execute. Отже, саме цей метод потрібно перевизначити. Цей метод приймає такі параметри:
- ActionMapping mapping: об’єкт, що представляє конфігурацію додатка в struts-config.xml
- ActionForm form: форма, пов’язана з дією, якщо така визначена в конфігурації дії (атрибут name дії).
- HttpServletRequest request: запит клієнта
- HttpServletResponse: відповідь клієнту
- клас InitFormulaireAction повинен ініціалізувати форму dynaFormulaire. Вона передається до методу execute у вигляді параметра ActionForm form. Нагадаємо, що dynaFormulaire належить до типу DynaFormulaire — класу, похідного від класу DynaActionForm, який, у свою чергу, є похідним від класу ActionForm.
- У методі `execute` значенням присвоюються три поля valeursCombo, valeursListeSimple, valeursListeMultiple за допомогою методу `set` класу DynaActionForm. Для простоти ці значення є довільними масивами. Зауважимо, що метод set присвоює значення існуючому полю. Він не може використовуватися для створення нових полів. Тому необхідно визначити три поля valeursCombo, valeursListeSimple, valeursListeMultiple у визначенні об’єкта dynaFormulaire у struts-config.xml.
- Метод `execute` завершується, повертаючи контролеру ключ подання, яке слід відобразити у відповіді клієнту. У даному випадку це ключ afficherFormulaire, який у файлі struts-config.xml було пов’язано з поданням /vues/formulaire.jsp.
6.6. Розгортання
Структура додатка виглядає наступним чином:
![]() | ![]() |
![]() | ![]() |


Нагадаємо, що наведений вище файл ApplicationResources.properties необхідний для бібліотеки тегів struts-bean. Відомо, що цей файл містить повідомлення додатка. До них має доступ бібліотека struts-bean. У даному випадку наш додаток не визначає жодного повідомлення. Тому файл ApplicationResources.properties існує, але є порожнім.
6.7. Висновок
У цьому уроці ми детально розглянули, як працювати з різними компонентами форми HTML. Тепер ми можемо використовувати складні форми у наших додатках Struts.






