转载

跟我学Spring3(10.2):集成其它Web框架之集成Struts1.x

10.2  集成Struts1.x

10.2.1  概述

Struts1.x是最早实现MVC(模型-视图-控制器)模式的Web框架之一,其使用非常广泛,虽然目前已经有Struts2.x等其他Web框架,但仍有很多公司使用Struts1.x框架。

集成Struts1.x也非常简单,除了通用配置外,有两种方式可以将Struts1.x集成到Spring中:

  • 最简单集成:使用Spring提供的WebApplicationContextUtils工具类中的获取Spring Web容器,然后通过Spring Web容器获取Spring管理的Bean;
  • Struts1.x插件集成:利用Struts1.x中的插件ContextLoaderPlugin来将Struts1.x集成到Spring中。

        接下来让我们首先让我们准备Struts1x 所需要的jar 包:

1.1 、从下载的spring-framework- 3.0.5 .RELEASE-with-docs.zip 中dist 目录查找如下jar 包,该jar 包用于提供集成struts1.x 所需要的插件实现等:

org.springframework.web.struts-3.0.5.RELEASE.jar

1.2 、从下载的spring-framework- 3.0.5 .RELEASE-dependencies.zip 中查找如下依赖jar 包,该组jar 是struts1.x 需要的jar 包:

com.springsource.org.apache.commons.beanutils-1.8.0.jar   //用于请求参数绑定

com.springsource.javax.servlet-2.5.0.jar                            //Servlet 2.5 API

antlr.jar                                                                          //语法分析包(已有)

commons-logging.jar                                                       //日志记录组件包(已有)

servlet-api.jar                                                                 //Servlet API包(已有)

jsp-api.jar                                                                      //JSP API包(已有,可选)

commons-validator.jar                                                 // 验证包(可选)

commons-fileupload.jar                                               // 文件上传包(可选)

10.2.2  最简单集成

只使用通用配置,利用WebApplicationContextUtils提供的获取Spring Web容器方法获取Spring Web容器,然后从Spring Web容器获取Spring管理的Bean。

1、  第一个Action 实现:

java代码:
package cn.javass.spring.chapter10.struts1x.action; import org.apache.struts.action.Action; //省略部分import public class HelloWorldAction1 extends Action {     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {          WebApplicationContext ctx = WebApplicationContextUtils.             getRequiredWebApplicationContext(getServlet().getServletContext());                String message = ctx.getBean("message", String.class);         request.setAttribute("message",  message);         return mapping.findForward("hello");     } }

此Action实现非常简单,首先通过WebApplicationContextUtils获取Spring Web容器,然后从Spring Web容器中获取“message”Bean并将其放到request里,最后转到“hello”所代表的jsp页面。

2 、JSP 页面定义(webapp/WEB-INF/jsp/hello.jsp ):

java代码:
<%@ page language="java" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head>     <title>Hello World</title> </head> <body>     ${message} </body> </html>

3 、配置文件定义:

3.1 、Spring 配置文件定义(resources/chapter10/applicationContext-message.xml ):

在此配置文件中定义我们使用的“message”Bean;

java代码:
<bean id="message" class="java.lang.String">     <constructor-arg index="0" value="Hello Spring"/> </bean>

3.2 、struts 配置文件定义(resources/chapter10/struts1x/struts-config.xml ):

java代码:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC           "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"           "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config>   <action-mappings>     <action path="/hello" type="cn.javass.spring.chapter10.struts1x.action.HelloWorldAction1">        <forward name="hello" path="/WEB-INF/jsp/hello.jsp"/>     </action>   </action-mappings> </struts-config>

3.3 、web.xml 部署描述符文件定义(webapp/WEB-INF/web.xml )添加如下内容:

java代码:
<!-- Struts1.x前端控制器配置开始   -->        <servlet>         <servlet-name>hello</servlet-name>         <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>          <init-param>             <param-name>config</param-name>             <param-value>                       /WEB-INF/classes/chapter10/struts1x/struts-config.xml              </param-value>         </init-param>         <load-on-startup>1</load-on-startup>        </servlet>        <servlet-mapping>         <servlet-name>hello</servlet-name>         <url-pattern>*.do</url-pattern>       </servlet-mapping> <!-- Struts1.x前端控制器配置结束   -->

Struts1.x前端控制器配置了ActionServlet前端控制器,其拦截以.do开头的请求,Strut配置文件通过初始化参数“config”来指定,如果不知道“config”参数则默认加载的配置文件为“/WEB-INF/ struts-config.xml”。

4 、执行测试: 在Web浏览器中输入http://localhost:8080/hello.do可以看到“Hello Spring”信息说明测试正常。

有朋友想问,我不想使用这种方式,我想在独立环境内测试,没关系,您只需将spring/lib目录拷贝到spring/webapp/WEB-INF/下,然后将webapp拷贝到如tomcat中即可运行,尝试一下吧。

Spring还提供ActionSupport类来简化获取WebApplicationContext,Spring为所有标准Action类及子类提供如下支持类,即在相应Action类后边加上Support后缀:

  • ActionSupport
  • DispatchActionSupport
  • LookupDispatchActionSupport
  • MappingDispatchActionSupport

具体使用方式如下:

1 、Action 定义

java代码:
package cn.javass.spring.chapter10.struts1x.action; //省略import public class HelloWorldAction2 extends ActionSupport { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {         WebApplicationContext ctx = getWebApplicationContext();             String message = ctx.getBean("message", String.class);         request.setAttribute("message", message);         return mapping.findForward("hello");     } }

和第一个示例唯一不同的是直接调用 getWebApplicationContext() 即可获得Spring Web容器。

2 、修改Struts 配置文件(resources/chapter10/struts1x/struts-config.xml )添加如下Action 定义:

java代码:
<action path="/hello2" type="cn.javass.spring.chapter10.struts1x.action.HelloWorldAction2">     <forward name="hello" path="/WEB-INF/jsp/hello.jsp"/> </action>

3 、启动嵌入式Web 服务器 并在Web浏览器中输入http://localhost:8080/hello2.do可以看到“Hello Spring”信息说明Struts1集成成功。

这种集成方式好吗?而且这种方式算是集成吗?直接获取Spring Web容器然后从该Spring Web容器中获取Bean,暂且看作是集成吧,这种集成对于简单操作可以接受,但更复杂的注入呢?接下来让我们学习使用Struts插件进行集成。

10.2.2  Struts1.x插件集成

Struts插件集成使用ContextLoaderPlugin类,该类用于为ActionServlet加载Spring配置文件。

1 、在Struts 配置文件(resources/chapter10/struts1x/struts-config.xml )中配置插件:

java代码:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">     <set-property property="contextClass" value="org.springframework.web.context.support.XmlWebApplicationContext"/>     <set-property property="contextConfigLocation" value="/WEB-INF/hello-servlet.xml"/>     <set-property property="namespace" value="hello"/> </plug-in>
  • contextClass 可选,用于指定WebApplicationContext实现类,默认是XmlWebApplicationContext;
  • contextConfigLocation 指定Spring配置文件位置,如果我们的ActionServlet 在 web.xml 里面通过 <servlet-name>hello</servlet-name>指定名字为“hello”,且没有指定contextConfigLocation,则默认Spring配置文件是/WEB-INF/hello-servlet.xml;
  • namespace 因为默认使用ActionServlet在web.xml定义中的Servlet的名字,因此如果想要使用其他名字可以使用该变量指定,如指定“hello”,将加载的Spring配置文件为/WEB-INF/hello-servlet.xml;

由于我们的ActionServlet在web.xml中的名字为hello,而我们的配置文件在/WEB-INF/hello-servlet.xml,因此contextConfigLocation和namespace可以不指定,因此最简单配置如下:

java代码:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/>

通用配置的Spring Web容器将作为 ContextLoaderPlugin 中创建的Spring Web容器的父容器存在,然而可以省略通用配置而直接在struts配置文件中通过 ContextLoaderPlugin 插件指定所有配置文件。

插件已经配置了,那如何定义Action、配置Action、配置Spring管理Bean呢,即如何真正集成Spring+Struts1x呢?使用插件方式时Action将在Spring中配置而不是在Struts中配置了,Spring目前提供以下两种方式:

  • 将Struts配置文件中的<action>的type属性指定为DelegatingActionProxy,然后在Spring中配置同名的Spring管理的Action Bean;
  • 使用Spring提供的DelegatingRequestProcessor重载 Struts 默认的 RequestProcessor来从Spring容器中查找同名的Spring管理的Action Bean。

看懂了吗?好像没怎么看懂,那就直接上代码,有代码有真相。

2 、定义Action 实现,由于Action 将在Spring 中配置,因此message 可以使用依赖注入方式了:

java代码:
package cn.javass.spring.chapter10.struts1x.action; //省略 public class HelloWorldAction3 extends Action {     private String message;     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {          request.setAttribute("message", message);         return mapping.findForward("hello");     }     public void setMessage(String message) {//有setter方法,大家是否想到setter注入         this.message = message;     } }

3 、DelegatingActionProxy 方式与Spring 集成配置:

3 .1 、在Struts 配置文件(resources/chapter10/struts1x/struts-config.xml )中进行Action 定义:

java代码:
<action path="/hello3" type="org.springframework.web.struts.DelegatingActionProxy">     <forward name="hello" path="/WEB-INF/jsp/hello.jsp"/> </action>

3.2 、在Spring 配置文件(webapp/WEB-INF/hello-servlet.xml )中定义Action 对应的Bean

java代码:
<bean name="/hello3" class="cn.javass.spring.chapter10.struts1x.action.HelloWorldAction3">     <property name="message" ref="message"/> </bean>

3.3 、启动嵌入式Web 服务器 并在Web浏览器中输入http://localhost:8080/hello3.do可以看到“Hello Spring”信息说明测试正常。

从以上配置中可以看出:

  • Struts配置文件中<action>标签的path属性和Spring配置文件的name属性应该完全一样,否则错误;
  • Struts通过 DelegatingActionProxy 去到Spring Web容器中查找同名的Action Bean;

很简单吧,DelegatingActionProxy是个代理Action,其实现了Action类,其内部帮我们查找相应的Spring管理Action Bean并把请求转发给这个真实的Action。

4 、DelegatingRequestProcessor 方式与Spring 集成:

4.1 、首先要替换掉Struts 默认的RequestProcessor ,在Struts 配置文件(resources/chapter10/struts1x/struts-config.xml )中添加如下配置:

java代码:
<controller>     <set-property property="processorClass"          value="org.springframework.web.struts.DelegatingRequestProcessor"/> </controller>

4 .2 、在Struts 配置文件(resources/chapter10/struts1x/struts-config.xml )中进行Action 定义:

java代码:
<action path="/hello4" type=" cn.javass.spring.chapter10.struts1x.action.HelloWorldAction3">     <forward name="hello" path="/WEB-INF/jsp/hello.jsp"/> </action>

或更简单形式:

java代码:
<action path="/hello4">     <forward name="hello" path="/WEB-INF/jsp/hello.jsp"/> </action>

4.3 、在Spring 配置文件(webapp/WEB-INF/hello-servlet.xml )中定义Action 对应的Bean

java代码:
<bean name="/hello4" class="cn.javass.spring.chapter10.struts1x.action.HelloWorldAction3">     <property name="message" ref="message"/> </bean>

4.4 、启动嵌入式Web 服务器 并在Web浏览器中输入http://localhost:8080/hello4.do可以看到“Hello Spring”信息说明Struts1集成成功。

从以上配置中可以看出:

  • Struts配置文件中<action>标签的path属性和Spring配置文件的name属性应该完全一样,否则错误;
  • Struts通过 DelegatingRequestProcessor 去到Spring Web容器中查找同名的Action Bean;

很简单吧,只是由 DelegatingRequestProcessor 去帮我们查找相应的Action Bean,但没有代理Action了,所以推荐使用该方式。

跟我学Spring3(10.2):集成其它Web框架之集成Struts1.x

图10-4 共享及专用Spring Web容器

Struts1x与Spring集成到此就完成了,在集成时需要注意一下几点:

  • 推荐使用ContextLoaderPlugin+DelegatingRequestProcessor方式集成;
  • 当有多个Struts模块时建议在通用配置部分配置通用部分,因为通用配置在正在Web容器中是可共享的,而在各个Struts模块配置文件中配置是不可共享的,因此不推荐直接使用ContextLoaderPlugin中为每个模块都指定所有配置,因为 ContextLoaderPlugin 加载的Spring 容器只对当前的ActionServlet 有效对其他ActionServlet 无效, 如图10-4所示。

本系列:

原文  http://www.importnew.com/18404.html
正文到此结束
Loading...