除了通用配置外,有两种方式可以将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无效