8. Esempio 06 – La sessione
8.1. Il concetto di sessione
Quando il browser di un client si connette per la prima volta a un'applicazione web, riceve un token di sessione, una stringa di caratteri univoca che invia con ogni nuova richiesta effettuata all'applicazione web. Ciò consente all'applicazione web di riconoscere il browser del client. L'applicazione web può quindi associare dei dati a questo token di sessione. Questi dati appartengono a un singolo browser client. Pertanto, man mano che il browser del client effettua richieste, si crea una memoria.
![]() |
Come mostrato sopra, ogni utente (browser) ha una propria memoria, nota come sessione. Questa memoria è condivisa da tutte le richieste provenienti dallo stesso utente. Esiste anche una memoria di livello superiore chiamata memoria dell'applicazione. Questa memoria è condivisa da tutte le richieste provenienti da tutti gli utenti. È generalmente di sola lettura.
8.2. Il progetto NetBeans
![]() |
Il progetto [example-06] viene creato copiando il progetto [example-05]. Modificheremo alcuni elementi per
- sfruttare la sessione utente.
- Aggiungere una nuova azione [Cancella] [1] per cancellare il campo di immissione.
8.3. Configurazione
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>
<!-- internationalization -->
<constant name="struts.custom.i18n.resources" value="messages" />
<!-- default package -->
<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>
<!-- equity 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>
Le righe 27–29 definiscono una nuova azione [Delete] associata a una classe [Delete]. La risposta a questa azione è la vista [Input.jsp].
8.4. L'azione [Confirm]
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{
// model
private String nom;
// session
private Map<String, Object> session;
// getters and 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(){
// put the name in the session
session.put("nom",nom);
// navigation
return SUCCESS;
}
}
- Riga 7: La classe [Confirm] implementa l'interfaccia SessionAware. Questa interfaccia ha un solo metodo, il metodo setSession alle righe 25–27. Prima che venga chiamato il metodo execute, uno degli intercettatori di richiesta inserirà, tramite il metodo setSession, la sessione dell'utente sotto forma di un dizionario Map<String, Object> (riga 25). Abbiamo scelto di memorizzare questo dizionario nel campo session alla riga 12.
- Righe 30–34: il metodo `execute` dell'azione. Quando viene eseguito, il campo session è stato inizializzato da uno degli intercettatori e il campo name da un altro intercettatore. Utilizziamo questo dizionario di sessione per memorizzare il campo name. Pertanto, il nome farà parte della sessione 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] cambia 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: aggiungiamo un attributo `value` al tag `<s:textfield>`. Questo attributo imposta il valore da visualizzare nel campo di immissione. Se questo attributo viene omesso, `value` assume per impostazione predefinita il valore `name`. In questo caso, il valore dell'attributo è un'espressione OGNL (Object-Graph Navigation Language) nella forma `%{espressione_da_valutare}`. In questo caso, l'espressione da valutare è #attr['name']. L'attributo name verrà cercato nell'azione corrente, nella pagina, nella richiesta, nella sessione e nell'applicazione, in quest'ordine. Poiché l'azione [Confirm] inserisce l'attributo name nella sessione, verrà trovato lì. Ciò è dimostrato dalla seguente richiesta:
![]() |
In [1], il nome inserito era ST. Sappiamo che l'azione [Confirm] ha inserito questo nome nella sessione. Il link [2] ci porta all'URL [3]. Viene visualizzata la vista [Saisie.jsp]. Per il campo di immissione, l'attributo %{#attr['name']} recupera il nome dalla sessione.
- Riga 14: il pulsante [Cancella], che attiva l'esecuzione dell'azione [Cancella] 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 [Elimina]
Il codice per l'azione [Elimina] è 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{
// session
private Map<String, Object> session;
@Override
public String execute(){
// retrieve the name from the session
String nom=(String)session.get("nom");
// remove it from the session if necessary
if(nom!=null){
session.remove("nom");
}
// navigation
return SUCCESS;
}
@Override
public void setSession(Map<String, Object> map) {
this.session=map;
}
}
- Riga 7: La classe [Delete] implementa l'interfaccia [SessionAware], proprio come ha fatto l'azione [Confirm].
- riga 13: L'azione [Delete] deve cancellare il contenuto del campo di immissione del nome nella vista [Input.jsp]. Sappiamo che questa vista recupera il nome dalla sessione. Dobbiamo quindi rimuovere il nome dalla sessione. Questo è ciò che fa il metodo execute.
Vediamo come funziona:
![]() |
In [1], vogliamo cancellare il campo di immissione. Facciamo clic sul pulsante [Cancella].
<s:submit key="saisie.effacer" action="Effacer"/>
Verrà eseguita l'azione [Cancella]. In [2], notiamo che l'URL richiamato era quello dell'azione [Conferma]. Ciò deriva dal tag <s:form> nel modulo:
<s:form action="Confirmer">
il che fa sì che il modulo venga inviato all'azione [Conferma]. Quando si fa clic sul pulsante [Cancella], il parametro
action:Delete=Delete
è stato inviato all'URL [/actions/Confirm.action]. Struts utilizza questo parametro per elaborare i dati inviati dall'azione [Elimina]. Questa azione rimuove il nome della sessione. La pagina [Input.jsp] è la risposta all'azione [Elimina]:
<action name="Effacer" class="actions.Effacer">
<result name="success">/vues/Saisie.jsp</result>
</action>
Questa, che visualizza il nome della sessione, mostra poi una stringa vuota [3].
Abbiamo scritto diversi semplici esempi per introdurre i concetti fondamentali di Struts 2:
- internazionalizzazione delle pagine
- iniezione dei parametri inviati nei campi dell'azione
- il concetto di sessioni
- il rapporto tra azioni e viste
Ora che abbiamo acquisito padronanza di questi concetti, siamo pronti ad affrontare esempi più complessi. Inizieremo introducendo i vari tag che possono essere utilizzati in un modulo.



