关于Spring , Struts结合学习。
一、前言
刚刚接触了日本一个项目,用的框架名称是Northland Framework,主要用到以下部分
Struts、Spring、iBATIS、Velocity。Struts、Spring如何结合在一起?
二、
Spring
提供了三种整合
Struts
的方法:
使用
Spring
的
ActionSupport
类整合
Structs
使用
Spring
的
DelegatingRequestProcessor
覆盖
Struts
的
RequestProcessor
将
Struts Action
管理委托给
Spring
框架
(
参见
Get a better handle on Struts actions, with Spring
对应还有译文:
三、我只关心第三种整合方法:
这种方法通过
Spring
提供的两个和
Struts
相关类来实现:
org.springframework.web.struts.
DelegatingActionProxy
,
org.springframework.web.struts.
ContextLoaderPlugIn
。
ContextLoaderPlugIn
实现
Struts
的
PlugIn
接口,只要在
struts-config.xml
中有如下配置:
<
action
path
=
"/searchSubmit"
>
type
=
"ca.nexcel.books.actions.DelegatingActionProxy"
input
=
"/searchEntry.do"
validate
=
"true"
name
=
"searchForm"
>
<
forward
name
=
"success"
path
=
"/WEB-INF/pages/detail.jsp"
/>
<
forward
name
=
"failure"
path
=
"/WEB-INF/pages/search.jsp"
/>
</
action
>
<
plug-in
className
=
"org.springframework.web.struts.ContextLoaderPlugIn"
>
<
set-property
property
=
"contextConfigLocation"
value
=
"/WEB-INF/beans.xml"
/>
</
plug-in
>
|
ActionServlet
装载的时候就可以顺便装载和
Spring
相关的
beans.xml
,和
beans.xml
中相关的一个东西叫做
WebApplicationContext , (
在
Spring
里关键就是取得
WebApplicationContext
,取得这个也就可以用
Spring
管理业务
)
,在
ContextLoaderPlugIn
中是这样保存
WebApplicationContext
:
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
再看
DelegatingActionProxy
,它继承于
Struts
的
Action
,以后
struts-config.xml
中所有的
Action-mapping
都要指向它,只是每个
Action-mapping
的
path
不同,将来也是用这个
path
来区分究竟需要执行
beans.xml
中的那个类。如下代码:
public ActionForward execute(){
Action delegateAction = getDelegateAction(mapping);
return delegateAction.execute(mapping, form, request, response);
}
|
这里的
delegateAction
就是
beans.xml
中一个相关的类
(beans.xml
也要求类继承于
Struts
的
Action)
去看看怎么得到
delegateAction
:
protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
WebApplicationContext wac = getWebApplicationContext(getServlet(),
mapping.getModuleConfig());
String beanName = determineActionBeanName(mapping);
return (Action) wac.getBean(beanName, Action.class);
}
|
是如何取得
WebApplicationContext
呢:
wac=(WebApplicationContext)actionServlet.getServletContext().getAttribute( ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX);
|
SERVLET_CONTEXT_PREFIX
正是 前边提到的
ContextLoaderPlugIn
中
的
attrName
。
现在这个原理一目了然,
ContextLoaderPlugIn
在
actionServlet
初始化过程中保存
起来留到后面供
DelegatingActionProxy
用。
四、在另一篇文章中提到在上面的方法中
OpenSessionInView Filter
不能用
在
web.xml
中配置
ContextLoaderListener
:
<
context-param
>
<
param-name
>
contextConfigLocation
</
param-name
>
<
param-value
>
/WEB-INF/beans.xml
</
param-value
>
</
context-param
>
<
listener
>
<
listener-class
>
org.springframework.web.util.Log4jConfigListener
</
listener-class
>
</
listener
>
<
listener
>
<
listener-class
>
org.springframework.web.context.ContextLoaderListener
</
listener-class
>
</
listener
>
|
对应的
beans.xml
和前边那个一样,
Log4jConfigListener
先不用管,去查看相关文档。
Web
服务启动的时候,我们去看看
ContextLoaderListener
作了什么:
WebApplicationContext = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
|
同样是保存
WebApplicationContext
,但是
key
是
ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
怎么才能不用
ContextLoaderPlugIn
而只用
ContextLoaderListener
?
下面我修改
org.springframework.web.struts.
DelegatingActionProxy
把它修改成
ca.nexcel.books.actions.
DelegatingActionProxy
并且修改一下代码:
修改
getWebApplicationContext
方法
Return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet,
moduleConfig);
换成下边方法
|
|
ServletContext sc = actionServlet.getServletContext();
WebApplicationContext wac = null;
wac = WebApplicationContextUtils.getWebApplicationContext(sc);
return wac;
|
并且在
struts-config.xml
中将
action
的
type
指向自己的
ca.nexcel.books.actions.
DelegatingActionProxy
,
PlugIn
删除
web.xml
加上刚才提到的
Listener
,启动
tomcat
运行一切正常。
五、我把
northland
的配置文件贴出来。
Struts-config.xml
:
<
action-mappings
>
<
action
path
=
"/list"
input
=
"/list.jsp"
name
=
"_list"
scope
=
"request"
type
=
"jp.co.nec.hnes.northland.web.struts.FlowAction"
>
<
display-name
>
一覧画面
</
display-name
>
</
action
>
<
action
path
=
"/register"
input
=
"/register.jsp"
name
=
"_register"
scope
=
"request"
type
=
"jp.co.nec.hnes.northland.web.struts.FlowAction"
>
<
display-name
>
登録画面
</
display-name
>
</
action
>
|
|
Web.xml:
<
context-param
>
<
param-name
>
contextConfigLocation
</
param-name
>
<
param-value
>
classpath:flowConfig.xml,
classpath:viewConfig.xml,
classpath:applicationContext.xml,
classpath:applicationContext-extra.xml
</
param-value
>
</
context-param
>
<
listener
>
<
listener-class
>
org.springframework.web.util.Log4jConfigListener
</
listener-class
>
</
listener
>
<
listener
>
<
listener-class
>
org.springframework.web.context.ContextLoaderListener
</
listener-class
>
</
listener
>
<
servlet
>
<
servlet-name
>
ActionServlet
</
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
>
</
servlet
>
|
从中可以看到
其中的
jp.co.nec.hnes.northland.web.struts.FlowAction
和
ca.nexcel.books.actions.
DelegatingActionProxy
的功能差不多。
posted on 2006-09-21 15:04
jackstudio 阅读(3139)
评论(0) 编辑 收藏 所属分类:
common 、
struts 、
spring