(如需引用请注明出处:
http://blog.youkuaiyun.com/haofeng82/archive/2007/04/24/1579373.aspx
)
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
>
我们可以看到增加了一个p
lug-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是业务逻辑处理部分)
看一下代码:
public
final
class
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() {
return
pb
;
}
public
void
setPb(PersonBean pb) {
this
.
pb
= pb;
}
}
说到这,struts和spring的整合的基本方法已经介绍完了。感觉还是有一定的用处,但感觉用处不是很大,起码没有hibernate和spring整合带来的好处多。
如需要这一部分的完整代码,请留言回复