Skip to content

8. Beispiel 06 – Die Sitzung

8.1. Das Konzept einer Sitzung

Wenn sich ein Client-Browser zum ersten Mal mit einer Webanwendung verbindet, erhält er ein Sitzungstoken, eine eindeutige Zeichenfolge, die er bei jeder neuen Anfrage an die Webanwendung zurücksendet. Dadurch kann die Webanwendung den Client-Browser erkennen. Die Webanwendung kann dann Daten mit diesem Sitzungstoken verknüpfen. Diese Daten gehören zu einem einzelnen Client-Browser. So wird mit jeder Anfrage des Client-Browsers ein Speicher aufgebaut.

Wie oben dargestellt, verfügt jeder Benutzer (Browser) über einen eigenen Speicher, der als Sitzung bezeichnet wird. Dieser Speicher wird von allen Anfragen desselben Benutzers gemeinsam genutzt. Es gibt außerdem einen übergeordneten Speicher, den sogenannten Anwendungsspeicher. Dieser Speicher wird von allen Anfragen aller Benutzer gemeinsam genutzt. Er ist in der Regel schreibgeschützt.

8.2. Das NetBeans-Projekt

Das Projekt [example-06] wird durch Kopieren des Projekts [example-05] erstellt. Wir werden einige Elemente ändern, um

  • die Vorteile der Benutzersitzung zu nutzen.
  • Fügen Sie eine neue Aktion [Clear] [1] hinzu, um das Eingabefeld zu löschen.

8.3. Konfiguration

Die Datei [struts.xml] ändert sich wie folgt:


<?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>
  <!-- internationalization -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- default package -->
  <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>
  <!-- equity package -->
  <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>

Die Zeilen 27–29 definieren eine neue Aktion [Delete], die mit einer Klasse [Delete] verknüpft ist. Die Antwort auf diese Aktion ist die Ansicht [Input.jsp].

8.4. Die Aktion [Confirm]

Sie verläuft wie folgt:


package actions;
 
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
 
public class Confirmer extends ActionSupport implements SessionAware{
 
  // model
  private String nom;
  // session
  private Map<String, Object> session;
 
  // getters and 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(){
    // put the name in the session
    session.put("nom",nom);
    // navigation
    return SUCCESS;
  }
 
}
  • Zeile 7: Die Klasse [Confirm] implementiert die Schnittstelle SessionAware. Diese Schnittstelle verfügt nur über eine Methode, die Methode setSession in den Zeilen 25–27. Bevor die Methode execute aufgerufen wird, fügt einer der Request-Interceptors über die Methode setSession die Sitzung des Benutzers in Form eines Map<String, Object>-Wörterbuchs ein (Zeile 25). Wir entscheiden uns dafür, dieses Wörterbuch im Feld `session` in Zeile 12 zu speichern.
  • Zeilen 30–34: Die `execute`-Methode der Aktion. Bei ihrer Ausführung wurde das Feld „session“ bereits von einem der Interceptors initialisiert, das Feld „name“ von einem anderen Interceptor. Wir verwenden dieses Session-Dictionary, um das Feld „name“ zu speichern. Somit wird der Name Teil der Benutzersitzung und steht für alle dessen Anfragen zur Verfügung.

8.5. Die Ansichten [Confirmation.jsp] und [Saisie.jsp]

Die Ansicht [Confirmation.jsp] bleibt unverändert. Die Ansicht [Saisie.jsp] ändert sich wie folgt:


<%@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>
  • Zeile 12: Wir fügen dem `<s:textfield>`-Tag ein `value`-Attribut hinzu. Dieses Attribut legt den Wert fest, der im Eingabefeld angezeigt werden soll. Wird dieses Attribut weggelassen, ist der Standardwert von `value` `name`. Hier ist der Wert des Attributs ein OGNL-Ausdruck (Object-Graph Navigation Language) in der Form `%{expression_to_evaluate}`. Hier lautet der auszuwertende Ausdruck #attr['name']. Das Attribut „name“ wird in der aktuellen Aktion, auf der Seite, in der Anfrage, in der Sitzung und in der Anwendung in dieser Reihenfolge gesucht. Da die Aktion [Confirm] das Attribut „name“ in der Sitzung ablegt, wird es dort gefunden. Dies wird durch die folgende Anfrage veranschaulicht:

In [1] lautete der eingegebene Name ST. Wir wissen, dass die Aktion [Confirm] diesen Namen in der Sitzung abgelegt hat. Der Link [2] führt uns zur URL [3]. Die Ansicht [Saisie.jsp] wird angezeigt. Für das Eingabefeld ruft das Attribut %{#attr['name']} den Namen aus der Sitzung ab.

  • Zeile 14: die Schaltfläche [Clear], die die Ausführung der Aktion [Clear] und die Anzeige der Ansicht [Saisie.jsp] auslöst

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

8.6. Die Aktion [Löschen]

Der Code für die Aktion [Löschen] lautet wie folgt:


package actions;
 
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
 
public class Effacer extends ActionSupport implements SessionAware{
 
  // session
  private Map<String, Object> session;
 
  @Override
  public String execute(){
    // retrieve the name from the session
    String nom=(String)session.get("nom");
    // remove it from the session if necessary
    if(nom!=null){
      session.remove("nom");
    }
    // navigation
    return SUCCESS;
  }
 
  @Override
  public void setSession(Map<String, Object> map) {
    this.session=map;
  }
}

  • Zeile 7: Die Klasse [Delete] implementiert die Schnittstelle [SessionAware], genau wie die Aktion [Confirm].
  • Zeile 13: Die Aktion [Delete] muss den Inhalt des Namens-Eingabefelds in der Ansicht [Input.jsp] löschen. Wir wissen, dass diese Ansicht diesen Namen aus der Sitzung abruft. Wir müssen daher den Namen aus der Sitzung entfernen. Genau das tut die Methode execute.

Schauen wir uns an, wie das funktioniert:

In [1] möchten wir das Eingabefeld löschen. Wir klicken auf die Schaltfläche [Löschen].


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

Die Aktion [Löschen] wird ausgeführt. In [2] stellen wir fest, dass die aufgerufene URL die der Aktion [Bestätigen] war. Dies ist auf das <s:form>-Tag im Formular zurückzuführen:


<s:form action="Confirmer">

wodurch das Formular an die Aktion [Bestätigen] übermittelt wird. Wenn die Schaltfläche [Löschen] angeklickt wird, wird der Parameter

action:Delete=Delete

an die URL [/actions/Confirm.action] gesendet. Struts verwendet diesen Parameter, um die von der Aktion [Delete] gesendeten Daten zu verarbeiten. Diese Aktion entfernt den Sitzungsnamen. Die Seite [Input.jsp] ist die Antwort auf die Aktion [Delete]:


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

Diese Aktion, die den Sitzungsnamen anzeigt, gibt anschließend eine leere Zeichenfolge aus [3].

Wir haben mehrere einfache Beispiele geschrieben, um wichtige Konzepte von Struts 2 vorzustellen:

  • Internationalisierung von Seiten
  • Einfügen von übermittelten Parametern in Aktionsfelder
  • das Konzept von Sitzungen
  • die Beziehung zwischen Actions und Views

Nachdem wir diese Konzepte nun beherrschen, sind wir bereit, komplexere Beispiele anzugehen. Wir beginnen mit der Vorstellung der verschiedenen Tags, die in einem Formular verwendet werden können.