您的位置:首页 > 编程语言 > Java开发

struts1.2和spring2.5.X的整合几种方式

2012-09-15 13:24 459 查看
struts1.2和spring的整合几种方式
使用了struts和spring一段时间.但是对其中他们的整合也用了好几次.就这次机会总结下经验并整理下思绪. 
整合方式1: 
最原始而易懂的方式: 
Action继承spring提供的类org.springframework.web.struts.MappingDispatchActionSupport 
Action中的代码: 
Java代码
1.    public class UserAction extends MappingDispatchActionSupport {    
2.    public ActionForward login(ActionMapping mapping, ActionForm form,    
3.                 HttpServletRequest request, HttpServletResponse response)    
4.                throws Exception {    
5.             String uname = request.getParameter("uname");    
6.             String upass = request.getParameter("upass");    
7.            //使用其自带的一个方法实例化ApplicationContext对象    
8.             ApplicationContext context = this.getWebApplicationContext();    
9.             userService=(UserService)context.getBean("userService");    
10.             User user = userService.findByName(uname, upass);    
11.            if (user==null) {    
12.                 request.setAttribute("error", "对不起,您输入的用户名或者密码错误!");    
13.                    
14.                return mapping.findForward("failure");    
15.             } else {    
16.                 request.getSession().setAttribute("user", user);    
17.                return mapping.findForward("success");    
18.                    
19.             }    
20.         }    
21.    }   

struts-config.xml代码: 
Java代码
1.    <action path="/login" parameter="login"   
2.                 type="com.addresslist.action.UserAction" scope="request">    
3.                 <forward name="success" path="/page/index.htm"></forward>               
4.             </action>   

你会发现使用这种方法的话.直接可以保持你原先struts的配置.只需要改变一下你相应的Action类继承MappingDispatchActionSupport. 
其中缺点就是:你的Action将会和Spring耦合在一起.当你有多个Action类都继承MappingDispatchActionSupport的话你将会每次都需要调用

getWebApplicationContext()获取ApplicationContext的实例.这样如果你想放弃使用spring的话.所要修改的代码量将非常大 

整合方式2: 
启动Spring再在相应的Action类中实例化ApplicationContext 
spring有三种启动方式,使用ContextLoaderServlet,ContextLoaderListener和ContextLoaderPlugIn. 
我的测试使用的ContextLoaderListener 
web.xml的配置: 
Java代码
1.    <!--      
2.        //可以选择使用ContextLoaderServle    
3.         <servlet>    
4.       <servlet-name>springInitServlet</servlet-name>    
5.         <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>    
6.            // 如果使用要注意这里设置开启的优先级要比Struts的ActionServlet高    
7.         <load-on-startup>2</load-on-startup>    
8.       </servlet>    
9.         -->    
10.         <context-param>    
11.         <param-name>contextConfigLocation</param-name>    
12.         <param-value>/WEB-INF/applicationContext.xml</param-value>    
13.       </context-param>    
14.       <!-- 使用ContextLoaderListener -->    
15.         <listener>    
16.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
17.         </listener>   

与整合1主要的变化是使用了 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
形成spring的环境 
struts-config.xml代码: 
Java代码
1.    <action path="/login" parameter="login"   
2.                 type="com.addresslist.action.UserAction" scope="request">    
3.                 <forward name="success" path="/page/index.htm"></forward>               
4.             </action>    
5.    <!--    
6.             可以选择使用    
7.             <plug-in    
8.             className="org.springframework.web.struts.ContextLoaderPlugIn">    
9.             <set-property property="contextConfigLocation"   
10.                 value="/WEB-INF/applicationContext.xml" />    
11.         </plug-in>    
12.    -->   

Action的代码: 
Java代码
1.    publi
13ff9
c class UserAction extends MappingDispatchAction {    
2.    public UserService getFileService(){    
3.    //这里使用了WebApplicationContextUtils工具类实例化ApplicationContext    
4.             ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(this.getServlet().getServletContext());    
5.            return (UserService) ac.getBean("userService");    
6.         }    
7.       
8.        public ActionForward login(ActionMapping mapping, ActionForm form,    
9.                 HttpServletRequest request, HttpServletResponse response)    
10.                throws Exception {    
11.             String uname = request.getParameter("uname");    
12.             String upass = request.getParameter("upass");    
13.                
14.             User user = getFileService().findByName(uname, upass);    
15.            if (user==null) {    
16.                 request.setAttribute("error", "对不起,您输入的用户名或者密码错误!");    
17.                    
18.                return mapping.findForward("failure");    
19.             } else {    
20.                 request.getSession().setAttribute("user", user);    
21.                return mapping.findForward("success");    
22.                    
23.             }    
24.         }    
25.    }   

WebApplicationContextUtils(参考于http://tech.ddvip.com/2007-08/118764954132510_8.html) 

  当 Web 应用集成 Spring 容器后,代表 Spring 容器的EebApplicationContext 对象将以 

  WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 为键存放在 ServletContext 属性列表中。您当然可以直接通过以下语句获取 

WebApplicationContext: 

  WebApplicationContext wac = (WebApplicationContext)servletContext. 

  getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 
  但通过位于 org.springframework.web.context.support 包中的WebApplicationContextUtils 工具类获取 WebApplicationContext 更方便: 

  WebApplicationContext wac =WebApplicationContextUtils. 

  getWebApplicationContext(servletContext); 
  当 ServletContext 属性列表中不存在 WebApplicationContext 时,getWebApplicationContext() 方法不会抛出异常,它简单地返回 null。如果后续代码直接

访问返回的结果将引发一个 NullPointerException 异常,而 WebApplicationContextUtils 另一个 getRequiredWebApplicationContext(ServletContext sc) 方法

要求 ServletContext 属性列表中一定要包含一个有效的 WebApplicationContext 对象,否则马上抛出一个 IllegalStateException 异常。我们推荐使用后者,因为

它能提前发现错误的时间,强制开发者搭建好必备的基础设施。 

通过该方式整合我们只需要进行启动Spring和在相应的Action类获取WebApplicationContext .这样子对Spring的耦合降低 

整合方式3:将动作管理委托给 Spring 
将Struts的动作管理委托给Spring.使用Struts-config.xml的动态映射中注册一个代理. 
代理负责在Spring中找到Struts的动作.由于动作在Spring的控制之下.所以Spring可以对Action进行javaBean的注入和Spring的一些Aop使用 
需要发生改变的配置有: 
Struts-config.xml: 
Java代码
1.    <struts-config>    
2.         <data-sources />    
3.         <form-beans />    
4.         <global-exceptions />    
5.         <global-forwards />    
6.         <action-mappings>    
7.              <!--这里使用了org.springframework.web.struts.DelegatingAction-->    
8.         <action path="/login" parameter="login" type="org.springframework.web.struts.DelegatingActionProxy">    
9.         <forward name="success" path="/page/index.htm"/>    
10.         <forward name="failure" path="/page/fail.htm"/>    
11.         </action>    
12.         </action-mappings>    
13.            
14.       
15.         <message-resources    
16.             parameter="com.addresslist.properties.ApplicationResources" />    
17.    <!--这里使用ContextLoaderPlugIn建立Spring的环境-->    
18.         <plug-in    
19.             className="org.springframework.web.struts.ContextLoaderPlugIn">    
20.    <set-property property="contextConfigLocation"   
21.                 value="/WEB-INF/applicationContext.xml" />    
22.    </plug-in>   

Action中的代码: 
Java代码
1.    public class UserAction extends MappingDispatchAction {    
2.    //使用普遍依赖注入方式    
3.    UserService userService;    
4.    public void setUserService(UserService userService) {    
5.            this.userService = userService;    
6.    }    
7.    public ActionForward login(ActionMapping mapping, ActionForm form,    
8.                 HttpServletRequest request, HttpServletResponse response)    
9.                throws Exception {    
10.             String uname = request.getParameter("uname");    
11.             String upass = request.getParameter("upass");    
12.            //直接使用userService    
13.             User user = userService.findByName(uname, upass);    
14.            if (user==null) {    
15.                 request.setAttribute("error", "对不起,您输入的用户名或者密码错误!");    
16.                    
17.                return mapping.findForward("failure");    
18.             } else {    
19.                 request.getSession().setAttribute("user", user);    
20.                return mapping.findForward("success");    
21.                    
22.             }    
23.         }    
24.    }   

这个配置只于传统的struts-config的配置.这里使用的是Spring的注册代理.而不是直接使用相应Action类的完整类名. 
这里使用的ContextLoaderPlugIn.声明的环境。通过DelegatingActionProxy使用动作映射名/login在Spring环境中找到相应的Action.所以我们需要在Spring环境中注

册一个Struts的动作: 
Java代码
1.    <bean name="/login" class="com.addresslist.action">    
2.    <property name="userService" ref="userService"></property>    
3.    </bean>   

这个方法可以说是多数人认可最好的方法: 
这个方法的使用只在配置文件中着手不需要对源码进行修改.将struts动作放置到Spring中使得其享受了Spring提供的各种好处.一旦让 Spring 控制您的 Struts 动作

,您就可以使用 Spring 给动作补充更强的活力。例如,没有 Spring 的话,所有的 Struts 动作都必须是线程安全的。如果您设置 <bean> 标记的 singleton 属性

为“false”,那么不管用何种方法,您的应用程序都将在每一个请求上有一个新生成的动作对象。您也可以利用 Spring 的生命周期方法。例如,当实例化 Struts 动

作时,<bean> 标记的 init-method 属性被用于运行一个方法。类似地,在从容器中删除 bean 之前,destroy-method 属性执行一个方法. 

整合方式4: 
使用 org.springframework.web.struts.DelegatingRequestProcessor 类来覆盖 Struts 的 RequestProcessor 处理程序 
只需要在struts-config.xml中配置: 
Java代码
1.    <action-mappings>    
2.         <action path="/login" parameter="login" type="com.addresslist.action.UserAction">    
3.         <forward name="success" path="/page/index.htm"/>    
4.         <forward name="failure" path="/page/fail.htm"/>    
5.         </action>    
6.    <!--下面controller配置是核心-->    
7.    <controller processorClass="org.springframework.web.struts.    
8.        DelegatingRequestProcessor"/>    
9.    <plug-in    
10.             className="org.springframework.web.struts.ContextLoaderPlugIn">    
11.    <set-property property="contextConfigLocation"   
12.                 value="/WEB-INF/applicationContext.xml" />    
13.    </plug-in>   

Struts中的action配置则无需配置type属性(即使配置了type属性也不起任何作用,除非在spring的配置文件里找不到对应的name属性值) 
其他的配置和类使用和整合方式3一样. 
这个设计方式是使用Spring提供的一个RequestProcessor来进行工作.这里如果对struts工作流程比较熟悉的话就指定struts1.2真正工作的核心是RequestProecssor和

Action. 
这里使用Spring的DelegatingRequestProcessor替换了struts的RequestProcessor.可以使得struts享受到Spring的控制容器.网上人都不建议使用这种方法.因为考虑

到效率和方法使用寿命的问题.所以我也比较少用. 
总结语: 
通过以上的总结。大概了解了struts和Spring整合的几种方式.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息