使用MyEclipse集成SSH和DWR(一)整合Spring和Struts

来源:互联网 发布:重启linux服务器关闭 编辑:程序博客网 时间:2024/05/17 02:41

 开发环境:
  1. JDK 1.5
  2. Tomcat 6.0
  3. Spring 2.5
  4. Struts 1.3
  5. Hibernate 3.2
  6. DWR 2.0
  7. MyEclipse 6.5
  8. SQL Server 2005
本系列文章PDF格式及示例源代码请到此处下载

Spring和Struts整合的价值在于将Struts使用的BO或DAO 乃至Action交给Spring管理,从而充分利用Spring强大的IoC和AOP 特性。

   无论使用哪种方式整合,都需要为 Struts装载 Spring 应用上下文环境。有以下三种方式:


         1) 在struts-config.xml中使用Struts Plugin

  1. <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
  2.    <set-property property="contextConfigLocation"    value="/WEB-INF/classes/applicationContext.xml,/WEB-INF/action-servlet.xml"/>
  3. </plug-in>

         2) 在web.xml中使用ContextLoaderListener

  1. <context-param>
  2.       <param-name>contextConfigLocation</param-name>
  3.       <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
  4. </context-param>
  5. <listener>
  6.       <listener-class>
  7.             org.springframework.web.context.ContextLoaderListener
  8.       </listener-class>
  9. </listener>

         3) 在web.xml中使用ContextLoaderServlet

  1. <context-param>
  2.       <param-name>contextConfigLocation</param-name>
  3.       <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
  4. </context-param>
  5. <servlet>
  6.      <servlet-name>SpringContextServlet</servlet-name>
  7.      <servlet-class>
  8.          org.springframework.web.context.ContextLoaderServlet
  9.       </servlet-class>
  10.       <load-on-startup>1</load-on-startup>
  11. </servlet>

注意:
   用Struts PlugIn的方式加载Spring配置文件有可能导致DWR无法取得Spring中定义的bean,因为DWR有可能先于Struts被访问使用,而此时Struts配置文件还未加载!
   因此,在Spring、Struts和DWR 集成时,应该在web.xml中通过ContextLoaderLisenter或ContextLoaderServlet加载Spring配置文件。
   最佳实践是使用Struts PlugIn的方式加载Struts Action配置文件/WEB-INF/action-servlet.xml,而使用ContextLoaderLisenter或ContextLoaderServlet方式加载Spring配置文件applicationContext.xml,通过两次加载完成Spring所有配置文件的加载。


至少有四种Spring与Struts整合方式:


1. 手工创建Spring 环境整合 Spring和Struts
  为了Web应用环境可以和Spring的IoC容器很好的结合,Spring提供了专门用于Web应用环境中的Spring 容器——WebApplicationContext。使用ContextLoaderPlugIn装载 Spring 应用程序环境时,ContextLoaderPlugIn会自动创建一个WebApplicationContext对象,并加载相应的配置文件,然后将其保存在ServletContext中。之后所有的Servlet或Action便都可以通过ServletContext访问该WebApplicationContext实例并从中获取BO或DAO Bean。

  1. ServletContext servletContext=this.getServlet().getServletContext();
  2. WebApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext(servletContext);
  3. UserInfoDAO userInfoDAO=(UserInfoDAO)ctx.getBean("userInfoDAO");

2. 使用 Spring 的 ActionSupport 类整合 Struts
   org.springframework.web.struts.ActionSupport 类提供了一个 getWebApplicationContext() 方法可以获取到WebApplicationContext实例,您所做的只是从 Spring 的 ActionSupport 而不是 Struts Action 类扩展您的动作:

  1. public class AddActionSupport extends ActionSupport {
  2.     public ActionForward execute(ActionMapping mapping, ActionForm form,
  3.             HttpServletRequest request, HttpServletResponse response) {
  4.         AddForm addForm = (AddForm) form;
  5.         UserInfo user=new UserInfo();
  6.         user.setUserName(addForm.getName());
  7.         user.setUserPwd(addForm.getPassword());
  8.         UserInfoDAO userInfoDAO=
  9. (UserInfoDAO)getWebApplicationContext().getBean("userInfoDAO");
  10.         userInfoDAO.save(user);
  11.         return mapping.findForward("success");
  12.     }
  13. }

结论:第1、2种整合方式由Spring来管理BO或DAO Bean,实现了表示层和业务逻辑层的解耦,但Struts的Action和Spring耦合在了一起,违反了Spring“非侵入”性原则;另外,Action类负责查找由Spring管理的Bean,也违背了Spring控制反转(IoC)的原则。以下第3、4种整合方式实现了由Spring来管理Struts Action,实现了Struts和Spring的解耦,从而解决了以上问题。

3. 使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor
  用Spring的DelegatingRequestProcessor重载Struts 默认的 RequestProcessor。这样当收到一个针对 Action的请求时,DelegatingRequestProcessor会自动从Spring Context中查找对应的Action Bean。
  在struts-config.xml中添加: 

  1. <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>

4. 【最佳方案】使用DelegatingActionProxy将Struts Action 管理全权委托给 Spring 框架
  Action 的创建和对象的依赖注入全部由IOC容器来完成,使用Spring的DelegatingAcionProxy来帮助 实现代理的工作。DelegatingActiongProxy继承于org.apache.struts.action.Action 。此时需要将struts-config.xml中所有Action类别全部配置为 org.springframework.web.struts.DelegatingActionProxy:

  1. <action
  2.       attribute="loginForm"
  3.       input="/login.jsp"
  4.       name="loginForm"
  5.       path="/login"
  6.       scope="request"
  7.       type="org.springframework.web.struts.DelegatingActionProxy">
  8.       <forward name="error" path="/error.html" />
  9.       <forward name="success" path="/success.html" />
  10. </action>

 3、4两种方式都需要在WEB-INF下新建一个action-servlet.xml作为Spring context文件,创建Struts Action Bean,并对Action进行BO或DAO Bean注入:

  1. <!--name 的取值一定要和Struts 配置文件action 中的path 的值相对应-->
  2. <bean name="/login" class="cn.qdqn.ssh.struts.action.LoginAction">
  3.       <property name="userBO">
  4.        <ref bean="userBO"/>
  5.       </property>
  6. </bean>

结论:
  以上2种方式实现了由Spring管理Struts的Action,从而可以利用Spring在Struts Action中轻松的注入BO或DAO,还可以将 Spring 的 AOP 拦截器应用于Struts 动作,用最小的代价处理横切关注点。
   第3种整合方式只需要配置一个<controller>,不需要改动Struts Action配置信息,但Struts的RequestProcessor只能被重载一次,如果在应用中还要进行编码等其它功能RequestProcessor重载时,此种方式将异常繁琐。
   第4种整合方式可以避免RequestProcessor的占用,但必须将struts-config.xml中所有Action类别全部配置为 org.springframework.web.struts.DelegatingActionProxy。

原创粉丝点击