1.Struts2插件
Struts2通过提供各种插件,用于与大部分流程的J2EE框架进行整合。
插件概述
Struts2的插件是一个JAR文件,这个JAR文件可以用于扩展、改变或者添加Struts2的功能。每个Struts2的插件JAR都包含一个名为struts-plugin.xml的配置文件,struts-plugin.xml文件的内容与普通的struts.xml文件内容完全相同。
当把这个包含struts-plugin.xml文件的JAR文件复制到Web应用中时,Struts2会自动加载该JAR文件的struts-plugin.xml文件。
Struts2应用包含3种类型的配置文件:struts-default.xml(包含在struts2-core.xml文件中),struts-plugin.xml(包含在各插件JAR文件中)和struts.xml文件。
启动一个struts2应用时,加载顺序: struts-default.xml、struts-plugin.xml和struts.xml。
2.集成Spring
和Spring集成的目标:是希望Struts2的Action定义直接使用Spring IoC的功能,将业务层的Bean注入到Struts的Action中。
将Struts类包添加到lib路径下
struts2-core.2.jar
xwork-2.jar
ognl-2.jar
struts2-spring-plugin-2.jar
freemarker-2.jar
其中struts2-spring-plugin-2.jar就是将Struts2集成到Spring中的类包,该类包有一个struts-plugin.xml配置文件,定义了一个名为spring的StrutsSpringObjectFactory的Bean,以便将Action类的管理工作委托给Spring容器进行。
编写Struts配置文件struts.xml
1
2
3
4
5
6
7
8
|
<?
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
>
<!-- 通过这个配置指定使用struts-plugin.xml中的StrutsSpringObjectFacotry作为创建Action的工具类 -->
<
constant
name
=
"struts.objectFactory"
value
=
"spring"
/>
</
struts
>
|
配置web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
web-app
id
=
"WebApp_ID"
version
=
"2.5"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
>
<!-- spring config -->
<
context-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>classpath:ApplicationContext*.xml</
param-value
>
</
context-param
>
<
listener
>
<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>
</
listener
>
<!-- 定义Struts2的核心控制器FilterDispathcer的Filter -->
<
filter
>
<!-- 定义核心Filter的名字 -->
<
filter-name
>struts2</
filter-name
>
<!-- 定义核心Filter的实现类 -->
<
filter-class
>org.apache.struts2.dispatcher.FilterDispatcher</
filter-class
>
</
filter
>
<!-- FilterDispatcher用来初始化struts2并且处理所有的HTTP请求。 -->
<
filter-mapping
>
<
filter-name
>struts2</
filter-name
>
<
url-pattern
>*.action</
url-pattern
>
</
filter-mapping
>
<
filter-mapping
>
<
filter-name
>struts2</
filter-name
>
<
url-pattern
>*.jsp</
url-pattern
>
</
filter-mapping
>
<!-- 定义struts2.0 end. -->
</
web-app
>
|
通过contextConfigLocation指定Spring配置文件,并配置ContextLoaderListener启动Spring容器。
整合流程
Struts2的核心控制器是拦截用户请求,然后将请求转发给对应Action处理,这个过程是固定的。但实际上,Action实例是由Spring容器产生,而不是Struts2容器,Spring通过提供一种伪Action,当在struts.xml文件配置Action时,通常需要指定class属性,不是指向Action的实际类,而是指向Spring容器的Bean ID。
在整合策略下,处理用户请求的Action有Spring负责创建,但Spring创建Action实例时,并不是利用配置Action时指定的class属性来创建该Action实例,而是从Spring容器中取出对应的Bean实例完成创建。
3.注册用户实例
创建Action对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public
class
User {
private
String userName;
private
String password;
public
String getUserName() {
return
userName;
}
public
void
setUserName(String userName) {
this
.userName = userName;
}
public
String getPassword() {
return
password;
}
public
void
setPassword(String password) {
this
.password = password;
}
}
import
cms.com.system.domain.User;
import
com.opensymphony.xwork2.ActionSupport;
public
class
UserRegisterAction
extends
ActionSupport {
private
User user;
public
User getUser() {
return
user;
}
public
void
setUser(User user) {
this
.user = user;
}
public
String execute()
throws
Exception {
if
(user ==
null
) {
user =
new
User();
return
"input"
;
}
else
{
return
"success"
;
}
}
}
|
配置Action
在ApplicationContext.xml的Spring配置文件中配置UserRegisterAction Bean:
1
|
<
bean
id
=
"registerUserAction"
class
=
"cms.com.system.action.UserRegisterAction"
scope
=
"prototype"
/>
|
在Spring中配置好Struts2的Action,在Struts配置文件中引用这个Bean:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?
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
>
<!-- 通过这个配置指定使用struts-plugin.xml中的StrutsSpringObjectFacotry作为创建Action的工具类 -->
<
constant
name
=
"struts.objectFactory"
value
=
"spring"
/>
<!-- struts2的Action都必须配置在package里 -->
<
package
name
=
"user"
extends
=
"struts-default"
>
<
action
name
=
"registerUserAction"
class
=
"registerUserAction"
>
<
result
name
=
"input"
>/jsp/registerUser.jsp</
result
>
<
result
name
=
"success"
>/jsp/success.jsp</
result
>
</
action
>
</
package
>
</
struts
>
|
其中class="registerUserAciton",在正常情况下,struts通过class属性指定Action给的实现类:
1
|
<
action
name
=
"registeruserAction"
class
=
"cms.com.system.action.UserRegisterAction"
>
|
但此时却是一个类似于Bean名的字符串,事实上class属性的值正是指向Spring容器中的Bean名称,在后台通过StrutsSpringObjectFactory获得真实的Action实例。
当使用Spring容器管理系统的Action,在struts.xml文件中配置该Action时,class属性并不是指向Action实体类,而是指向了Spring容器中Action的实例的ID。
表单页面和成功页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<
html
>
<
head
>
<
title
>My JSP 'MyJsp.jsp' starting page</
title
>
</
head
>
<
body
>
<
s:form
>
<
s:textfield
key
=
"user.userName"
label
=
"用户名"
/>
<
s:textfield
key
=
"user.password"
label
=
"密码"
/>
<
s:submit
/>
</
s:form
>
</
body
>
</
html
>
|
表单标签<s:form>通过简单地标签声明,无需通过action属性指定表单提交地址,表单组件标签也通过级联属性的方式绑定表单对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<
html
>
<
head
>
<
title
>My JSP 'MyJsp.jsp' starting page</
title
>
</
head
>
<
body
>
<
s:form
>
<
s:textfield
key
=
"user.userName"
label
=
"用户名"
/>
<
s:textfield
key
=
"user.password"
label
=
"密码"
/>
<
s:submit
/>
</
s:form
>
</
body
>
</
html
>
|
测试用户注册界面
在点击Submit提交表单后,RegisterUserAction负责处理表单提交,处理后将重定向到success.jsp页面上。
完成Spring和Struts2的整合主要作用,是能让Struts2的Action实例利用Spring容器的IoC特性。
整合的不足
Spring管理Action,必须将所有的Action配置在Spring容器中,而struts.xml未见还需要配置一个“伪Action”,从而导致文件臃肿、冗余。
Action的业务逻辑组件接收容器注入,会导致代码的可读性降低。