Skip to content

16. Beispiel 13 – Der Kontext einer Aktion

Diese Anwendung soll zeigen, dass eine Aktion Zugriff hat auf:

  • auf die Parameter der Anfrage
  • auf die Attribute der Anfrage
  • auf die Attribute der Benutzersitzung

Image

16.1. Das NetBeans-Projekt

Das NetBeans-Projekt lautet wie folgt:

  • in [1], die Ansicht [Context.jsp]
  • in [2] die Aktion [Action1.java] und die Struts-Konfigurationsdatei [example.xml]

16.2. Configuration

Die Projektkonfiguration erfolgt in [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>
  • Zeile 8: Die Anfrage an die URL [/example/Action1] führt zur Instanziierung der Klasse [example.Action]. Da keine Methode angegeben ist, wird die Methode execute ausgeführt.
  • Zeile 9: Es wird nur ein Schlüssel akzeptiert. Der Schlüssel success führt zur Anzeige der Ansicht [Context.jsp].

Die vereinfachte Architektur zur Bearbeitung einer Anfrage sieht wie folgt aus:

Die Anfrage wird von zwei Elementen der Webanwendung verarbeitet: der Aktion [Action1] [1] und der Ansicht [Context.jsp] [2]. Diese beiden Elemente haben Zugriff auf Daten unterschiedlicher Art:

  • Daten mit dem Geltungsbereich Application, [3] und c.a.d. Diese Daten sind für alle Anfragen aller Benutzer zugänglich. Sie sind fast immer schreibgeschützt. In diesen Daten findet man häufig die Anfangskonfiguration der Anwendung. Hier haben [Action1] und [Context.jsp] Zugriff auf diese Daten.
  • Daten mit dem Geltungsbereich Session, [4], c.a.d. Diese Daten sind für alle Anfragen desselben Benutzers zugänglich. Sie sind schreib- und lesbar. Hier nutzt [Action1] die Sitzung im Lese-/Schreibmodus, während [Context.jsp] sie im Lesemodus nutzt.
  • Daten im Bereich Requête [5], die für alle Elemente zugänglich sind, die die Anfrage bearbeiten. Hier wird [Action1] einen Wert in diesen Speicher schreiben und [Context.jsp] ihn abrufen. Daten im Abfrage-Gültigkeitsbereich ermöglichen es einem Element N, Informationen an das Element N+1 weiterzugeben.
  • Die vom Client gesendeten Parameter der Anfrage [6]. Sie werden von den Elementen, die die Anfrage bearbeiten, nur zum Lesen verwendet.

16.3. Die Aktion [Action1]

Der Code der Klasse [Action1] lautet wie folgt:


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 {

  // Konstruktor ohne Parameter
  public Action1() {
  }
  // Sitzung, Anfrage, Parameter
  Map<String, Object> session;
  Map<String, Object> request;
  Map<String, String[]> parameters;

  @Override
  public String execute() {
    // Liste der Parameter
    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));
      }
    }
    // Sitzung
    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));
    // Anfrage
    request.put("info1", "information1");
    // Seitenanzeige JSP
    return SUCCESS;
  }

  // Sitzung
  public void setSession(Map<String, Object> session) {
    this.session = session;
  }

  // Anfrage
  public void setRequest(Map<String, Object> request) {
    this.request = request;
  }

  // Parameter
  public void setParameters(Map<String, String[]> parameters) {
    this.parameters = parameters;
  }
}
  • Zeile 10: Die Klasse implementiert die folgenden Schnittstellen
  • SessionAware: für den Zugriff auf das Attributwörterbuch der Sitzung (Zeile 16). Diese Schnittstelle verfügt nur über eine Methode, nämlich die in Zeile 46.
  • RequestAware: für den Zugriff auf das Attributverzeichnis der Abfrage (Zeile 17). Diese Schnittstelle hat nur eine Methode, nämlich die in Zeile 51.
  • ParameterAware: für den Zugriff auf das Parameterverzeichnis der Abfrage (Zeile 18). Es ist zu beachten, dass einem Schlüssel (dem Namen des Parameters) ein Wertearray zugeordnet ist. Dies ist erforderlich, um Eingabefelder zu berücksichtigen, die mehrere Werte übermitteln, wie beispielsweise eine Mehrfachauswahlliste. Die Schnittstelle ParameterAware verfügt nur über eine Methode, nämlich die in Zeile 56.
  • Zeile 21: Die Methode execute, die ausgeführt wird, wenn die Aktion [Action1] angefordert wird. Bei ihrer Ausführung haben die Interceptoren ihre Arbeit bereits erledigt:
  • Die Methode setParameters (Zeile 56) wurde aufgerufen, und das Parameter-Dictionary in Zeile 18 enthält alle Parameter der Anfrage.
  • Die Methode setSession (Zeile 46) wurde aufgerufen, und das Dictionary „session“ in Zeile 16 enthält alle Attribute der Sitzung.
  • Die Methode setRequest (Zeile 51) wurde aufgerufen, und das Dictionary „request“ in Zeile 17 enthält alle Attribute der Anfrage.
  • Zeilen 31–38: Der dem Schlüssel compteur zugeordnete Wert wird in die Sitzung geschrieben
  • Zeilen 32–34: Der Schlüssel compteur wird in der Sitzung gesucht. Ist er dort nicht vorhanden, wird er dort mit dem ganzzahligen Wert 0 verknüpft.
  • Zeilen 35–37: Der Schlüssel compteur wird in der Sitzung gesucht, sein Wert wird erhöht und anschließend wird der Schlüssel wieder in die Sitzung geschrieben.
  • Zeile 38: Der dem Schlüssel compteur zugeordnete Wert wird angezeigt. Da die Inkrementierung bei jeder Abfrage der Aktion [Action1] erfolgt, sollte man beobachten können, wie der Wert des Zählers im Laufe der Abfragen ansteigt.
  • Zeile 40: In das Attributwörterbuch der Anfrage wird ein Attribut mit dem Schlüssel „info1“ und dem Wert „information1“ eingefügt. Die Attribute einer Anfrage unterscheiden sich von ihren Parametern. Die Parameter werden vom Client der Webanwendung gesendet. Die Attribute der Anfrage ermöglichen hingegen die Kommunikation zwischen den verschiedenen Elementen der Webanwendung, die sie verarbeiten. So wird nach der Ausführung von [Action1] die Ansicht [Context.jsp] angezeigt. Wir werden sehen, dass sie in der Lage ist, die Attribute der Anfrage abzurufen.
  • Zeile 42: Die Methode execute gibt den Schlüssel succes zurück.

16.4. Die Meldungsdatei

Die Datei [messages.properties] sieht wie folgt aus:


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. Die Ansicht [Context.jsp]

Die Ansicht [Context.jsp] dient dazu, Folgendes anzuzeigen:

  • bestimmte Parameter der Abfrage
  • den Wert des Schlüssels compteur in der Sitzung
  • den Wert des Schlüssels info1 in der Abfrage

Ihr Code lautet wie folgt:


<%@ 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>
  • Zeilen 12–14: zeigen alle Werte an, die dem Parameter nom zugeordnet sind
  • Zeilen 15–17: zeigen alle Werte an, die dem Parameter prenom zugeordnet sind
  • Zeilen 18–20: Zeigen alle Werte an, die mit dem Parameter age verknüpft sind
  • Zeile 22: Zeigt den Wert an, der dem Schlüssel compteur in der Sitzung zugeordnet ist
  • Zeile 24: Zeigt den Wert an, der dem Schlüssel info1 in der Abfrage zugeordnet ist

16.6. Die Tests

  • in [1], Action1 wird ohne Parameter
  • bei [2] wurden für [Context.jsp] keine Parameter gefunden
  • in [3], [Context.jsp] wurde der Schlüssel compteur in der Sitzung gefunden
  • in [4], [Context.jsp] hat den Schlüssel info1 in der Abfrage gefunden

Machen wir einen weiteren Test:

  • in [1] wird Action1 mit den Parametern
  • in [2], [Context.jsp] zeigt diese Parameter an
  • bei [3] hat [Context.jsp] den Schlüssel compteur in der Sitzung gefunden. Der Zähler wurde tatsächlich um 1 erhöht, was zeigt, dass zwischen den beiden Anfragen tatsächlich eine Speicherung stattgefunden hat.
  • In [4] hat [Context.jsp] den Schlüssel info1 in der Anfrage gefunden

Wir erinnern uns, dass die Methode [Action1.execute] Ausgaben auf die Konsole des Webservers schrieb. Hier ein Beispiel:

1
2
3
4
5
6
7
Paramètres...
[prenom,y]
[prenom,y2]
[age,z]
[nom,x]
Session...
compteur=2

16.7. Conclusion

Beachten Sie folgende Punkte:

  • Um Informationen zu speichern, die von allen Anfragen aller Benutzer gemeinsam genutzt werden sollen, verwenden wir den Anwendungsspeicher. Wir werden dazu in Kürze ein Beispiel zeigen.
  • Um Informationen zu speichern, die von allen Anfragen desselben Benutzers gemeinsam genutzt werden sollen, verwenden wir dessen Sitzung.
  • Um Informationen zu speichern, die von allen Komponenten, die eine Anfrage bearbeiten, gemeinsam genutzt werden sollen, wird der Speicher der Anfrage verwendet.