16. Exemplo 13 — o contexto de uma ação
Esta aplicação tem como objetivo demonstrar que uma ação tem acesso:
- aos parâmetros da solicitação
- aos 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. Configuration
A configuração do projeto é feita 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 do URL [/example/Action1] irá provocar a instanciação da classe [example.Action]. Como não é especificado nenhum método, será executado o método execute.
- linha 9: é aceite apenas uma chave. A chave success leva à exibição da vista [Context.JSP].
A arquitetura simplificada do processamento de um pedido será a seguinte:
![]() |
A consulta será processada por dois elementos da aplicação web: a ação [Action1] [1] e a vista [Context.JSP] [2]. Estes dois elementos têm acesso a dados de diferentes tipos:
- dados de âmbito Application, [3] e c.a.d. Dados acessíveis a todas as solicitações de todos os utilizadores. Estes são, na maioria das vezes, de leitura única. É frequente encontrar nestes dados a configuração inicial da aplicação. Neste caso, [Action1] e [Context.JSP] têm acesso a estes dados.
- Dados de âmbito Session, [4] e c.a.d. São dados acessíveis a todas as solicitações de um mesmo utilizador. Estão em modo de leitura/escrita. Aqui, [Action1] utilizará a sessão em modo de leitura/escrita, enquanto [Context.JSP] a utilizará em modo de leitura.
- Dados de âmbito Requête [5], acessíveis a todos os elementos que processam a consulta. Aqui, [Action1] irá colocar um dado nesta memória e [Context.JSP] irá recuperá-lo. Os dados de âmbito «Requête» permitem que um elemento N transmita informação ao elemento N+1.
- Os parâmetros da solicitação [6] enviados pelo cliente. São utilizados em modo de leitura apenas pelos elementos que processam a solicitação.
16.3. A ação [Action1]
O código da 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 {
// construtor sem parâmetros
public Action1() {
}
// Sessão, Pedido, 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));
}
}
// sessão
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));
// pedido
request.put("info1", "information1");
// exibição da página JSP
return SUCCESS;
}
// sessão
public void setSession(Map<String, Object> session) {
this.session = session;
}
// pedido
public void setRequest(Map<String, Object> request) {
this.request = request;
}
// parâmetros
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 da linha 46.
- RequestAware: para aceder ao dicionário de atributos da consulta (linha 17). Esta interface tem apenas um método, o da linha 51.
- ParameterAware: para aceder ao dicionário de parâmetros da consulta (linha 18). Note-se que a cada chave (o nome do parâmetro) corresponde um tabuleiro de valores. Isto é necessário para ter em conta os campos de introdução de dados que enviam vários valores, como, por exemplo, uma lista de seleção múltipla. A interface ParameterAware tem apenas um método, o da linha 56.
- linha 21: o método execute, que é executado quando se solicita a ação [Action1]. Quando este é executado, os interceptores já tiveram de fazer o seu trabalho:
- o método setParameters (linha 56) foi chamado e o dicionário «parameters» da linha 18 contém todos os parâmetros da solicitação.
- o método setSession (linha 46) foi chamado e o dicionário «session» da linha 16 contém todos os atributos da sessão.
- O método setRequest (linha 51) foi chamado e o dicionário request da linha 17 contém todos os atributos do pedido.
- linhas 31-38: grava-se o valor associado à chave compteur na sessão
- linhas 32-34: procura-se a chave compteur na sessão. Se não for encontrada, é adicionada à sessão associada ao valor inteiro 0.
- linhas 35-37: procura-se a chave compteur na sessão, o seu valor é incrementado e, em seguida, a chave é novamente inserida na sessão.
- linha 38: o valor associado à chave compteur é apresentado. Como o incremento é efetuado em cada consulta à ação [Action1], deverá ser possível observar o valor do contador a aumentar à medida que as consultas são efetuadas.
- linha 40: insere-se no dicionário de atributos da solicitação um atributo com a chave info1 e o valor information1. Os atributos de uma solicitação são diferentes dos seus parâmetros. Os parâmetros são enviados pelo cliente da aplicação web. Os atributos da solicitação, por sua vez, permitem a comunicação entre os diferentes elementos da aplicação web que a processam. Assim, após a execução de [Action1], a vista [Context.JSP] será apresentada. Veremos que ela é capaz de recuperar os atributos da solicitação.
- linha 42: o método execute devolve a chave succes.
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] tem como função apresentar:
- alguns parâmetros da consulta
- o valor da chave compteur na sessão
- o valor da chave info1 na consulta
O seu 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: apresentam todos os valores associados ao parâmetro nom
- linhas 15-17: apresentam todos os valores associados ao parâmetro prenom
- linhas 18-20: apresentam todos os valores associados ao parâmetro age
- linha 22: apresenta o valor associado à chave compteur na sessão
- linha 24: apresenta o valor associado à chave info1 na consulta
16.6. Os testes
![]() |
- em [1], Action1 é solicitado sem parâmetros
- em [2], [Context.JSP] não encontrou parâmetros
- em [3], [Context.JSP] encontrou a chave compteur na sessão
- em [4], [Context.JSP] encontrou a chave info1 na consulta
Vamos fazer outro teste:
![]() |
- em [1], Action1 é solicitado com parâmetros
- em [2], [Context.JSP] apresenta esses parâmetros
- em [3], [Context.JSP] encontrou a chave compteur na sessão. O contador foi efetivamente incrementado em 1, demonstrando assim que houve, de facto, memorização entre as duas solicitações.
- em [4], [Context.JSP] encontrou a chave info1 na solicitação
Recorde-se que o método [Action1.execute] escrevia na consola do servidor web. Eis um exemplo:
16.7. Conclusion
É importante ter em conta os seguintes pontos:
- para armazenar informações a partilhar por todas as solicitações de todos os utilizadores, utilizar-se-á a memória da aplicação. Mostraremos um exemplo em breve.
- para armazenar informações a partilhar por todas as solicitações de um mesmo utilizador, utilizar-se-á a sessão desse utilizador.
- Para armazenar informações a partilhar por todos os elementos que processam uma solicitação, utilizar-se-á a memória da solicitação.




