8. Приклад 06 — Сесія
8.1. Поняття сесії
Коли браузер клієнта вперше підключається до веб-додатка, він отримує сесійний токен — унікальний набір символів, який він надсилає з кожним новим запитом до веб-додатка. Це дозволяє додатку розпізнавати браузер клієнта. З цим сесійним токеном додаток може пов’язувати дані. Ці дані належать лише одному браузеру клієнта. Таким чином, у міру надходження запитів від клієнтського браузера формується пам’ять.
![]() |
Як показано вище, кожен користувач (браузер) має власний обсяг пам’яті, який називається сесією. Цей обсяг пам’яті є спільним для всіх запитів одного користувача. Існує також обсяг пам’яті вищого рівня, який називається пам’яттю додатка. Цей обсяг пам’яті є спільним для всіх запитів усіх користувачів. Зазвичай він доступний лише для читання.
8.2. Проєкт NetBeans
![]() |
Проєкт [exemple-06] отримано шляхом копіювання проєкту [exemple-05]. Ми змінимо деякі елементи, щоб
- скористатися сесією користувача.
- додати нову дію [Effacer] [1] для очищення поля введення.
8.3. Configuration
Файл [struts.xml] змінюється наступним чином:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- інтернаціоналізація -->
<constant name="struts.custom.i18n.resources" value="messages" />
<!-- пакет за замовчуванням -->
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<action name="index">
<result type="redirectAction">
<param name="actionName">Saisir</param>
<param name="namespace">/actions</param>
</result>
</action>
</package>
<!-- пакет дій -->
<package name="actions" namespace="/actions" extends="struts-default">
<action name="Saisir">
<result name="success">/vues/Saisie.JSP</result>
</action>
<action name="Confirmer" class="actions.Confirmer">
<result name="success">/vues/Confirmation.JSP</result>
</action>
<action name="Effacer" class="actions.Effacer">
<result name="success">/vues/Saisie.JSP</result>
</action>
</package>
</struts>
Рядки 27–29 визначають нову дію [Effacer], пов’язану з класом [Effacer]. Відповіддю на цю дію є представлення [Saisie.JSP].
8.4. Дія [Confirmer]
Вона розвивається наступним чином:
package actions;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class Confirmer extends ActionSupport implements SessionAware{
// модель
private String nom;
// сесія
private Map<String, Object> session;
// методи getter та setter
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
@Override
public void setSession(Map<String, Object> session) {
this.session=session;
}
@Override
public String execute(){
// заносимо ім'я в сесію
session.put("nom",nom);
// навігація
return SUCCESS;
}
}
- рядок 7: клас [Confirmer] реалізує інтерфейс SessionAware. Цей інтерфейс має лише один метод — метод setSession у рядках 25–27. Перед викликом методу execute один із перехоплювачів запиту вставляє, за допомогою методу setSession, сесію користувача у вигляді словника Map<String, Object> (рядок 25). Ми вирішили зберегти цей словник у полі session у рядку 12.
- рядки 30–34: метод execute дії. Під час його виконання поле session було ініціалізовано одним із перехоплювачів, а поле nom — іншим перехоплювачем. Цей словник session використовується для зберігання поля nom. Таким чином, ім’я стане частиною пам’яті користувача і буде доступним для всіх його запитів.
8.5. Види [Confirmation.JSP] та [Saisie.JSP]
Вигляд [Confirmation.JSP] залишається без змін. Вигляд [Saisie.JSP] змінюється наступним чином:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="saisie.titre1"/></title>
</head>
<body>
<h1><s:text name="saisie.titre2"/></h1>
<s:form action="Confirmer">
<s:textfield key="saisie.libelle" name="nom" value="%{#attr['nom']}"/>
<s:submit key="saisie.valider" action="Confirmer"/>
<s:submit key="saisie.effacer" action="Effacer"/>
</s:form>
</body>
</html>
- рядок 12: додаємо атрибут value до тегу <s:textfield>.. Цей атрибут визначає значення, яке має відображатися в полі введення. За відсутності цього атрибута value = name. У цьому випадку значенням атрибута є вираз OGNL (Object-Graph Navigation Language) у формі %{expression_à_évaluer}. У цьому випадку вираз, що підлягає обчисленню, — це #attr['nom']. Атрибут nom шукатиметься у поточній дії, на сторінці, у запиті, у сесії та в додатку саме в такому порядку. Оскільки дія [Confirmer] встановлює атрибут nom у сесії, його буде знайдено саме там. Це ілюструє наступний запит:
![]() |
У дії [1] введено ім’я ST. Відомо, що дія [Confirmer] внесла це ім’я до сесії. Посилання [2] веде нас до URL та [3]. Відображається вікно [Saisie.JSP]. Для поля введення атрибут %{#attr['nom']} дозволяє знайти ім’я в сесії.
- рядок 14: кнопка [Effacer], яка запускає виконання дії [Effacer] та відображення подання [Saisie.JSP]
<action name="Effacer" class="actions.Effacer">
<result name="success">/vues/Saisie.JSP</result>
</action>
8.6. Дія [Effacer]
Код дії [Effacer] такий:
package actions;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class Effacer extends ActionSupport implements SessionAware{
// сесія
private Map<String, Object> session;
@Override
public String execute(){
// отримання імені з сесії
String nom=(String)session.get("nom");
// видаляємо його з сесії, якщо потрібно
if(nom!=null){
session.remove("nom");
}
// навігація
return SUCCESS;
}
@Override
public void setSession(Map<String, Object> map) {
this.session=map;
}
}
- рядок 7: клас [Effacer] реалізує інтерфейс [SessionAware], як це робила дія [Confirmer].
- рядок 13: дія [Effacer] повинна очистити вміст поля введення імені у вигляді [Saisie.JSP]. Ми знаємо, що цей вигляд отримує це ім’я з сесії. Тому потрібно видалити ім’я з сесії. Саме це робить метод execute.
Подивимося, що з цього вийде:
![]() |
У [1] потрібно очистити поле введення. Натискаємо кнопку [Effacer].
<s:submit key="saisie.effacer" action="Effacer"/>
Виконається дія [Effacer]. У [2] можна помітити, що викликана URL була тією, що належить дії [Confirmer]. Це пов’язано з тегом <s:form> у формі:
<s:form action="Confirmer">
, завдяки якій форма надсилається до дії [Confirmer]. При натисканні кнопки [Effacer] параметр
action:Effacer=Effacer
був відправлений до дії URL [/actions/Confirmer.action]. Struts використовує цей параметр для обробки даних, відправлених дією [Effacer]. Ця дія видаляє ім’я сесії. Сторінка [Saisie.JSP] є відповіддю дії [Effacer]:
<action name="Effacer" class="actions.Effacer">
<result name="success">/vues/Saisie.JSP</result>
</action>
Ця дія, яка відображає ім’я сесії, показує порожній рядок [3].
Ми написали кілька простих прикладів, щоб ознайомити вас з важливими концепціями Struts 2:
- інтернаціоналізація сторінок
- введення параметрів, надісланих у полях дій
- поняття сесії
- взаємодія між діями та поданнями
Опанувавши ці поняття, ми тепер можемо перейти до більш складних прикладів. Почнемо з огляду різних тегів, які можна використовувати у формі.



