方法:
1.使用 Spring 的 ActionSupport 类整合 Structs
2.使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor
3.将 Struts Action 管理委托给 Spring 框架
无论您使用哪种技术,都需要使用Spring的ContextLoaderPlugin为 Struts 的 ActionServlet 装载 Spring 应用程序环境。就像添加任何其他插件一样,简单地向您的 struts-config.xml 文件添加该插件,如下所示:
Java代码
<plug-in className= "org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>
<plug-in className= "org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/></plug-in>
也可以通过web.xml中配置web应用在加载的时候添加ContextListener来实现上面插件的功能
Spring框架提供了这样的类,配置信息如下:
Java代码
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
方法1.
使用 Spring 的 ActionSupport
手动创建一个 Spring 环境是一种整合 Struts 和 Spring 的最直观的方式。
为了使它变得更简单,Spring 提供了一些帮助。
为了方便地获得 Spring 环境,org.springframework.web.struts.ActionSupport
类提供了一个 getWebApplicationContext() 方法。
您所做的只是从 Spring 的 ActionSupport 而不是 Struts Action 类扩展您的动作
struts-config.xml文件配置:
Java代码
<?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="testForm"
type="com.yourcompany.struts.form.TestForm" />
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings >
<action
attribute="testForm"
input="/form/test.jsp"
name="testForm"
path="/test"
scope="request"
type="com.yourcompany.struts.action.TestAction">
<forward name="success" path="/result.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.yourcompany.struts.ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="classpath:applicationContext.xml" />
</plug-in>
</struts-config>
<?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="testForm" type="com.yourcompany.struts.form.TestForm" /> </form-beans> <global-exceptions /> <global-forwards /> <action-mappings > <action attribute="testForm" input="/form/test.jsp" name="testForm" path="/test" scope="request" type="com.yourcompany.struts.action.TestAction"> <forward name="success" path="/result.jsp" /> </action> </action-mappings> <message-resources parameter="com.yourcompany.struts.ApplicationResources" /> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="classpath:applicationContext.xml" /> </plug-in></struts-config>
applicationContext.xml的配置
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="springTest" class="com.spring.SpringIOC">
<property name="message">
<value>SpringIOC Message</value>
</property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="springTest" class="com.spring.SpringIOC"> <property name="message"> <value>SpringIOC Message</value> </property> </bean></beans>
Action类:
Java代码
package com.yourcompany.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.springframework.web.struts.ActionSupport;
import com.spring.SpringIOC;
public class TestAction extends ActionSupport {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
SpringIOC sIoc=(SpringIOC)this.getWebApplicationContext().getBean("springTest");
sIoc.displayMessage();
return mapping.findForward("success");
}
}
package com.yourcompany.struts.action;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.springframework.web.struts.ActionSupport;import com.spring.SpringIOC;public class TestAction extends ActionSupport { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { SpringIOC sIoc=(SpringIOC)this.getWebApplicationContext().getBean("springTest"); sIoc.displayMessage(); return mapping.findForward("success"); }}
注入到Action中的使用的类SpringIOC
Java代码
package com.spring;
public class SpringIOC {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void displayMessage(){
System.out.println(message);
}
}
package com.spring;public class SpringIOC { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public void displayMessage(){ System.out.println(message); }}
这种技术很简单并且易于理解。不幸的是,它将 Struts 动作与 Spring 框架耦合在一起。
如果您想替换掉 Spring,那么您必须重写代码。并且,由于 Struts 动作不在 Spring 的控制之下,所以它不能获得 Spring AOP 的优势。
当使用多重独立的 Spring 环境时,这种技术可能有用,但是在大多数情况下,这种方法不如另外两种方法合适。
方法2:覆盖 RequestProcessor
将 Spring 从 Struts 动作中分离是一个更巧妙的设计选择。
分离的一种方法是使用 org.springframework.web.struts.DelegatingRequestProcessor 类来覆盖 Struts 的 RequestProcessor 处理程序
struts-config.xml
Java代码
<action
attribute="testForm"
input="/form/test.jsp"
name="testForm"
path="/test"
scope="request"
type="com.yourcompany.struts.action.TestAction">
<forward name="success" path="/result.jsp" />
</action>
<!-- 关键点 重新使用Sping框架的DelegatingRequestProcessor 替代了Struts框架的RequestProcessor -->
<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor" />
<action attribute="testForm" input="/form/test.jsp" name="testForm" path="/test" scope="request" type="com.yourcompany.struts.action.TestAction"> <forward name="success" path="/result.jsp" /></action> <!-- 关键点 重新使用Sping框架的DelegatingRequestProcessor 替代了Struts框架的RequestProcessor --> <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor" />
applicationContext.xml
Java代码
<bean id="sIoc" class="com.spring.SpringIOC">
<property name="message">
<value>SpringIOC Message</value>
</property>
</bean>
<bean name="/test" class="com.yourcompany.struts.action.TestAction">
<property name="springIoc">
<ref local="sIoc"/>
</property>
</bean>
<bean id="sIoc" class="com.spring.SpringIOC"> <property name="message"> <value>SpringIOC Message</value> </property></bean> <bean name="/test" class="com.yourcompany.struts.action.TestAction"> <property name="springIoc"> <ref local="sIoc"/> </property> </bean>
Action类:
Java代码
public class TestAction extends Action{
private SpringIOC springIoc;
public SpringIOC getSpringIoc() {
return springIoc;
}
public void setSpringIoc(SpringIOC springIoc) {
this.springIoc = springIoc;
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
getSpringIoc().displayMessage();
return mapping.findForward("success");
}
}
public class TestAction extends Action{ private SpringIOC springIoc; public SpringIOC getSpringIoc() { return springIoc; } public void setSpringIoc(SpringIOC springIoc) { this.springIoc = springIoc; } public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { getSpringIoc().displayMessage(); return mapping.findForward("success"); }}
DelegatingRequestProcessor 方法的确比第一种方法好,但是仍然存在一些问题。
如果您使用一个不同的 RequestProcessor,则需要手动整合 Spring 的 DelegatingRequestProcessor。
添加的代码会造成维护的麻烦并且将来会降低您的应用程序的灵活性。
此外,还有过一些使用一系列命令来代替 Struts RequestProcessor 的传闻。
这种改变将会对这种解决方法的使用寿命造成负面的影响。
方法3:
将动作管理委托给 Spring, 一个更好的解决方法是将 Strut 动作管理委托给 Spring。
您可以通过在 struts-config 动作映射中注册一个代理来实现。
代理负责在 Spring 环境中查找 Struts 动作。
由于动作在 Spring 的控制之下,所以它可以填充动作的 JavaBean 属性,
并为应用诸如 Spring 的 AOP 拦截器之类的特性带来了可能。
struts-config.xml
Java代码
<!-- 方法3和方法2的区别所在 将Struts的动作委托给Spring框架的一个代理类来管理 -->
<action attribute="testForm"
name="testForm"
path="/test"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy"
validate="false">
<forward name="success" path="/result.jsp" />
</action>
<!-- 方法3和方法2的区别所在 将Struts的动作委托给Spring框架的一个代理类来管理 --> <action attribute="testForm" name="testForm" path="/test" scope="request" type="org.springframework.web.struts.DelegatingActionProxy" validate="false"> <forward name="success" path="/result.jsp" /> </action>
applicationContext.xml
Java代码
<bean id="sIoc" class="com.spring.SpringIOC">
<property name="message">
<value>SpringIOC Message</value>
</property>
</bean>
<bean name="/test" class="com.yourcompany.struts.action.TestAction">
<property name="springIoc">
<ref local="sIoc"/>
</property>
</bean>
<!-- Interceptors -->
<bean name="logger"
class="com.spring.interceptors.LoggingInterceptor" />
<!-- AutoProxies -->
<bean name="loggingAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>/test</value>
</property>
<property name="interceptorNames">
<list>
<value>logger</value>
</list>
</property>
</bean>
<bean id="sIoc" class="com.spring.SpringIOC"> <property name="message"> <value>SpringIOC Message</value> </property> </bean> <bean name="/test" class="com.yourcompany.struts.action.TestAction"> <property name="springIoc"> <ref local="sIoc"/> </property> </bean> <!-- Interceptors --> <bean name="logger" class="com.spring.interceptors.LoggingInterceptor" /> <!-- AutoProxies --> <bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <value>/test</value> </property> <property name="interceptorNames"> <list> <value>logger</value> </list> </property> </bean>
Action同方法2
拦截器类如下:
Java代码
package com.spring.interceptors;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class LoggingInterceptor implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o)
throws Throwable {
for(Object obj:objects){
System.out.println(obj.getClass());
}
System.out.println("target "+o.getClass());
System.out.println(method.getName());
System.out.println("logging before!");
}
}
package com.spring.interceptors;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class LoggingInterceptor implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable { for(Object obj:objects){ System.out.println(obj.getClass()); } System.out.println("target "+o.getClass()); System.out.println(method.getName()); System.out.println("logging before!"); }}
就像这个例子所展示的,将您的 Struts 动作置于 Spring 框架的控制之下,为处理您的 Struts 应用程序提供了一系列全新的选择。
在本例中,使用动作委托可以轻松地利用 Spring 拦截器提高 Struts 应用程序中的日志记录能力。