16. Esempio 13 - Il contesto di un'azione
Questa applicazione ha lo scopo di dimostrare che un'azione ha accesso a:
- parametri della richiesta
- agli attributi della richiesta
- agli attributi della sessione utente

16.1. Il progetto NetBeans
![]() |
Il progetto NetBeans è il seguente:
- in [1], la vista [Context.jsp]
- in [2], l'azione [Action1.java] e il file di configurazione Struts [example.xml]
16.2. Configurazione
La configurazione del progetto è definita in [example.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>
<package name="example" namespace="/example" extends="struts-default">
<action name="Action1" class="example.Action1">
<result name="success">/example/Context.jsp</result>
</action>
</package>
</struts>
- Riga 8: La richiesta per l'URL [/example/Action1] attiverà l'istanziazione della classe [example.Action]. Poiché non è specificato alcun metodo, verrà eseguito il metodo execute.
- Riga 9: È accettata una sola chiave. La chiave "success" fa sì che venga visualizzata la vista [Context.jsp].
L'architettura semplificata per l'elaborazione di una richiesta è la seguente:
![]() |
La richiesta verrà elaborata da due componenti dell'applicazione web: l'azione [Action1] [1] e la vista [Context.jsp] [2]. Questi due componenti hanno accesso a diversi tipi di dati:
- Dati a livello di applicazione [3], ovvero dati accessibili a tutte le richieste di tutti gli utenti. Sono quasi sempre di sola lettura. Questi dati contengono spesso la configurazione iniziale dell'applicazione. In questo caso, [Action1] e [Context.jsp] hanno accesso a questi dati.
- Dati a livello di sessione [4], ovvero dati accessibili a tutte le richieste provenienti dallo stesso utente. Questi dati sono in modalità lettura/scrittura. In questo caso, [Action1] utilizzerà la sessione in modalità lettura/scrittura, mentre [Context.jsp] la utilizzerà in modalità di sola lettura.
- Dati nell'ambito della richiesta [5], accessibili a tutti gli elementi che elaborano la richiesta. In questo caso, [Action1] memorizzerà i dati in questa memoria e [Context.jsp] li recupererà. I dati nell'ambito della richiesta consentono all'elemento N di passare informazioni all'elemento N+1.
- Parametri di richiesta [6] inviati dal client. Sono utilizzati in modalità di sola lettura dai componenti che elaborano la richiesta.
16.3. L'azione [Action1]
Il codice per la classe [Action1] è il seguente:
package example;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import java.util.Set;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;
public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {
// constructor without parameters
public Action1() {
}
// Session, Request, Parametres
Map<String, Object> session;
Map<String, Object> request;
Map<String, String[]> parameters;
@Override
public String execute() {
// parameter list
System.out.println("Paramètres...");
Set<String> clés = parameters.keySet();
for (String clé : clés) {
for (String valeur : parameters.get(clé)) {
System.out.println(String.format("[%s,%s]", clé, valeur));
}
}
// session
System.out.println("Session...");
if (session.get("compteur") == null) {
session.put("compteur", new Integer(0));
}
Integer compteur = (Integer) session.get("compteur");
compteur = compteur + 1;
session.put("compteur", compteur);
System.out.println(String.format("compteur=%s", compteur));
// request
request.put("info1", "information1");
// display page JSP
return SUCCESS;
}
// session
public void setSession(Map<String, Object> session) {
this.session = session;
}
// request
public void setRequest(Map<String, Object> request) {
this.request = request;
}
// settings
public void setParameters(Map<String, String[]> parameters) {
this.parameters = parameters;
}
}
- riga 10: la classe implementa le seguenti interfacce
- SessionAware: per accedere al dizionario degli attributi di sessione (riga 16). Questa interfaccia ha un solo metodo, quello alla riga 46.
- RequestAware: per accedere al dizionario degli attributi della richiesta (riga 17). Questa interfaccia ha un solo metodo, quello alla riga 51.
- ParameterAware: per accedere al dizionario dei parametri della richiesta (riga 18). Si noti che ogni chiave (il nome del parametro) corrisponde a un array di valori. Ciò è necessario per gestire i campi di input che inviano più valori, come un elenco a selezione multipla. L'interfaccia ParameterAware ha un solo metodo, quello alla riga 56.
- Riga 21: il metodo execute, che viene eseguito quando viene richiesta l'azione [Action1]. Al momento dell'esecuzione, gli intercettatori hanno già svolto il loro compito:
- il metodo setParameters (riga 56) è stato chiamato e il dizionario dei parametri alla riga 18 contiene tutti i parametri della richiesta.
- Il metodo setSession (riga 46) è stato chiamato e il dizionario session alla riga 16 contiene tutti gli attributi di sessione.
- il metodo setRequest (riga 51) è stato chiamato e il dizionario request alla riga 17 contiene tutti gli attributi della richiesta.
- Righe 31–38: Il valore associato alla chiave `compteur` viene scritto nella sessione
- Righe 32–34: La chiave `compteur` viene cercata nella sessione. Se non viene trovata, viene aggiunta con il valore intero 0.
- Righe 35–37: La chiave `counter` viene cercata nella sessione, il suo valore viene incrementato e quindi la chiave viene reinserita nella sessione.
- Riga 38: viene visualizzato il valore associato alla chiave `counter`. Poiché l'incremento viene eseguito ad ogni richiesta sull'azione [Action1], dovremmo vedere il valore del contatore aumentare man mano che vengono effettuate le richieste.
- Riga 40: un attributo con la chiave `info1` e il valore `information1` viene inserito nel dizionario degli attributi della richiesta. Gli attributi della richiesta sono diversi dai parametri della richiesta. I parametri vengono inviati dal client dell'applicazione web. Gli attributi della richiesta, invece, consentono la comunicazione tra i vari componenti dell'applicazione web che elaborano la richiesta. Pertanto, dopo l'esecuzione di [Action1], verrà visualizzata la vista [Context.jsp]. Vedremo che è in grado di recuperare gli attributi della richiesta.
- Riga 42: Il metodo execute restituisce la chiave "success".
16.4. Il file dei messaggi
Il file [messages.properties] è il seguente:
Context.titre=Contexte de l''action
Context.message=Contexte de l''action
Context.parameters=Param\u00E8tres de l''action
Context.session=Elements de session
Context.request=Attributs de requ\u00EAte
16.5. La vista [Context.jsp]
La vista [Context.jsp] è responsabile della visualizzazione di:
- alcuni parametri di richiesta
- il valore della chiave counter nella sessione
- il valore della chiave info1 nella richiesta
Il codice è il seguente:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title><s:text name="Context.titre"/></title>
<s:head/>
</head>
<body background="<s:url value="/ressources/standard.jpg"/>">
<h2><s:text name="Context.message"/></h2>
<h3><s:text name="Context.parameters"/></h3>
<s:iterator value="#parameters['nom']" var="nom">
nom : <s:property value="nom"/><br/>
</s:iterator>
<s:iterator value="#parameters['prenom']" var="prenom">
prenom : <s:property value="prenom"/><br/>
</s:iterator>
<s:iterator value="#parameters['age']" var="age">
âge : <s:property value="age"/><br/>
</s:iterator>
<h3><s:text name="Context.session"/></h3>
compteur : <s:property value="#session['compteur']"/>
<h3><s:text name="Context.request"/></h3>
info1 : <s:property value="#request['info1']"/>
</body>
</html>
- Righe 12–14: visualizza tutti i valori associati al parametro "name"
- righe 15-17: visualizza tutti i valori associati al parametro 'first_name'
- righe 18-20: visualizza tutti i valori associati al parametro age
- riga 22: visualizza il valore associato alla chiave counter nella sessione
- riga 24: visualizza il valore associato alla chiave info1 nella query
16.6. I test
![]() |
- In [1], Action1 viene chiamata senza parametri
- in [2], [Context.jsp] non ha trovato alcun parametro
- in [3], [Context.jsp] ha trovato la chiave counter nella sessione
- in [4], [Context.jsp] ha trovato la chiave info1 nella richiesta
Eseguiamo un altro test:
![]() |
- In [1], Action1 viene richiesta con i parametri
- In [2], [Context.jsp] visualizza questi parametri
- In [3], [Context.jsp] ha trovato la chiave "compteur" nella sessione. Il contatore è stato effettivamente incrementato di 1, dimostrando che i dati sono stati conservati con successo tra le due richieste.
- In [4], [Context.jsp] ha trovato la chiave "info1" nella richiesta
Ricordiamo che il metodo [Action1.execute] ha scritto sulla console del server web. Ecco un esempio:
16.7. Conclusione
Tenete a mente i seguenti punti:
- Per memorizzare le informazioni da condividere tra tutte le richieste di tutti gli utenti, useremo la memoria dell'applicazione. Ne mostreremo un esempio tra poco.
- Per memorizzare le informazioni da condividere tra tutte le richieste dello stesso utente, useremo la sessione di quell'utente.
- Per memorizzare le informazioni da condividere tra tutti i componenti che elaborano una richiesta, useremo l'ambito della richiesta.



