Skip to content

17. Esempio 15 – Integrazione Struts 2 / Spring

Nell’esempio precedente non avevamo dati con ambito Application condivisi da tutte le richieste di tutti gli utenti. Ne mostriamo qui un esempio. Per implementarlo, utilizziamo il framework Spring [http://www.springsource.org/]. Spring è uno strumento di grande valore. In questo esempio ne mostriamo solo una minima parte. Un esempio successivo ne farà un uso più intensivo.

Lo scopo di questa applicazione è visualizzare i dati relativi al campo Application.

17.1. Il progetto NetBeans

Il progetto NetBeans dell'applicazione è il seguente:

  • in [1]:
    • [web.xml], che configura l'applicazione web, subirà alcune modifiche rispetto alle versioni precedenti
    • [applicationContext.xml] è il file di configurazione di Spring
  • in [2]: la vista [Context.JSP] che visualizzerà i dati dell'ambito Application
  • in [3]:
    • il file dei messaggi [messages.properties]
    • il file di configurazione principale di Struts [struts.xml]. Subirà modifiche rispetto alle applicazioni precedenti.
  • in [4]:
    • l’azione Struts [Action1.java]
    • la classe [Config.java] che memorizzerà i dati nell'ambito dell'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 alcuni archivi al progetto
  • modificare i file [web.xml] e [struts.xml]

17.2. Configuration

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 avviene alle righe 12-14. All'applicazione web viene aggiunto un listener. All'avvio dell'applicazione web, verrà istanziata la classe che implementa questo listener. Si tratta di una classe di 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">
  
  <!-- configurazione dei bean a livello di applicazione -->
  <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). Si potrebbe tradurre beans con «oggetti». Spring istanzierà tutti gli oggetti (bean) presenti in questo file di configurazione. Lo fa una sola volta, quando listener Spring viene avviato all’avvio dell’applicazione web.
  • righe 7-9: definiscono un bean denominato config (id). Il bean config è associato alla classe (class) [example.Config]. Spring istanzierà questa classe.
  • riga 8: definisce una proprietà della classe [example.Config]. Spring chiamerà il metodo [example.Config].setNbMaxUsers(10). È quindi necessario che il metodo setNbMaxUsers esista nella classe. Il codice è 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 solo un campo nbMaxUsers con i relativi get e set. Se avete seguito correttamente quanto detto, all’avvio dell’applicazione web viene istanziata un’istanza della classe [Config] con il valore 10 per il suo campo nbMaxUsers. Abbiamo definito un solo campo, ma è sufficiente per la nostra dimostrazione. Vogliamo mostrare che questo campo, che potrebbe rappresentare il numero massimo di utenti, è un dato di ambito Application accessibile a tutte le azioni. È 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>
  <!-- internazionalizzazione -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- integrazione Spring -->
  <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 è diversa dalle versioni precedenti di questo file. Essa definisce una costante Struts. Gli oggetti istanziati da Spring possono essere iniettati in altri oggetti. Questo è il fondamento stesso di Spring. In questo caso, un riferimento all’oggetto di tipo [Config] creato da Spring potrà essere iniettato in oggetti Struts. È qui che entra in gioco il plugin Spring per Struts 2, che garantisce l’integrazione di Spring con Struts.

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


<!-- configurazione dei bean a livello di applicazione -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

Ciò che Struts 2 chiama «nome del bean» è in realtà qui id. Quindi, in questo caso, il bean di tipo [Config] istanziato ha come nome config.

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


package example;

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

  // costruttore senza parametri
  public Action1() {
  }
  
  // Sessione, richiesta, parametri
  private Map<String, Object> session;
  private Map<String, Object> request;
  private Map<String, String[]> parameters;
  private Config config;

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

    // Visualizzazione della pagina JSP
    return SUCCESS;
  }
...
  public Config getConfig() {
    return config;
  }

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

L'azione [Action1] è identica a quella presente nell'applicazione precedente, salvo i seguenti dettagli:

  • riga 15: è stato aggiunto un campo config. Poiché porta il nome di un bean istanziato da Spring, questo campo riceverà automaticamente un riferimento a tale oggetto. In questo modo 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. Pertanto, tale metodo deve essere presente.
  • riga 21: l’azione accede alle informazioni dell’ambito Application. Si inserisce il numero massimo di utenti nbMaxUsers nella query affinché 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. I test

Un esempio di esecuzione è il seguente: