Skip to content

8. Exemplo 06 – A sessão

8.1. O conceito de sessão

Quando um navegador cliente se conecta pela primeira vez a um aplicativo web, ele recebe um token de sessão, uma sequência única de caracteres que ele reenvia a cada nova solicitação que faz ao aplicativo web. Isso permite que o aplicativo reconheça o navegador cliente. A esse token de sessão, ele pode então associar dados. Esses dados pertencem a um único navegador cliente. Assim, à medida que o navegador do cliente envia solicitações, forma-se uma memória.

No exemplo acima, cada usuário (navegador) possui sua própria memória, chamada de sessão. Essa memória é compartilhada por todas as solicitações de um mesmo usuário. Existe também uma memória de nível superior, chamada de memória da aplicação. Essa memória é compartilhada por todas as solicitações de todos os usuários. Geralmente, ela é somente de leitura.

8.2. O projeto NetBeans

O projeto [exemple-06] é obtido por meio de uma cópia do projeto [exemple-05]. Vamos alterar alguns elementos para

  • aproveitar a sessão do usuário.
  • adicionar uma nova ação [Effacer] [1] para limpar o campo de entrada.

8.3. Configuration

O arquivo [struts.xml] passa a ter a seguinte forma:


<?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>
  <!-- internacionalização -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- pacote padrão -->
  <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>
  <!-- pacote de ações -->
  <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>

As linhas 27 a 29 definem uma nova ação [Effacer] associada a uma classe [Effacer]. A resposta a essa ação é a visualização [Saisie.JSP].

8.4. A ação [Confirmer]

Ela evolui da seguinte forma:


package actions;

import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;

public class Confirmer extends ActionSupport implements SessionAware{
  
  // modelo
  private String nom;
  // sessão
  private Map<String, Object> session;
  
  // getters e 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(){
    // colocamos o nome na sessão
    session.put("nom",nom);
    // navegação
    return SUCCESS;
  }
  
}
  • linha 7: a classe [Confirmer] implementa a interface SessionAware. Essa interface possui apenas um método, o método setSession das linhas 25 a 27. Antes da chamada do método execute, um dos interceptadores da solicitação injetará, por meio do método setSession, a sessão do usuário na forma de um dicionário Map<String, Object> (linha 25). Optamos por armazenar esse dicionário no campo session da linha 12.
  • linhas 30-34: o método execute da ação. Quando ele é executado, o campo session já foi inicializado por um dos interceptadores, assim como o campo nom por outro interceptador. Utiliza-se esse dicionário session para armazenar o campo nom. Assim, o nome passará a fazer parte da memória do usuário e estará disponível para todas as suas consultas.

8.5. As visualizações [Confirmation.JSP] e [Saisie.JSP]

A visualização [Confirmation.JSP] permanece inalterada. A visualização [Saisie.JSP] sofre as seguintes alterações:


<%@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>
  • linha 12: inserimos um atributo value na tag <s:textfield>.. Esse atributo define o valor a ser exibido no campo de entrada. Na ausência desse atributo, value = name. Aqui, o valor do atributo é uma expressão OGNL (Object-Graph Navigation Language) da forma %{expression_à_évaluer}. Aqui, a expressão a ser avaliada é #attr['nom']. O atributo nom será procurado na ação atual, na página, na consulta, na sessão e no aplicativo, nessa ordem. Como a ação [Confirmer] insere o atributo nom na sessão, ele será encontrado lá. É o que mostra a seguinte consulta:

Na ação [1], o nome inserido foi ST. Sabemos que a ação [Confirmer] inseriu esse nome na sessão. O link [2] nos leva a URL e [3]. A visualização [Saisie.JSP] é exibida. Para o campo de entrada, o atributo %{#attr['nom']} permite recuperar o nome da sessão.

  • linha 14: o botão [Effacer], que acionará a execução da ação [Effacer] e a exibição da visualização [Saisie.JSP]

<action name="Effacer" class="actions.Effacer">
      <result name="success">/vues/Saisie.JSP</result>
</action>

8.6. A ação [Effacer]

O código da ação [Effacer] é o seguinte:


package actions;

import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;

public class Effacer extends ActionSupport implements SessionAware{
  
  // sessão
  private Map<String, Object> session;
  
  @Override
  public String execute(){
    // recuperando o nome da sessão
    String nom=(String)session.get("nom");
    // removemos da sessão, se necessário
    if(nom!=null){
      session.remove("nom");
    }
    // navegação
    return SUCCESS;
  }

  @Override
  public void setSession(Map<String, Object> map) {
    this.session=map;
  }
}
  • linha 7: a classe [Effacer] implementa a interface [SessionAware], assim como fazia a ação [Confirmer].
  • linha 13: a ação [Effacer] deve apagar o conteúdo do campo de entrada do nome na visualização [Saisie.JSP]. Sabemos que essa visualização busca esse nome na sessão. Portanto, precisamos remover o nome da sessão. É isso que faz o método execute.

Vamos ver como isso funciona:

Na [1], queremos apagar o campo de entrada. Clicamos no botão [Effacer].


<s:submit key="saisie.effacer" action="Effacer"/>

A ação [Effacer] será executada. Em [2], percebe-se que a ação URL chamada foi a da ação [Confirmer]. Isso se deve à tag <s:form> do formulário:


<s:form action="Confirmer">

que faz com que o formulário seja enviado para a ação [Confirmer]. Ao clicar no botão [Effacer], o parâmetro

action:Effacer=Effacer

foi enviado para a ação URL [/actions/Confirmer.action]. O Struts utiliza esse parâmetro para processar os dados enviados pela ação [Effacer]. Essa ação remove o nome da sessão. A página [Saisie.JSP] é a resposta da ação [Effacer]:


<action name="Effacer" class="actions.Effacer">
      <result name="success">/vues/Saisie.JSP</result>
</action>

Essa ação, que exibe o nome da sessão, apresenta então uma string vazia: [3].

Escrevemos vários exemplos simples para apresentar conceitos importantes do Struts 2:

  • a internacionalização das páginas
  • a injeção de parâmetros enviados nos campos das ações
  • o conceito de sessão
  • a articulação entre Ações e Visualizações

Com esses conceitos assimilados, agora estamos aptos a abordar exemplos mais complexos. Começamos apresentando as diferentes tags que podem ser utilizadas em um formulário.