16. Exemplo 13 - O contexto de uma ação
Esta aplicação tem como objetivo demonstrar que uma ação tem acesso a:
- parâmetros de solicitação
- atributos da solicitação
- aos atributos da sessão do utilizador

16.1. O projeto NetBeans
![]() |
O projeto NetBeans é o seguinte:
- em [1], a vista [Context.jsp]
- em [2], a ação [Action1.java] e o ficheiro de configuração do Struts [example.xml]
16.2. Configuração
A configuração do projeto é definida em [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>
- Linha 8: O pedido para o URL [/example/Action1] irá desencadear a instanciação da classe [example.Action]. Uma vez que não é especificado nenhum método, o método execute será executado.
- Linha 9: Apenas uma chave é aceite. A chave «success» faz com que a vista [Context.jsp] seja apresentada.
A arquitetura simplificada para o processamento de uma solicitação é a seguinte:
![]() |
A solicitação será processada por dois componentes da aplicação web: a ação [Action1] [1] e a visualização [Context.jsp] [2]. Estes dois componentes têm acesso a diferentes tipos de dados:
- Dados no âmbito da aplicação [3], ou seja, dados acessíveis a todas as solicitações de todos os utilizadores. São quase sempre de leitura única. Estes dados contêm frequentemente a configuração inicial da aplicação. Aqui, [Action1] e [Context.jsp] têm acesso a estes dados.
- Dados no âmbito da sessão [4], ou seja, dados acessíveis a todos os pedidos do mesmo utilizador. Estes dados são de leitura/gravação. Aqui, [Action1] utilizará a sessão no modo de leitura/gravação, enquanto [Context.jsp] a utilizará no modo de leitura apenas.
- Dados no âmbito da solicitação [5], acessíveis a todos os elementos que processam a solicitação. Aqui, [Action1] armazenará dados nesta memória, e [Context.jsp] irá recuperá-los. Os dados no âmbito da solicitação permitem que o elemento N passe informações para o elemento N+1.
- Parâmetros de solicitação [6] enviados pelo cliente. São utilizados em modo de leitura apenas pelos componentes que processam a solicitação.
16.3. A ação [Action1]
O código para a classe [Action1] é o seguinte:
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;
}
}
- linha 10: a classe implementa as seguintes interfaces
- SessionAware: para aceder ao dicionário de atributos da sessão (linha 16). Esta interface tem apenas um método, o que se encontra na linha 46.
- RequestAware: para aceder ao dicionário de atributos da solicitação (linha 17). Esta interface tem apenas um método, o que se encontra na linha 51.
- ParameterAware: para aceder ao dicionário de parâmetros da solicitação (linha 18). Note-se que cada chave (o nome do parâmetro) corresponde a uma matriz de valores. Isto é necessário para lidar com campos de entrada que enviam vários valores, como uma lista de seleção múltipla. A interface ParameterAware tem apenas um método, o que se encontra na linha 56.
- Linha 21: o método execute, que é executado quando a ação [Action1] é solicitada. No momento em que é executado, os interceptores já cumpriram a sua função:
- o método setParameters (linha 56) foi chamado e o dicionário de parâmetros na linha 18 contém todos os parâmetros da solicitação.
- O método setSession (linha 46) foi chamado, e o dicionário de sessão na linha 16 contém todos os atributos de sessão.
- O método setRequest (linha 51) foi chamado, e o dicionário de solicitação na linha 17 contém todos os atributos da solicitação.
- Linhas 31–38: O valor associado à chave `compteur` é gravado na sessão
- Linhas 32–34: A chave `compteur` é procurada na sessão. Se não for encontrada, é adicionada com o valor inteiro 0.
- Linhas 35–37: A chave `counter` é procurada na sessão, o seu valor é incrementado e, em seguida, a chave é devolvida à sessão.
- Linha 38: o valor associado à chave `counter` é exibido. Uma vez que o incremento é realizado com cada pedido na ação [Action1], devemos ver o valor do contador aumentar à medida que os pedidos são efetuados.
- Linha 40: Um atributo com a chave `info1` e o valor `information1` é inserido no dicionário de atributos da solicitação. Os atributos da solicitação são diferentes dos parâmetros da solicitação. Os parâmetros são enviados pelo cliente da aplicação web. Os atributos da solicitação, por outro lado, permitem a comunicação entre os vários componentes da aplicação web que processam a solicitação. Assim, após a execução de [Action1], a visualização [Context.jsp] será exibida. Veremos que é capaz de recuperar os atributos da solicitação.
- Linha 42: O método execute retorna a chave "success".
16.4. O ficheiro de mensagens
O ficheiro [messages.properties] é o seguinte:
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. A vista [Context.jsp]
A vista [Context.jsp] é responsável por apresentar:
- determinados parâmetros de solicitação
- o valor da chave do contador na sessão
- o valor da chave info1 na solicitação
O código é o seguinte:
<%@ 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>
- Linhas 12–14: exibem todos os valores associados ao parâmetro «name»
- linhas 15-17: exibem todos os valores associados ao parâmetro 'first_name'
- linhas 18-20: exibem todos os valores associados ao parâmetro «age»
- linha 22: exibe o valor associado à chave counter na sessão
- linha 24: exibe o valor associado à chave info1 na consulta
16.6. Os testes
![]() |
- Em [1], a Action1 é chamada sem parâmetros
- em [2], [Context.jsp] não encontrou quaisquer parâmetros
- em [3], [Context.jsp] encontrou a chave counter na sessão
- em [4], [Context.jsp] encontrou a chave info1 na solicitação
Vamos fazer outro teste:
![]() |
- Em [1], a Action1 é solicitada com parâmetros
- Em [2], [Context.jsp] apresenta estes parâmetros
- Em [3], [Context.jsp] encontrou a chave «compteur» na sessão. O contador foi, de facto, incrementado em 1, demonstrando que os dados foram retidos com sucesso entre os dois pedidos.
- Em [4], [Context.jsp] encontrou a chave «info1» na solicitação
Recorde-se que o método [Action1.execute] escreveu na consola do servidor web. Aqui está um exemplo:
16.7. Conclusão
Tenha em mente os seguintes pontos:
- Para armazenar informações a serem partilhadas entre todos os pedidos de todos os utilizadores, utilizaremos a memória da aplicação. Mostraremos um exemplo disso em breve.
- Para armazenar informações a serem partilhadas por todas as solicitações do mesmo utilizador, utilizaremos a sessão desse utilizador.
- Para armazenar informações a serem partilhadas por todos os componentes que processam uma solicitação, utilizaremos o âmbito da solicitação.



