16. Ejemplo 13: el contexto de una acción
Esta aplicación tiene como objetivo mostrar que una acción tiene acceso a:
- a los parámetros de la consulta
- a los atributos de la solicitud
- a los atributos de la sesión del usuario
![]() |
16.1. El proyecto NetBeans
![]() |
El proyecto de NetBeans es el siguiente:
- en [1], la vista [Context.JSP]
- en [2], la acción [Action1.java] y el archivo de configuración de Struts [example.xml]
16.2. Configuration
La configuración del proyecto se realiza en [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>
- línea 8: la solicitud de URL [/example/Action1] provocará la instanciación de la clase [example.Action]. Como no se especifica ningún método, se ejecutará el método execute.
- línea 9: solo se acepta una clave. La clave success da lugar a la visualización de la vista [Context.JSP].
La arquitectura simplificada para el procesamiento de una consulta será la siguiente:
![]() |
La solicitud será procesada por dos elementos de la aplicación web: la acción [Action1] [1] y la vista [Context.JSP] [2]. Estos dos elementos tienen acceso a datos de diferente naturaleza:
- datos de ámbito Application, [3] y c.a.d. Estos son accesibles para todas las solicitudes de todos los usuarios y, casi siempre, son de solo lectura. A menudo, en estos datos se encuentra la configuración inicial de la aplicación. En este caso, [Action1] y [Context.JSP] tienen acceso a estos datos.
- Datos de ámbito Session, [4] y c.a.d. Son datos accesibles para todas las consultas de un mismo usuario. Son de lectura y escritura. Aquí, [Action1] utilizará la sesión en modo de lectura y escritura, mientras que [Context.JSP] la utilizará en modo de lectura.
- Datos de ámbito Requête y [5], accesibles para todos los elementos que procesan la consulta. Aquí, [Action1] almacenará un dato en esta memoria y [Context.JSP] lo recuperará. Los datos de ámbito «Consulta» permiten que un elemento N transmita información al elemento N+1.
- Los parámetros de la solicitud [6] enviados por el cliente. Los elementos que procesan la solicitud los utilizan en modo de solo lectura.
16.3. La acción [Action1]
El código de la clase [Action1] es el siguiente:
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 sin parámetros
public Action1() {
}
// Sesión, solicitud, parámetros
Map<String, Object> session;
Map<String, Object> request;
Map<String, String[]> parameters;
@Override
public String execute() {
// lista de parámetros
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));
}
}
// sesión
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));
// solicitud
request.put("info1", "information1");
// visualización de la página JSP
return SUCCESS;
}
// sesión
public void setSession(Map<String, Object> session) {
this.session = session;
}
// solicitud
public void setRequest(Map<String, Object> request) {
this.request = request;
}
// parámetros
public void setParameters(Map<String, String[]> parameters) {
this.parameters = parameters;
}
}
- línea 10: la clase implementa las siguientes interfaces
- SessionAware: para tener acceso al diccionario de atributos de la sesión (línea 16). Esta interfaz solo tiene un método, el de la línea 46.
- RequestAware: para tener acceso al diccionario de atributos de la consulta (línea 17). Esta interfaz solo tiene un método, el de la línea 51.
- ParameterAware: para acceder al diccionario de parámetros de la consulta (línea 18). Cabe señalar que a cada clave (el nombre del parámetro) le corresponde una tabla de valores. Esto es necesario para tomar en cuenta los campos de entrada que envían varios valores, como por ejemplo una lista de selección múltiple. La interfaz ParameterAware solo tiene un método, el de la línea 56.
- línea 21: el método execute, que se ejecuta cuando se solicita la acción [Action1]. Cuando se ejecuta, los interceptores ya han hecho su trabajo:
- se ha llamado al método setParameters (línea 56) y el diccionario parameters de la línea 18 contiene todos los parámetros de la solicitud.
- se ha llamado al método setSession (línea 46) y el diccionario «session» de la línea 16 contiene todos los atributos de la sesión.
- Se ha llamado al método setRequest (línea 51) y el diccionario request de la línea 17 contiene todos los atributos de la solicitud.
- líneas 31-38: se escribe el valor asociado a la clave compteur en la sesión
- líneas 32-34: se busca la clave compteur en la sesión. Si no se encuentra, se agrega asociándola al valor entero 0.
- líneas 35-37: se busca la clave compteur en la sesión, se incrementa su valor y luego se vuelve a guardar la clave en la sesión.
- línea 38: se muestra el valor asociado a la clave compteur. Dado que el incremento se realiza con cada consulta sobre la acción [Action1], deberíamos ver cómo aumenta el valor del contador a medida que se realizan las consultas.
- línea 40: se inserta en el diccionario de atributos de la solicitud un atributo con la clave info1 y el valor information1. Los atributos de una solicitud son distintos de sus parámetros. Los parámetros son enviados por el cliente de la aplicación web. Los atributos de la solicitud, por su parte, permiten la comunicación entre los distintos elementos de la aplicación web que la procesan. Así, tras la ejecución de [Action1], se mostrará la vista [Context.JSP]. Veremos que esta es capaz de recuperar los atributos de la solicitud.
- línea 42: el método execute devuelve la clave succes.
16.4. El archivo de mensajes
El archivo [messages.properties] es el siguiente:
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] tiene como función mostrar:
- algunos parámetros de la consulta
- el valor de la clave compteur en la sesión
- el valor de la clave info1 en la consulta
Su código es el siguiente:
<%@ 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>
- líneas 12-14: muestran todos los valores asociados al parámetro nom
- líneas 15-17: muestran todos los valores asociados al parámetro prenom
- líneas 18-20: muestran todos los valores asociados al parámetro age
- línea 22: muestra el valor asociado a la clave compteur en la sesión
- línea 24: muestra el valor asociado a la clave info1 en la consulta
16.6. Las pruebas
![]() |
- en [1], se solicita Action1 sin parámetros
- en [2], [Context.JSP] no encontró parámetros
- en [3], [Context.JSP] encontró la clave compteur en la sesión
- en [4], [Context.JSP] encontró la clave info1 en la consulta
Hagamos otra prueba:
![]() |
- en [1], se solicita Action1 con parámetros
- en [2], [Context.JSP] muestra estos parámetros
- en [3], [Context.JSP] encontró la clave compteur en la sesión. El contador se incrementó correctamente en 1, lo que demuestra que sí hubo almacenamiento entre las dos solicitudes.
- En [4], [Context.JSP] encontró la clave info1 en la solicitud
Recordemos que el método [Action1.execute] escribía en la consola del servidor web. He aquí un ejemplo:
16.7. Conclusion
Recordemos los siguientes puntos:
- Para almacenar información que deban compartir todas las solicitudes de todos los usuarios, se utilizará la memoria de la aplicación. Pronto mostraremos un ejemplo de esto.
- Para almacenar información que deben compartir todas las solicitudes de un mismo usuario, se utilizará la sesión de dicho usuario.
- Para almacenar información que deben compartir todos los componentes que procesan una solicitud, se utilizará la memoria de la solicitud.




