天天看点

3.[Struts2权威指南笔记]整合Spring 1.Struts2插件 2.集成Spring 3.注册用户实例

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。

和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

<code>&lt;?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"UTF-8"</code><code>?&gt;</code>

<code>&lt;!DOCTYPE struts PUBLIC</code>

<code>        </code><code>"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"</code>

<code>        </code><code>"http://struts.apache.org/dtds/struts-2.0.dtd"&gt;</code>

<code>&lt;</code><code>struts</code><code>&gt;</code>

<code>    </code><code>&lt;!-- 通过这个配置指定使用struts-plugin.xml中的StrutsSpringObjectFacotry作为创建Action的工具类 --&gt;</code>

<code>    </code><code>&lt;</code><code>constant</code> <code>name</code><code>=</code><code>"struts.objectFactory"</code> <code>value</code><code>=</code><code>"spring"</code> <code>/&gt;</code>

<code>&lt;/</code><code>struts</code><code>&gt;</code>

配置web.xml

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<code>&lt;</code><code>web-app</code> <code>id</code><code>=</code><code>"WebApp_ID"</code> <code>version</code><code>=</code><code>"2.5"</code>

<code>    </code><code>xmlns</code><code>=</code><code>"http://java.sun.com/xml/ns/javaee"</code> <code>xmlns:xsi</code><code>=</code><code>"http://www.w3.org/2001/XMLSchema-instance"</code>

<code>    </code><code>xsi:schemaLocation</code><code>=</code><code>"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</code><code>&gt;</code>

<code>    </code><code>&lt;!-- spring config --&gt;</code>

<code>    </code><code>&lt;</code><code>context-param</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-name</code><code>&gt;contextConfigLocation&lt;/</code><code>param-name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>param-value</code><code>&gt;classpath:ApplicationContext*.xml&lt;/</code><code>param-value</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>context-param</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>listener</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>listener-class</code><code>&gt;org.springframework.web.context.ContextLoaderListener&lt;/</code><code>listener-class</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>listener</code><code>&gt;</code>

<code>    </code><code>&lt;!-- 定义Struts2的核心控制器FilterDispathcer的Filter --&gt;</code>

<code>    </code><code>&lt;</code><code>filter</code><code>&gt;</code>

<code>        </code><code>&lt;!-- 定义核心Filter的名字 --&gt;</code>

<code>        </code><code>&lt;</code><code>filter-name</code><code>&gt;struts2&lt;/</code><code>filter-name</code><code>&gt;</code>

<code>        </code><code>&lt;!-- 定义核心Filter的实现类 --&gt;</code>

<code>    </code><code>&lt;</code><code>filter-class</code><code>&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/</code><code>filter-class</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>filter</code><code>&gt;</code>

<code>    </code><code>&lt;!-- FilterDispatcher用来初始化struts2并且处理所有的HTTP请求。 --&gt;</code>

<code>    </code><code>&lt;</code><code>filter-mapping</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>url-pattern</code><code>&gt;*.action&lt;/</code><code>url-pattern</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>filter-mapping</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>url-pattern</code><code>&gt;*.jsp&lt;/</code><code>url-pattern</code><code>&gt;</code>

<code>    </code><code>&lt;!-- 定义struts2.0 end.  --&gt;</code>

<code>&lt;/</code><code>web-app</code><code>&gt;</code>

通过contextConfigLocation指定Spring配置文件,并配置ContextLoaderListener启动Spring容器。

整合流程

Struts2的核心控制器是拦截用户请求,然后将请求转发给对应Action处理,这个过程是固定的。但实际上,Action实例是由Spring容器产生,而不是Struts2容器,Spring通过提供一种伪Action,当在struts.xml文件配置Action时,通常需要指定class属性,不是指向Action的实际类,而是指向Spring容器的Bean ID。

<a target="_blank" href="http://blog.51cto.com/attachment/201306/134002849.png"></a>

在整合策略下,处理用户请求的Action有Spring负责创建,但Spring创建Action实例时,并不是利用配置Action时指定的class属性来创建该Action实例,而是从Spring容器中取出对应的Bean实例完成创建。

创建Action对象

31

32

33

34

35

<code>public</code> <code>class</code> <code>User {</code>

<code>    </code><code>private</code> <code>String userName;</code>

<code>    </code><code>private</code> <code>String password;</code>

<code>    </code><code>public</code> <code>String getUserName() {</code>

<code>        </code><code>return</code> <code>userName;</code>

<code>    </code><code>}</code>

<code>    </code><code>public</code> <code>void</code> <code>setUserName(String userName) {</code>

<code>        </code><code>this</code><code>.userName = userName;</code>

<code>    </code><code>public</code> <code>String getPassword() {</code>

<code>        </code><code>return</code> <code>password;</code>

<code>    </code><code>public</code> <code>void</code> <code>setPassword(String password) {</code>

<code>        </code><code>this</code><code>.password = password;</code>

<code>}</code>

<code>import</code> <code>cms.com.system.domain.User;</code>

<code>import</code> <code>com.opensymphony.xwork2.ActionSupport;</code>

<code>public</code> <code>class</code> <code>UserRegisterAction </code><code>extends</code> <code>ActionSupport {</code>

<code>    </code><code>private</code> <code>User user;</code>

<code>    </code><code>public</code> <code>User getUser() {</code>

<code>        </code><code>return</code> <code>user;</code>

<code>    </code><code>public</code> <code>void</code> <code>setUser(User user) {</code>

<code>        </code><code>this</code><code>.user = user;</code>

<code>    </code><code>public</code> <code>String execute() </code><code>throws</code> <code>Exception {</code>

<code>        </code><code>if</code><code>(user == </code><code>null</code><code>) {</code>

<code>            </code><code>user = </code><code>new</code> <code>User();</code>

<code>            </code><code>return</code> <code>"input"</code><code>;</code>

<code>        </code><code>} </code><code>else</code> <code>{</code>

<code>            </code><code>return</code> <code>"success"</code><code>;</code>

<code>        </code><code>}</code>

配置Action

在ApplicationContext.xml的Spring配置文件中配置UserRegisterAction Bean:

<code>&lt;</code><code>bean</code> <code>id</code><code>=</code><code>"registerUserAction"</code> <code>class</code><code>=</code><code>"cms.com.system.action.UserRegisterAction"</code> <code>scope</code><code>=</code><code>"prototype"</code> <code>/&gt;</code>

在Spring中配置好Struts2的Action,在Struts配置文件中引用这个Bean:

<code>    </code><code>&lt;!-- struts2的Action都必须配置在package里 --&gt;</code>

<code>    </code><code>&lt;</code><code>package</code> <code>name</code><code>=</code><code>"user"</code> <code>extends</code><code>=</code><code>"struts-default"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>action</code> <code>name</code><code>=</code><code>"registerUserAction"</code> <code>class</code><code>=</code><code>"registerUserAction"</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>result</code> <code>name</code><code>=</code><code>"input"</code><code>&gt;/jsp/registerUser.jsp&lt;/</code><code>result</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>result</code> <code>name</code><code>=</code><code>"success"</code><code>&gt;/jsp/success.jsp&lt;/</code><code>result</code><code>&gt;</code>

<code>        </code><code>&lt;/</code><code>action</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>package</code><code>&gt;</code>

其中class="registerUserAciton",在正常情况下,struts通过class属性指定Action给的实现类:

<code>&lt;</code><code>action</code> <code>name</code><code>=</code><code>"registeruserAction"</code> <code>class</code><code>=</code><code>"cms.com.system.action.UserRegisterAction"</code><code>&gt;</code>

但此时却是一个类似于Bean名的字符串,事实上class属性的值正是指向Spring容器中的Bean名称,在后台通过StrutsSpringObjectFactory获得真实的Action实例。

当使用Spring容器管理系统的Action,在struts.xml文件中配置该Action时,class属性并不是指向Action实体类,而是指向了Spring容器中Action的实例的ID。

表单页面和成功页面

<code>&lt;%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%&gt;</code>

<code>&lt;%@ taglib prefix="s" uri="/struts-tags" %&gt;</code>

<code>&lt;</code><code>html</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>title</code><code>&gt;My JSP 'MyJsp.jsp' starting page&lt;/</code><code>title</code><code>&gt;</code>

<code>  </code><code>&lt;/</code><code>head</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>body</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>s:form</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>s:textfield</code> <code>key</code><code>=</code><code>"user.userName"</code> <code>label</code><code>=</code><code>"用户名"</code> <code>/&gt;</code>

<code>        </code><code>&lt;</code><code>s:textfield</code> <code>key</code><code>=</code><code>"user.password"</code> <code>label</code><code>=</code><code>"密码"</code> <code>/&gt;</code>

<code>        </code><code>&lt;</code><code>s:submit</code><code>/&gt;</code>

<code>    </code><code>&lt;/</code><code>s:form</code><code>&gt;</code>

<code>  </code><code>&lt;/</code><code>body</code><code>&gt;</code>

<code>&lt;/</code><code>html</code><code>&gt;</code>

表单标签&lt;s:form&gt;通过简单地标签声明,无需通过action属性指定表单提交地址,表单组件标签也通过级联属性的方式绑定表单对象。

测试用户注册界面

<a target="_blank" href="http://blog.51cto.com/attachment/201306/134158621.png"></a>

在点击Submit提交表单后,RegisterUserAction负责处理表单提交,处理后将重定向到success.jsp页面上。

<a target="_blank" href="http://blog.51cto.com/attachment/201306/134205315.png"></a>

完成Spring和Struts2的整合主要作用,是能让Struts2的Action实例利用Spring容器的IoC特性。

整合的不足

Spring管理Action,必须将所有的Action配置在Spring容器中,而struts.xml未见还需要配置一个“伪Action”,从而导致文件臃肿、冗余。

Action的业务逻辑组件接收容器注入,会导致代码的可读性降低。

本文转自 LinkedKeeper 51CTO博客,原文链接:http://blog.51cto.com/sauron/1231687,如需转载请自行联系原作者