Struts与hibernate 整合 一 何谓两者的整合? 简单的来说就是让spring来管理struts Action的创建(包括关联对象),能充分利用spring的依赖注入优势,而无须显式的获取applicationContext实例。 二 主要的方式 1 使用DelegatingRequestProcessor 需要为struts增加ContextLoaderPlugin 由于ActionServlet是调用requestProcessor完成实际的转发,如果想将Action截获的请求转发给applicationContext 的bean。可以通过requestProcessor完成 这是通过用delegatingRequestProcessor替换requestProcessor实现的。 这样所有的请求就会转发到spring中配置的Action,而不是根据struts的action元素中配置的type属性进行action选择。从而实现了由spring管理action 缺点:占用了controllor,无法进行其它需要扩展requestProcessor的情况。 2 使用delegatingActionProxy(推荐使用,因为上一种方式占用了requestProcessor) 将所有的请求都发到DelegatingActionProxy类(通过配置所有struts的action为DelegatingActionProxy,再由DelegatingActionProxy根据path属性去匹配spring中配置的相关Action).利用IOC生成Action并运行。 下面看一下具体的配置: 先看一下struts-config.xml: <struts-config> <form-beans> <form-bean name="HelloForm" type="com.hf.struts.sayHello.HelloForm"/> </form-beans> <action-mappings> <!-- HELLOWORLD 配置,使用了spring 来管理strutsAction --> <action path = "/helloWorld" type = "org.springframework.web.struts.DelegatingActionProxy" name = "HelloForm" scope = "request" validate = "true" input = "/sayHelloTest/sayHello.jsp" > <forward name="displayHello" path="/sayHelloTest/displayHello.jsp" /> </action> </action-mappings> <!-- 资源文件 --> <message-resources parameter="com.hf.struts.application" /> <!-- spring管理struts的控件 --> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml"/> </plug-in> </struts-config> 我们可以看到增加了一个plug-in,这主要是用来保证随应用启动时创建applicationContext实例。 除此之外和平常struts配置文件最大的不同就在于action标签的type属性,此属性均为org.springframework.web.struts.DelegatingActionProxy,即所有的action都指向这样一个类型的实体对象,由他进行action的生成,控制,处理。至于如何知道生成何种Action,这是由path属性决定的,请见下文。 我们再来看一下spring 的配置文件,这里有两个,一个用来存放关于struts的信息,另一个存spring其他信息,这两个文件分别在struts的plug-in中指定(见上面)。 Action-servlet.xml: 存放struts信息。 <?xml version="1.0" encoding="GB2312"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean name="/helloWorld" class="com.hf.struts.sayHello.HelloAction" singleton="false"><!--每个request请求产生新实例--> <property name="pb"> <ref bean="personBean"/> </property> </bean> </beans> 这里定义了一个Action,这里的class本来是应该在struts-config的action标签的type中定义的。也就是说,访问 真正的action配置是在这里的。那么这是怎么关联起来的呢,看一下两个文件,会发现<bean>的name和action的path是一致的,明白了吧?? 这样做使我们可以充分利用spring的ioc特性,可以对action对象进行组织,在这里,我们为action指定了一个pb成员变量。他们创建及相互的关联均由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="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://127.0.0.1:3306/hibernatetest?characterEncoding=UTF8</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>12456</value> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> </props> </property> <property name="mappingResources"> <list> <value>com/hf/hibernate/hbm/User.hbm.xml</value> </list> </property> </bean> <bean id="personBean" class="com.hf.bean.sayHello.PersonBean"> <property name="userDAO"> <ref bean="userDAO"/> </property> </bean> <bean id="userDAO" class="com.hf.dao.sayHello.UserDAO" singleton="true"> <property name="sessionFactory"> <ref local="sessionFactory"/> </property> </bean> </beans> 对struts有用的部分就是 <bean id="personBean" class="com.hf.bean.sayHello.PersonBean"> <property name="userDAO"> <ref bean="userDAO"/> </property> </bean> 他被关联到上面的action对象。 这样在我们的com.hf.struts.sayHello.HelloAction中,就会自动拥有一个PersonBean对象,无须手工创建。(这里的PersonBean是业务逻辑处理部分) 看一下代码: publicfinalclass HelloAction extends Action { PersonBean pb = null; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String userName = (String)((HelloForm) form).getUserName(); pb.setUserName(userName); int times=pb.saveToPersistentStore(); request.setAttribute( "personbean", pb); request.setAttribute("times",String.valueOf(times)); //request.setAttribute("times",String.valueOf(1)); request.removeAttribute(mapping.getAttribute()); return (mapping.findForward("displayHello")); } public PersonBean getPb() { returnpb; } publicvoid setPb(PersonBean pb) { this.pb = pb; } }