17. 示例 15 – Struts 2 / Spring 集成
在之前的示例中,我们没有在所有用户的所有请求之间共享任何应用程序作用域的数据。我们将在这里展示一个这样的示例。为了实现这一点,我们将使用 Spring 框架 [http://www.springsource.org/]。Spring 是一个极其有价值的工具。在这个示例中,我们只展示了它的一小部分。后面的示例将更广泛地使用它。
本应用程序的目的是展示应用程序作用域内的数据。
17.1. NetBeans 项目
该应用程序的 NetBeans 项目如下:
![]() |
- 在 [1] 中:
- 用于配置 Web 应用程序的 [web.xml] 文件将与之前版本有所不同
- [applicationContext.xml] 是 Spring 配置文件
- 在 [2] 中:[Context.jsp] 视图,将显示应用程序范围的数据
- 在 [3] 中:
- 消息文件 [messages.properties]
- Struts 主配置文件 [struts.xml]。与之前的应用程序相比将有所变化。
- 在 [4] 中:
- Struts 动作 [Action1.java]
- [Config.java] 类,用于存储应用程序范围的数据
- 辅助 Struts 配置文件 [example.xml]
- 在 [5] 中:Struts 2 库
- 在 [6] 中:
- Spring 所需的归档文件 [spring-core, spring-context, spring-beans, spring-web, commons-logging]
- Struts 2 的 Spring 插件归档文件。用于实现 Spring 与 Struts 2 的集成 [struts2-spring-plugin]
与之前版本相比:
- 您必须将这些存档文件添加到项目中
- 修改 [web.xml] 和 [struts.xml] 文件
17.2. 配置
17.2.1. [web.xml] 文件
[web.xml] 文件的更改如下:
<?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>
更改发生在第 12–14 行。向 Web 应用程序中添加了一个监听器。当 Web 应用程序启动时,实现该监听器的类将被实例化。这是一个 Spring 类。该类将使用 [WEB-INF/applicationContext.xml] 文件。该文件内容如下:
<?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>
- Spring 配置文件具有根标签 <beans>(第 2 行和第 11 行)。Bean 可以被视为对象。Spring 会实例化该配置文件中找到的所有对象(Bean)。它仅在 Web 应用程序启动时 Spring 监听器被调用时执行一次此操作。
- 第 7–9 行:定义了一个名为 config(id)的 Bean。config Bean 与 [example.Config] 类相关联。Spring 将实例化该类。
- 第 8 行:定义 [example.Config] 类的属性。Spring 将调用 [example.Config].setNbMaxUsers(10) 方法。因此,该类中必须存在 setNbMaxUsers 方法。其定义如下:
package example;
public class Config {
private int nbMaxUsers;
public int getNbMaxUsers() {
return nbMaxUsers;
}
public void setNbMaxUsers(int nbMaxUsers) {
this.nbMaxUsers = nbMaxUsers;
}
}
该类仅定义了一个字段 nbMaxUsers 及其 get 和 set 方法。如果您一直跟随教程操作,那么在 Web 应用程序启动时,会实例化一个 [Config] 类的实例,并将 nbMaxUsers 字段的值设为 10。 虽然我们只定义了一个字段,但这已足以满足演示需求。我们希望展示:这个字段(可表示最大用户数)属于应用程序作用域的数据,所有操作均可访问。接下来我们将通过 [Action1] 操作演示这一点。
17.2.2. [struts.xml] 文件
Struts 的主配置文件如下:
<?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>
只有第 10 行与该文件的先前版本不同。它定义了一个 Struts 常量。由 Spring 实例化的对象可以注入到其他对象中。这就是 Spring 的根本基础。在此,Spring 创建的 [Config] 对象的引用可以注入到 Struts 对象中。这就是 Struts 2 的 Spring 插件发挥作用的地方,它确保了 Spring 与 Struts 的集成。
第 10 行表明,Spring 对象将通过名称(值)自动注入到 Struts 对象中(自动装配)。让我们回到 [applicationContext.xml] 配置文件:
<!-- configuration des beans de portée application -->
<bean id="config" class="example.Config" >
<property name="nbMaxUsers" value="10"/>
</bean>
Struts 2 所指的 Bean 名称实际上就是这里的 ID。因此,在此情况下,实例化的 [Config] Bean 被命名为 config。
[Action1.java] 动作代码如下:
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;
}
}
[Action1] 操作与上一应用程序中的完全相同,仅有以下细微差异:
- 第 15 行:已添加一个配置字段。由于该字段的名称与 Spring 实例化的 Bean 相同,因此该字段将自动获得对该对象的引用。这样,该 Action 就可以访问应用程序配置,或者更广泛地说,访问应用程序范围的数据。
- 第 31 行:Spring 将通过其 set 方法实例化 config 字段。因此该字段必须存在。
- 第 21 行:该操作访问应用范围的信息。我们将最大用户数 nbMaxUsers 包含在请求中,以便 [Context.jsp] 视图能够显示该数值。
17.2.3. [example.xml] 文件
辅助 Struts 配置文件与上一版本完全相同:
<?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. [Context.jsp] 视图
[Context.jsp] 视图如下:
<%@ 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. 测试
执行示例如下:

