17. Ejemplo 15 – Integración de Struts 2 y Spring
En el ejemplo anterior, no contábamos con datos de alcance Application compartidos por todas las solicitudes de todos los usuarios. Aquí mostramos un ejemplo. Para implementarlo, utilizamos el marco de trabajo Spring [http://www.springsource.org/]. Spring es una herramienta de gran valor. En este ejemplo solo mostramos una pequeña parte de sus capacidades. En un ejemplo posterior lo utilizaremos de manera más intensiva.
El objetivo de esta aplicación es mostrar los datos del rango Application.
17.1. El proyecto de NetBeans
El proyecto de NetBeans de la aplicación es el siguiente:
![]() |
- en [1]:
- [web.xml], que configura la aplicación web, cambiará con respecto a lo que era en versiones anteriores
- [applicationContext.xml] es el archivo de configuración de Spring
- a [2]; la vista [Context.JSP] mostrará los datos del ámbito Application
- en [3]:
- el archivo de mensajes [messages.properties]
- el archivo de configuración principal de Struts [struts.xml]. Evolucionará con respecto a las aplicaciones anteriores.
- en [4]:
- la acción de Struts [Action1.java]
- la clase [Config.java], que almacenará los datos de ámbito de aplicación
- el archivo de configuración secundario de Struts [example.xml]
- en [5]: la biblioteca de Struts 2
- en [6]:
- los archivos necesarios para Spring [spring-core, spring-context, spring-beans, spring-web, commons-logging]
- el archivo del complemento de Spring para Struts 2. Permite la integración de Spring con Struts 2 [struts2-spring-plugin]
En comparación con las versiones anteriores:
- hay que agregar archivos al proyecto
- modificar los archivos [web.xml] y [struts.xml]
17.2. Configuration
17.2.1. El archivo [web.xml]
El archivo [web.xml] cambia de la siguiente manera:
<?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>/*</patrón-URL>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
La modificación se realiza en las líneas 12 a 14. Se agrega un archivo listener a la aplicación web. Cuando se inicie la aplicación web, se instanciará la clase que implementa este listener. Se trata de una clase de Spring. Esta clase utilizará el archivo [WEB-INF/applicationContext.xml]. Este es el siguiente:
<?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">
<!-- configuración de los beans de alcance de aplicación -->
<bean id="config" class="example.Config" >
<property name="nbMaxUsers" value="10"/>
</bean>
</beans>
- El archivo de configuración de Spring tiene la etiqueta raíz <beans> (líneas 2 y 11). Se podría traducir beans como «objetos». Spring instanciará todos los objetos (bean) que se encuentren en este archivo de configuración. Lo hace solo una vez, cuando se inicia Spring al arrancar la aplicación web.
- Líneas 7-9: definen un bean llamado config (id). El bean «config» está asociado a la clase (class) [example.Config]. Spring instanciará esta clase.
- Línea 8: define una propiedad de la clase [example.Config]. Spring llamará al método [example.Config].setNbMaxUsers(10). Por lo tanto, el método setNbMaxUsers debe existir en la clase. Este es el siguiente:
package example;
public class Config {
private int nbMaxUsers;
public int getNbMaxUsers() {
return nbMaxUsers;
}
public void setNbMaxUsers(int nbMaxUsers) {
this.nbMaxUsers = nbMaxUsers;
}
}
Esta clase solo define un campo nbMaxUsers con sus campos get y set. Si hemos seguido bien lo explicado, al iniciar la aplicación web, se crea una instancia de la clase [Config] con el valor 10 para su campo nbMaxUsers. Solo hemos definido un único campo, pero es suficiente para nuestra demostración. Queremos mostrar que este campo, que podría representar un número máximo de usuarios, es un dato de alcance Application accesible para todas las acciones. Esto es lo que demostraremos con la acción [Action1].
17.2.2. El archivo [struts.xml]
El archivo de configuración principal de Struts es el siguiente:
<?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>
<!-- internacionalización -->
<constant name="struts.custom.i18n.resources" value="messages" />
<!-- integración con 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 línea 10 difiere de las versiones anteriores de este archivo. Define una constante de Struts. Los objetos instanciados por Spring pueden inyectarse en otros objetos. Este es el fundamento mismo de Spring. Aquí, una referencia al objeto de tipo [Config] creado por Spring podrá inyectarse en objetos de Struts. Aquí es donde entra en juego el complemento de Spring para Struts 2, que garantiza la integración de Spring con Struts.
La línea 10 indica que la inyección de objetos de Spring en un objeto de Struts se realizará de manera automática (autowire) por nombre (value). Volvamos al archivo de configuración [applicationContext.xml]:
<!-- configuración de beans de alcance de aplicación -->
<bean id="config" class="example.Config" >
<property name="nbMaxUsers" value="10"/>
</bean>
Lo que Struts 2 denomina «nombre del bean» es, de hecho, aquí el id. Por lo tanto, en este caso, el bean de tipo [Config] que se ha instanciado tiene como nombre config.
La acción [Action1.java] es la siguiente:
package example;
import com.opensymphony.xwork2.ActionSupport;
...
public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {
// constructor sin parámetros
public Action1() {
}
// Sesión, solicitud, parámetros
private Map<String, Object> session;
private Map<String, Object> request;
private Map<String, String[]> parameters;
private Config config;
@Override
public String execute() {
....
// solicitud
request.put("nbMaxUsers", config.getNbMaxUsers());
// Visualización de la página JSP
return SUCCESS;
}
...
public Config getConfig() {
return config;
}
public void setConfig(Config config) {
this.config = config;
}
}
La acción [Action1] es idéntica a la de la aplicación anterior, salvo por los siguientes detalles:
- línea 15: se ha agregado un campo config. Dado que lleva el nombre de un bean instanciado por Spring, este campo recibirá automáticamente una referencia a ese objeto. De esta manera, la acción tiene acceso a la configuración de la aplicación o, en términos más generales, a los datos de ámbito Application.
- línea 31: Spring instanciará el campo config mediante su método set. Por lo tanto, este debe estar presente.
- línea 21: la acción accede a la información del ámbito Application. Se incluye el número máximo de usuarios nbMaxUsers en la consulta para que la vista [Context.JSP] pueda mostrarlo.
17.2.3. El archivo [example.xml]
El archivo secundario de configuración de Struts es idéntico al de la versión anterior:
<?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] es la siguiente:
<%@ 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. Las pruebas
Un ejemplo de ejecución es el siguiente:
![]() |

