除了通用配置外,有两种方式可以将Struts1.x集成到Spring中:
- 最简单集成:使用Spring提供的WebApplicationContextUtils工具类中的获取Spring Web容器,然后通过Spring Web容器获取Spring管理的Bean;
- Struts1.x插件集成:利用Struts1.x中的插件ContextLoaderPlugin来将Struts1.x集成到Spring中
首先我们需要准备必须的jar包
1、从下载的spring-framework-3.0.5.RELEASE-with-docs.zip中dist目录查找如下jar包,该jar包用于提供集成struts1.x所需要的插件实现等:
org.springframework.web.struts-3.0.5.RELEASE.jar
2、从下载的spring-framework-3.0.5.RELEASE-dependencies.zip中查找如下依赖jar包,该组jar是struts1.x需要的jar包:
com.springsource.org.apache.struts-1.2.9.jar //struts1.2.9实现包
com.springsource.org.apache.commons.digester-1.8.1.jar //用于解析struts配置文件
com.springsource.org.apache.commons.beanutils-1.8.0.jar //用于请求参数绑定
com.springsource.javax.servlet-2.5.0.jar //Servlet 2.5 API
一、最简单的集成只使用通用配置,利用WebApplicationContextUtils提供的获取Spring Web容器方法获取Spring Web容器,然后从Spring Web容器获取Spring管理的Bean。
public class SysConfigAction extends DispatchAction{ private SysConfigBIS sysconfigbis; /** * 进入系统配置分类页面 */ public ActionForward SVSearchSysConfig(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { try{ WebApplicationContext ctx = WebApplicationContextUtils. getRequiredWebApplicationContext(getServlet().getServletContext()); sysconfigbis=ctx.getBean("sysconfigbis", SysConfigBIS.class); List<ENViwSysConCategory> list =sysconfigbis.SearchSysConfig("1"); System.out.println("list.size="+list.size()); request.setAttribute("sysconfiglist", list); } catch(Exception e) { e.printStackTrace(); } return mapping.findForward("SVSearchSysConfig"); } }
spring的配置文件是
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="sysconfigbis" class="scienpro.sysconfig.business.SysConfigBIS"> </bean> </bean>
web.xml部署描述符文件定义是
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml,/WEB-INF/sysconfig/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- 配置spring --> <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> </web-app>
这样配置后通过http://localhost:9999/SpringForScien/sysconfig.do?method=SVSearchSysConfig就能访问到想要的页面。
如果对于一个已经写好的strut1工程,使用这种方法“集成”意味着每个action中的每个method都需要更改(获取业务组件bis),有没有简单的方法能够使它自动注入呢?接下来让我们学习使用Struts插件进行集成。
二、Struts1.x插件集成
Struts插件集成使用ContextLoaderPlugin类,该类用于为ActionServlet加载Spring配置文件。
1、在Struts配置文件中配置插件:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextClass" value="org.springframework.web.context.support.XmlWebApplicationContext"/> <set-property property="contextConfigLocation" value="classpath*:applicationContext-*.xml"/> <!--<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;
插件已经配置了,那如何定义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。
1、DelegatingActionProxy方式与Spring集成:
public class SysConfigAction extends DispatchAction{ private SysConfigBIS sysconfigbis; public void setSysconfigbis(SysConfigBIS sysconfigbis){ this.sysconfigbis=sysconfigbis; } /** * 进入系统配置分类页面 */ public ActionForward SVSearchSysConfig(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { try{ List<ENViwSysConCategory> list =sysconfigbis.SearchSysConfig("1"); System.out.println("list.size="+list.size()); request.setAttribute("sysconfiglist", list); } catch(Exception e) { e.printStackTrace(); } return mapping.findForward("SVSearchSysConfig"); } }
struts配置文件如下
<?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 parameter="method" path="/sysconfig" scope="request" type="org.springframework.web.struts.DelegatingActionProxy"> <forward name="SVSearchSysConfig" path="/sysconfig/sysconfigmanage.jsp" /> </action> </action-mappings> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextClass" value="org.springframework.web.context.support.XmlWebApplicationContext"/> <set-property property="contextConfigLocation" value="classpath*:applicationContext-*.xml"/> </plug-in> </struts-config>
Spring配置文件如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="sysconfigbis" class="scienpro.sysconfig.business.SysConfigBIS"></bean> <bean name="/sysconfig" class="scienpro.sysconfig.action.SysConfigAction"> <property name="sysconfigbis" ref="sysconfigbis"/> </bean> </beans>
从以上配置中可以看出:
- Struts配置文件中<action>标签的path属性和Spring配置文件的name属性应该完全一样,否则错误;
- Struts通过DelegatingActionProxy去到Spring Web容器中查找同名的Action Bean;
很简单吧,DelegatingActionProxy是个代理Action,其实现了Action类,其内部帮我们查找相应的Spring管理Action Bean并把请求转发给这个真实的Action。
2、DelegatingRequestProcessor方式与Spring集成:
首先要替换掉Struts默认的RequestProcessor,在Struts配置文件中添加如下配置
<?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> <controller> <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/> </controller> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="classpath*:applicationContext-*.xml"/> </plug-in> </struts-config>
由于这个配置是所有struts共用的(如果一个工程里有多个struts-xml),可以把它单独放到一个struts-xml中配置在web-xml,其他的struts-xml也能共享这个配置了(注意,struts-xml中的action-mappings、controller、plug-in是有排列的先后顺序的,否则会报错)
实际的struts-xml配置如下
<?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 parameter="method" path="/sysconfig" scope="request"> <forward name="SVSearchSysConfig" path="/sysconfig/sysconfigmanage.jsp" /> </action> </action-mappings> </struts-config>
type可选,如果选的话type=scienpro.sysconfig.action.SysConfigAction
Spring的配置和Action的写法与DelegatingActionProxy方式相同
从以上配置中可以看出:
- Struts配置文件中<action>标签的path属性和Spring配置文件的name属性应该完全一样,否则错误;
- Struts通过DelegatingRequestProcessor去到Spring Web容器中查找同名的Action Bean;
很简单吧,只是由DelegatingRequestProcessor去帮我们查找相应的Action Bean,但没有代理Action了,所以推荐使用该方式。
Struts1x与Spring集成到此就完成了,在集成时需要注意一下几点:
- 推荐使用ContextLoaderPlugin+DelegatingRequestProcessor方式集成;
- 当有多个Struts模块时建议在通用配置部分配置通用部分,因为通用配置在正在Web容器中是可共享的,而在各个Struts模块配置文件中配置是不可共享的,因此不推荐直接使用ContextLoaderPlugin中为每个模块都指定所有配置,因为ContextLoaderPlugin加载的Spring容器只对当前的ActionServlet有效对其他ActionServlet无效