Skip to content

17. Beispiel 15 – Integration von Struts 2 und Spring

Im vorherigen Beispiel hatten wir keine Daten mit dem Geltungsbereich Application, die von allen Anfragen aller Benutzer gemeinsam genutzt wurden. Hier zeigen wir ein Beispiel dafür. Zur Umsetzung verwenden wir das Spring-Framework [http://www.springsource.org/]. Spring ist ein äußerst wertvolles Werkzeug. In diesem Beispiel zeigen wir nur einen winzigen Ausschnitt davon. Ein späteres Beispiel wird es intensiver nutzen.

Das Ziel dieser Anwendung ist es, Daten aus dem Bereich Application anzuzeigen.

17.1. Das NetBeans-Projekt

Das NetBeans-Projekt der Anwendung sieht wie folgt aus:

  • in [1]:
  • [web.xml], das die Webanwendung konfiguriert, wird sich gegenüber den vorherigen Versionen weiterentwickeln
  • [applicationContext.xml] ist die Spring-Konfigurationsdatei
  • in [2]: die Ansicht [Context.jsp], die die Daten des Anwendungsbereichs anzeigt
  • in [3]:
  • die Meldungsdatei [messages.properties]
  • die Hauptkonfigurationsdatei von Struts [struts.xml]. Diese wird sich im Vergleich zu den vorherigen Anwendungen weiterentwickeln.
  • in [4]:
  • die Struts-Aktion [Action1.java]
  • die Klasse [Config.java], die die Daten im Anwendungsbereich speichert
  • die sekundäre Struts-Konfigurationsdatei [example.xml]
  • in [5]: die Struts-2-Bibliothek
  • in [6]:
  • die für Spring erforderlichen Archive [spring-core, spring-context, spring-beans, spring-web, commons-logging]
  • das Archiv des Spring-Plugins für Struts 2. Ermöglicht die Integration von Spring in Struts 2 [struts2-spring-plugin]

Im Vergleich zu früheren Versionen:

  • müssen dem Projekt weitere Archive hinzugefügt werden
  • die Dateien [web.xml] und [struts.xml] müssen geändert werden

17.2. Configuration

17.2.1. Die Datei [web.xml]

Die Datei „[web.xml]“ ändert sich wie folgt:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Exemple 14</display-name>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

Die Änderung erfolgt in den Zeilen 12–14. Eine Datei listener wird der Webanwendung hinzugefügt. Beim Start der Webanwendung wird die Klasse instanziiert, die diese Datei listener implementiert. Es handelt sich um eine Spring-Klasse. Diese Klasse nutzt die Datei [WEB-INF/applicationContext.xml]. Diese lautet wie folgt:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  
  <!-- Konfiguration der Beans im Anwendungsbereich -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

</beans>
  • Die Spring-Konfigurationsdatei enthält das Stamm-Tag <beans> (Zeilen 2 und 11). Man könnte „beans“ mit „Objekte“ übersetzen. Spring instanziiert alle Objekte (bean), die in dieser Konfigurationsdatei gefunden werden. Dies geschieht nur einmal, wenn Spring beim Start der Webanwendung aufgerufen wird.
  • Zeilen 7–9: Definieren eine Bean mit dem Namen config (ID). Die Konfigurations-Bean ist der Klasse (class) [example.Config] zugeordnet. Spring wird diese Klasse instanziieren.
  • Zeile 8: Definiert eine Eigenschaft der Klasse [example.Config]. Spring ruft die Methode [example.Config].setNbMaxUsers(10) auf. Die Methode setNbMaxUsers muss also in der Klasse vorhanden sein. Diese lautet wie folgt:

package example;

public class Config {

  private int nbMaxUsers;

  public int getNbMaxUsers() {
    return nbMaxUsers;
  }

  public void setNbMaxUsers(int nbMaxUsers) {
    this.nbMaxUsers = nbMaxUsers;
  }
  
}

Diese Klasse definiert lediglich ein Feld nbMaxUsers mit den zugehörigen Feldern get und set. Wenn man den bisherigen Ausführungen richtig gefolgt ist, wird beim Start der Webanwendung eine Instanz der Klasse [Config] instanziiert, deren Feld nbMaxUsers den Wert 10 erhält. Wir haben zwar nur ein einziges Feld definiert, doch das reicht für unsere Demonstration aus. Wir möchten zeigen, dass dieses Feld, das beispielsweise die maximale Anzahl an Benutzern darstellen könnte, eine Variable mit dem Gültigkeitsbereich Application ist, auf die alle Aktionen zugreifen können. Dies werden wir anhand der Aktion [Action1] veranschaulichen.

17.2.2. Die Datei [struts.xml]

Die Hauptkonfigurationsdatei von Struts lautet 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>
  <!-- Internationalisierung -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- Spring-Integration -->
  <constant name="struts.objectFactory.spring.autoWire" value="name" />

  <include file="example/example.xml"/>

  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index" />
    <action name="index">
      <result type="redirectAction">
        <param name="actionName">Action1</param>
        <param name="namespace">/example</param>
      </result>
    </action>
  </package>

</struts>

Nur Zeile 10 unterscheidet sich von früheren Versionen dieser Datei. Sie definiert eine Struts-Konstante. Von Spring instanziierte Objekte können in andere Objekte injiziert werden. Dies ist die Grundlage von Spring. Hier kann eine Referenz auf das von Spring erstellte Objekt vom Typ [Config] in Struts-Objekte injiziert werden. An dieser Stelle kommt das Spring-Plugin für Struts 2 ins Spiel, das die Integration von Spring in Struts gewährleistet.

Zeile 10 gibt an, dass die Injektion von Spring-Objekten in ein Struts-Objekt automatisch (autowire) anhand des Namens (value) erfolgt. Kehren wir zur Konfigurationsdatei [applicationContext.xml] zurück:


<!-- Konfiguration von Beans mit Anwendungsbereich -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

Was Struts 2 als Namen des Beans bezeichnet, ist hier tatsächlich id. Das bedeutet, dass das instanziierte Bean vom Typ [Config] hier den Namen config trägt.

Die Aktion [Action1.java] lautet wie folgt:


package example;

import com.opensymphony.xwork2.ActionSupport;
...
public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {

  // Konstruktor ohne Parameter
  public Action1() {
  }
  
  // Session, Request, Parameter
  private Map<String, Object> session;
  private Map<String, Object> request;
  private Map<String, String[]> parameters;
  private Config config;

  @Override
  public String execute() {
  ....
    // Anfrage
    request.put("nbMaxUsers", config.getNbMaxUsers());

    // Seitenanzeige JSP
    return SUCCESS;
  }
...
  public Config getConfig() {
    return config;
  }

  public void setConfig(Config config) {
    this.config = config;
  }
}

Die Aktion [Action1] ist identisch mit der in der vorherigen Anwendung, abgesehen von den folgenden Details:

  • Zeile 15: Ein Feld config wurde hinzugefügt. Da es den Namen einer von Spring instanziierten Bean trägt, erhält dieses Feld automatisch eine Referenz auf dieses Objekt. Somit hat die Aktion Zugriff auf die Anwendungskonfiguration bzw. allgemeiner auf die Daten im Bereich Application.
  • Zeile 31: Spring instanziiert das Feld config über seine Methode set. Diese muss daher vorhanden sein.
  • Zeile 21: Die Aktion greift auf die Informationen des Bereichs Application zu. Die maximale Benutzeranzahl nbMaxUsers wird in die Abfrage aufgenommen, damit die Ansicht [Context.jsp] diese anzeigen kann.

17.2.3. Die Datei [example.xml]

Die sekundäre Struts-Konfigurationsdatei ist identisch mit der der vorherigen Version:


<?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>

17.3. Die Ansicht [Context.jsp]

Die Ansicht [Context.jsp] sieht wie folgt aus:


<%@ 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>
    nom : <s:property value="#parameters['nom']"/><br/>
    age : <s:property value="#parameters['age']"/>
    <h3><s:text name="Context.session"/></h3>
    compteur : <s:property value="#session['compteur']"/>
    <h3><s:text name="Context.request"/></h3>
    nbMaxUsers : <s:property value="#request['nbMaxUsers']"/>
  </body>
</html>

17.4. Die Tests

Ein Ausführungsbeispiel lautet wie folgt:

Image