關于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 閱讀(3155)
評論(0) 編輯 收藏 所屬分類:
common 、
struts 、
spring