Action不再继承Struts提供的Action类,而是要继承Spring提供的ActionSupport类,然后在Action中获得Spring的ApplicationContext,在这个示例中需要修改的地方为HelloWorldAction类,如下:
public class HelloWorldAction extends ActionSupport{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ApplicationContext cx=getWebApplicationContext();
HelloWorldService helloWorldService=(HelloWorldService)cx.getBean("helloWorldService");
String msg=helloWorldService.addMesg((HelloWorldForm)form);
request.setAttribute("helloWorld", msg);
return mapping.findForward("show");
}
}
这种方法简单明了,将继承的父类换成ActionSupport,然后利用ApplicationContext获得Spring里面配置的Bean就可以了,但它的缺点也比较大,就是Struts的Action不在Spring的控制之下,假如换用别的框架以及使用Spring的AOP都是比较困难的,假如你要使用多路径控制ACTION的时候,这种整合方法也无能为力了!
方法2:
在Struts里面担任角色控制的是ActionServlet,我们可以在Web.xml中看到:
<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</param-value>
</init-param>
Spring提供DelegatingRequestProcessor类,用来替代Struts中的ActionServlet,从而把Struts的Action与Spring分离开来,并把Struts的动作置于Spring的框架控制之下,下面的例子是在原有的Struts例子中改行整合:
首先让Spring的DelegatingRequestProcessor代替Struts的ActionServlet,在Struts配置文件中注册一下就好了,修改后struts-config.xml如下:
</action-mappings>
<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"></controller>
<message-resources parameter="ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
注意元素的位置不能乱
修改Spring的配置文件,让Struts的动作处于Spring框架的控制之下,修改后的applicationContext.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="helloWorldService" class="com.yourcompany.struts.action.HelloWorldServiceImpl"></bean>
<bean name="/helloWorld" class="com.yourcompany.struts.action.HelloWorldAction">
<property name="helloWorld">
<ref bean="helloWorldService"/>
</property>
</bean>
</beans>
我们的Action也要稍做一些修改,以便Spring对其进行注入,父类不变,如下:
package com.yourcompany.struts.action;
public class HelloWorldAction extends Action{
private HelloWorldService helloWorld;
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
String msg=this.helloWorld.addMesg((HelloWorldForm)form);
request.setAttribute("helloWorld", msg);
return mapping.findForward("show");
}
public HelloWorldService getHelloWorld() {
return helloWorld;
}
public void setHelloWorld(HelloWorldService helloWorld) {
this.helloWorld = helloWorld;
}
}
方法2也整合完成了
这个方法还是很不错的,Struts里面没有出现一点Spring的痕迹,但这种方法还是有缺点的,假如开发人员自定义RequestProcessor,没有使用Struts的RequestProcessor那就要手动整合Spring,Struts了,我暂时还没有遇到过这方面的问题.
方法3:
Spring提供了DelegatingActionProxy类,用来代理Struts中的动作,负责在Spring中配置方档中找到相对应的动作映射,从而将Struts的Action与Spring分离,在操作中,我们不需要再在struts-config.xml注册Spring的控制器了,此例子是在方法2的基础上进行修改,但struts-config.xml与方法1中的是一样的.
<message-resources parameter="ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
</struts-config>
但它的Action元素中的type是不一样的,它应该指定为:
org.springframework.web.struts.DelegatingActionProxy
以便Spring进行代理,完整的struts-config.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans >
<form-bean name="helloWorld" type="com.yourcompany.struts.form.HelloWorldForm" />
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings >
<action
attribute="helloWorld"
name="helloWorld"
path="/helloWorld"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="show" path="/show.jsp" />
</action>
<action forward="/input.jsp" path="/input" />
</action-mappings>
<message-resources parameter="ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
</struts-config>
同样使用方法2的Spring配置文件applicationContext.xml
<beans>
<bean id="helloWorldService" class="com.yourcompany.struts.action.HelloWorldServiceImpl"></bean>
<bean name="/helloWorld" class="com.yourcompany.struts.action.HelloWorldAction">
<property name="helloWorld">
<ref bean="helloWorldService"/>
</property>
</bean>
</beans>
Spring会自动进行动作的匹配工作
这时我们应该发现第三种方法最合适,Spring,Struts的整合,Struts与Spring的整合应该很多人都会了,但我自已总算动手做过了一遍.
附件不好传,要源码的发个EMAIL到我邮箱,badwps@163.com,有问题的话也可以留言,我们大家一起讨论下.