8. Esempio 06 – La sessione
8.1. Il concetto di sessione
Quando un browser client si connette per la prima volta a un'applicazione web, riceve un token di sessione, una sequenza di caratteri univoca che rinvia ad ogni nuova richiesta che invia all'applicazione web. Ciò consente a quest'ultima di riconoscere il browser client. A questo token di sessione, l'applicazione può quindi associare dei dati. Questi dati appartengono a un unico browser client. In questo modo, man mano che il browser client invia le richieste, si costituisce una memoria.
![]() |
Come illustrato sopra, ogni utente (browser) dispone di una propria memoria, denominata «sessione». Questa memoria è condivisa da tutte le richieste dello stesso utente. Esiste inoltre una memoria di livello superiore, denominata «memoria dell’applicazione». Questa memoria è condivisa da tutte le richieste di tutti gli utenti. In genere è di sola lettura.
8.2. Il progetto NetBeans
![]() |
Il progetto [exemple-06] è stato creato copiando il progetto [exemple-05]. Modificheremo alcuni elementi per
- sfruttare la sessione dell'utente.
- aggiungere una nuova azione [Effacer] [1] per cancellare il campo di immissione.
8.3. Configuration
Il file [struts.xml] viene modificato come segue:
<?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>
<!-- internazionalizzazione -->
<constant name="struts.custom.i18n.resources" value="messages" />
<!-- pacchetto predefinito -->
<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>
<!-- pacchetto azioni -->
<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>
Le righe 27-29 definiscono una nuova azione [Effacer] associata a una classe [Effacer]. La risposta a questa azione è la vista [Saisie.JSP].
8.4. L'azione [Confirmer]
Si evolve come segue:
package actions;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class Confirmer extends ActionSupport implements SessionAware{
// modello
private String nom;
// sessione
private Map<String, Object> session;
// getters e setters
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(){
// si inserisce il nome nella sessione
session.put("nom",nom);
// navigazione
return SUCCESS;
}
}
- riga 7: la classe [Confirmer] implementa l'interfaccia SessionAware. Questa interfaccia ha un solo metodo, il metodo setSession alle righe 25-27. Prima della chiamata al metodo execute, uno degli intercettatori della richiesta inserirà, tramite il metodo setSession, la sessione dell’utente sotto forma di un dizionario Map<String, Object> (riga 25). Scegliamo di memorizzare questo dizionario nel campo session della riga 12.
- righe 30-34: il metodo execute dell'azione. Al momento dell’esecuzione, il campo session è stato inizializzato da uno degli intercettatori, così come il campo nom da un altro intercettatore. Si utilizza questo dizionario session per memorizzarvi il campo nom. In questo modo il nome entrerà a far parte della memoria dell’utente e sarà disponibile per tutte le sue richieste.
8.5. Le viste [Confirmation.JSP] e [Saisie.JSP]
La vista [Confirmation.JSP] rimane invariata. La vista [Saisie.JSP] viene modificata come segue:
<%@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>
- riga 12: inseriamo un attributo value nel tag <s:textfield>.. Questo attributo definisce il valore da visualizzare nella casella di immissione. In assenza di questo attributo, value = name. In questo caso, il valore dell’attributo è un’espressione OGNL (Object-Graph Navigation Language) della forma %{expression_à_évaluer}. In questo caso, l’espressione da valutare è #attr['nom']. L’attributo nom verrà cercato nell’azione corrente, nella pagina, nella richiesta, nella sessione e nell’applicazione, in quest’ordine. Poiché l’azione [Confirmer] inserisce l’attributo nom nella sessione, esso verrà trovato lì. È quanto mostra la seguente query:
![]() |
In [1], il nome inserito era ST. Sappiamo che l’azione [Confirmer] ha inserito questo nome nella sessione. Il collegamento [2] ci porta a URL e [3]. Viene visualizzata la vista [Saisie.JSP]. Per il campo di immissione, l’attributo %{#attr['nom']} consente di recuperare il nome dalla sessione.
- riga 14: il pulsante [Effacer] che attiverà l'esecuzione dell'azione [Effacer] e la visualizzazione della vista [Saisie.JSP]
<action name="Effacer" class="actions.Effacer">
<result name="success">/vues/Saisie.JSP</result>
</action>
8.6. L'azione [Effacer]
Il codice dell'azione [Effacer] è il seguente:
package actions;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class Effacer extends ActionSupport implements SessionAware{
// sessione
private Map<String, Object> session;
@Override
public String execute(){
// si recupera il nome dalla sessione
String nom=(String)session.get("nom");
// lo si rimuove dalla sessione se necessario
if(nom!=null){
session.remove("nom");
}
// navigazione
return SUCCESS;
}
@Override
public void setSession(Map<String, Object> map) {
this.session=map;
}
}
- riga 7: la classe [Effacer] implementa l'interfaccia [SessionAware], così come faceva l'azione [Confirmer].
- riga 13: l'azione [Effacer] deve cancellare il contenuto del campo di immissione del nome nella vista [Saisie.JSP]. Sappiamo che questa vista recupera il nome dalla sessione. Dobbiamo quindi rimuovere il nome dalla sessione. È ciò che fa il metodo execute.
Vediamo come funziona:
![]() |
In [1], si desidera cancellare il campo di immissione. Si fa clic sul pulsante [Effacer].
<s:submit key="saisie.effacer" action="Effacer"/>
Verrà eseguita l’azione [Effacer]. In [2], si nota che l’azione URL richiamata è stata quella dell’azione [Confirmer]. Ciò deriva dal tag <s:form> del modulo:
<s:form action="Confirmer">
che fa sì che il modulo venga inviato all’azione [Confirmer]. Cliccando sul pulsante [Effacer], il parametro
action:Effacer=Effacer
è stato inviato all’azione URL [/actions/Confirmer.action]. Struts utilizza questo parametro per far elaborare i dati inviati dall’azione [Effacer]. Quest’ultima rimuove il nome della sessione. La pagina [Saisie.JSP] è la risposta dell'azione [Effacer]:
<action name="Effacer" class="actions.Effacer">
<result name="success">/vues/Saisie.JSP</result>
</action>
Quest'ultima, che visualizza il nome della sessione, mostra quindi una stringa vuota [3].
Abbiamo scritto diversi esempi semplici per introdurre alcuni concetti importanti di Struts 2:
- l'internazionalizzazione delle pagine
- l'iniezione dei parametri inviati nei campi delle azioni
- il concetto di sessione
- l'interazione tra azioni e viste
Una volta acquisiti questi concetti, siamo ora in grado di affrontare esempi più complessi. Iniziamo presentando i diversi tag utilizzabili in un modulo.



