Skip to content

17. Esempio 15 – Integrazione Struts 2 / Spring

Nell'esempio precedente non avevamo dati nell'ambito dell'applicazione condivisi tra tutte le richieste di tutti gli utenti. Ne mostreremo un esempio qui. Per implementarlo, useremo il framework Spring [http://www.springsource.org/]. Spring è uno strumento estremamente prezioso. In questo esempio ne mostriamo solo una piccola parte. Un esempio successivo lo utilizzerà in modo più esteso.

Lo scopo di questa applicazione è visualizzare i dati a livello di applicazione.

17.1. Il progetto NetBeans

Il progetto NetBeans per l'applicazione è il seguente:

  • in [1]:
  • [web.xml], che configura l'applicazione web, cambierà rispetto a quanto previsto nelle versioni precedenti
  • [applicationContext.xml] è il file di configurazione Spring
  • in [2]: la vista [Context.jsp], che visualizzerà i dati a livello di applicazione
  • in [3]:
  • il file dei messaggi [messages.properties]
  • il file di configurazione principale di Struts [struts.xml]. Cambierà rispetto alle applicazioni precedenti.
  • in [4]:
  • l'azione Struts [Action1.java]
  • la classe [Config.java], che memorizzerà i dati a livello di applicazione
  • il file di configurazione secondario di Struts [example.xml]
  • in [5]: la libreria Struts 2
  • in [6]:
  • gli archivi necessari per Spring [spring-core, spring-context, spring-beans, spring-web, commons-logging]
  • l'archivio del plugin Spring per Struts 2. Consente l'integrazione di Spring con Struts 2 [struts2-spring-plugin]

Rispetto alle versioni precedenti:

  • è necessario aggiungere gli archivi al progetto
  • modificare i file [web.xml] e [struts.xml]

17.2. Configurazione

17.2.1. Il file [web.xml]

Il file [web.xml] viene modificato come segue:


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

La modifica riguarda le righe 12–14. Viene aggiunto un listener all'applicazione web. All'avvio dell'applicazione web, verrà istanziata la classe che implementa questo listener. Si tratta di una classe Spring. Questa classe utilizzerà il file [WEB-INF/applicationContext.xml]. Il file è il seguente:


<?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">
 
  <!-- application scope bean configuration -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>
 
</beans>
  • Il file di configurazione di Spring ha il tag radice <beans> (righe 2 e 11). I bean possono essere considerati come oggetti. Spring istanzierà tutti gli oggetti (bean) presenti in questo file di configurazione. Lo fa una sola volta, quando il listener di Spring viene avviato all'avvio dell'applicazione web.
  • Righe 7–9: definiscono un bean denominato config (id). Il bean config è associato alla classe [example.Config]. Spring istanzierà questa classe.
  • Riga 8: definisce una proprietà della classe [example.Config]. Spring chiamerà il metodo [example.Config].setNbMaxUsers(10). Pertanto, il metodo setNbMaxUsers deve esistere nella classe. È il seguente:

package example;
 
public class Config {
 
  private int nbMaxUsers;
 
  public int getNbMaxUsers() {
    return nbMaxUsers;
  }
 
  public void setNbMaxUsers(int nbMaxUsers) {
    this.nbMaxUsers = nbMaxUsers;
  }
 
}

Questa classe definisce un solo campo, nbMaxUsers, con i relativi metodi get e set. Se avete seguito il procedimento, all'avvio dell'applicazione web viene istanziata un'istanza della classe [Config] con il valore 10 per il campo nbMaxUsers. Abbiamo definito un solo campo, ma è sufficiente per la nostra dimostrazione. Vogliamo mostrare che questo campo, che potrebbe rappresentare un numero massimo di utenti, è un dato a livello di applicazione accessibile a tutte le azioni. Questo è ciò che dimostreremo con l'azione [Action1].

17.2.2. Il file [struts.xml]

Il file di configurazione principale di Struts è il seguente:


<?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" />
  <!-- 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>

Solo la riga 10 differisce dalle versioni precedenti di questo file. Definisce una costante Struts. Gli oggetti istanziati da Spring possono essere iniettati in altri oggetti. Questo è il fondamento stesso di Spring. Qui, un riferimento all'oggetto [Config] creato da Spring può essere iniettato negli oggetti Struts. È qui che entra in gioco il plugin Spring per Struts 2, garantendo l'integrazione di Spring con Struts.

La riga 10 indica che l'inserimento degli oggetti Spring in un oggetto Struts avverrà automaticamente (autowire) in base al nome (valore). Torniamo al file di configurazione [applicationContext.xml]:


<!-- configuration des beans de portée application -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

Ciò che Struts 2 definisce come nome del bean è in realtà l'ID. Quindi, in questo caso, il bean [Config] istanziato è denominato config.

L'azione [Action1.java] è la seguente:


package example;
 
import com.opensymphony.xwork2.ActionSupport;
...
public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {
 
  // constructor without parameters
  public Action1() {
  }
  
  // Session, Request, Parametres
  private Map<String, Object> session;
  private Map<String, Object> request;
  private Map<String, String[]> parameters;
  private Config config;
 
  @Override
  public String execute() {
  ....
    // request
    request.put("nbMaxUsers", config.getNbMaxUsers());
 
    // display page JSP
    return SUCCESS;
  }
...
  public Config getConfig() {
    return config;
  }
 
  public void setConfig(Config config) {
    this.config = config;
  }
}

L'azione [Action1] è identica a quella dell'applicazione precedente, con le seguenti piccole differenze:

  • riga 15: è stato aggiunto un campo di configurazione. Poiché porta il nome di un bean istanziato da Spring, questo campo riceverà automaticamente un riferimento a quell'oggetto. Pertanto, l'azione ha accesso alla configurazione dell'applicazione o, più in generale, ai dati nell'ambito Application.
  • riga 31: Spring istanzierà il campo config tramite il suo metodo set. Deve quindi essere presente.
  • Riga 21: L'azione accede alle informazioni a livello di applicazione. Includiamo il numero massimo di utenti, nbMaxUsers, nella richiesta in modo che la vista [Context.jsp] possa visualizzarlo.

17.2.3. Il file [example.xml]

Il file di configurazione secondario di Struts è identico a quello della versione precedente:


<?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. La vista [Context.jsp]

La vista [Context.jsp] è la seguente:


<%@ 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. Test

Un esempio di esecuzione è il seguente:

Image