Skip to content

8. Voorbeeld 06 – De sessie

8.1. Het begrip ‘sessie’

Wanneer een clientbrowser voor het eerst verbinding maakt met een webapplicatie, ontvangt deze een sessietoken, een unieke reeks tekens die bij elk nieuw verzoek aan de webapplicatie wordt teruggestuurd. Hierdoor kan de webapplicatie de clientbrowser herkennen. Aan dit sessietoken kan de webapplicatie vervolgens gegevens koppelen. Deze gegevens behoren toe aan één enkele clientbrowser. Zo wordt er, naarmate de clientbrowser verzoeken verstuurt, een geheugen opgebouwd.

Zoals hierboven weergegeven, heeft elke gebruiker (browser) zijn eigen geheugen, dat de sessie wordt genoemd. Dit geheugen wordt gedeeld door alle verzoeken van dezelfde gebruiker. Er bestaat ook een geheugen op een hoger niveau, het applicatiegeheugen genaamd. Dit geheugen wordt gedeeld door alle verzoeken van alle gebruikers. Het is doorgaans alleen-lezen.

8.2. Het NetBeans-project

Het project [exemple-06] is gekopieerd van het project [exemple-05]. We gaan enkele elementen aanpassen om

  • te profiteren van de sessie van de gebruiker.
  • een nieuwe actie [Effacer] [1] toe te voegen om het invoerveld te wissen.

8.3. Configuration

Het bestand [struts.xml] verandert als volgt:


<?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>
  <!-- internationalisering -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- standaardpakket -->
  <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>
  <!-- actiepakket -->
  <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>

De regels 27-29 definiëren een nieuwe actie [Effacer] die is gekoppeld aan een klasse [Effacer]. De reactie op deze actie is de weergave [Saisie.JSP].

8.4. De actie [Confirmer]

Deze ontwikkelt zich als volgt:


package actions;

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

public class Confirmer extends ActionSupport implements SessionAware{
  
  // sjabloon
  private String nom;
  // sessie
  private Map<String, Object> session;
  
  // getters en 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(){
    // de naam wordt in de sessie opgeslagen
    session.put("nom",nom);
    // navigatie
    return SUCCESS;
  }
  
}
  • regel 7: de klasse [Confirmer] implementeert de interface SessionAware. Deze interface heeft slechts één methode, namelijk de methode setSession op de regels 25-27. Voordat de methode execute wordt aangeroepen, zal een van de interceptors van het verzoek via de methode setSession de sessie van de gebruiker invoegen in de vorm van een Map<String, Object>-woordenboek (regel 25). We kiezen ervoor om dit woordenboek op te slaan in het veld session op regel 12.
  • regels 30-34: de methode execute van de actie. Wanneer deze wordt uitgevoerd, is het veld session geïnitialiseerd door een van de interceptors en het veld nom door een andere interceptor. Dit woordenboek session wordt gebruikt om het veld nom daarin op te slaan. Zo wordt de naam opgenomen in het geheugen van de gebruiker en is deze beschikbaar voor al zijn verzoeken.

8.5. De weergaven [Confirmation.JSP] en [Saisie.JSP]

De weergave [Confirmation.JSP] blijft ongewijzigd. De weergave [Saisie.JSP] verandert als volgt:


<%@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>
  • regel 12: we voegen een attribuut value toe aan de tag <s:textfield>.. Dit attribuut bepaalt de waarde die in het invoerveld moet worden weergegeven. Zonder dit attribuut geldt: value = name. Hier is de waarde van het attribuut een OGNL-uitdrukking (Object-Graph Navigation Language) in de vorm %{expression_à_évaluer}. Hier is de uit te voeren uitdrukking #attr['nom']. Het attribuut nom wordt gezocht in de huidige actie, de pagina, de query, de sessie en de applicatie, in die volgorde. Aangezien de actie [Confirmer] het attribuut nom in de sessie plaatst, zal het daar worden gevonden. Dit blijkt uit de volgende query:

In [1] was de ingevoerde naam ST. We weten dat de actie [Confirmer] deze naam in de sessie heeft geplaatst. De link [2] leidt ons naar URL en [3]. De weergave [Saisie.JSP] wordt weergegeven. Voor het invoerveld maakt het attribuut %{#attr['nom']} het mogelijk om de naam in de sessie op te halen.

  • regel 14: de knop [Effacer] die de uitvoering van de actie [Effacer] en de weergave van de weergave [Saisie.JSP] in gang zet

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

8.6. De actie [Effacer]

De code van de actie [Effacer] is als volgt:


package actions;

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

public class Effacer extends ActionSupport implements SessionAware{
  
  // sessie
  private Map<String, Object> session;
  
  @Override
  public String execute(){
    // de naam uit de sessie ophalen
    String nom=(String)session.get("nom");
    // indien nodig uit de sessie verwijderen
    if(nom!=null){
      session.remove("nom");
    }
    // navigatie
    return SUCCESS;
  }

  @Override
  public void setSession(Map<String, Object> map) {
    this.session=map;
  }
}
  • regel 7: de klasse [Effacer] implementeert de interface [SessionAware], net zoals de actie [Confirmer] dat deed.
  • regel 13: de actie [Effacer] moet de inhoud van het invoerveld voor de naam in de weergave [Saisie.JSP] wissen. We weten dat deze weergave deze naam uit de sessie haalt. We moeten de naam dus uit de sessie verwijderen. Dat is wat de methode execute doet.

Laten we eens kijken wat het resultaat is:

In [1] willen we het invoerveld wissen. We klikken op de knop [Effacer].


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

De actie [Effacer] wordt uitgevoerd. In [2] zien we dat de aangeroepen URL die van de actie [Confirmer] was. Dit komt door de tag <s:form> in het formulier:


<s:form action="Confirmer">

waardoor het formulier wordt verzonden naar de actie [Confirmer]. Bij het klikken op de knop [Effacer] wordt de parameter

action:Effacer=Effacer

verzonden naar de actie URL [/actions/Confirmer.action]. Struts gebruikt deze parameter om de verzonden gegevens te laten verwerken door de actie [Effacer]. Deze actie verwijdert de sessienaam. De pagina [Saisie.JSP] is het antwoord op de actie [Effacer]:


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

Deze actie, die de sessienaam weergeeft, geeft vervolgens een lege tekenreeks weer: [3].

We hebben een aantal eenvoudige voorbeelden geschreven om belangrijke concepten van Struts 2 te introduceren:

  • de internationalisering van pagina's
  • het invoeren van verzonden parameters in de velden van acties
  • het concept van de sessie
  • de koppeling tussen acties en weergaven

Nu we deze concepten onder de knie hebben, kunnen we complexere voorbeelden gaan behandelen. We beginnen met een overzicht van de verschillende tags die in een formulier kunnen worden gebruikt.