?
This document uses PHP Chinese website manual Release
Struts 是 應(yīng)用最廣的 Java Web 開(kāi)發(fā)框架,主要是因?yàn)樗亲钕劝l(fā)行的幾個(gè)框架之一(2001年6月)。這個(gè)框架由 Craig McClanahan 開(kāi)發(fā)完成,現(xiàn)在作為 Apache 軟件基金會(huì)的一個(gè)開(kāi)源項(xiàng)目。 當(dāng)時(shí),它極大地簡(jiǎn)化了 JSP/Servlet 編程范例并且贏得了大多數(shù)正在使用私人框架的開(kāi)發(fā)人員的青睞。它簡(jiǎn)化了編程模型,它是開(kāi)源的,它具有一個(gè) 龐大的社區(qū),這些都使得這個(gè)項(xiàng)目快速成長(zhǎng),同時(shí)變得越來(lái)越流行。
要集成Struts 與 Spring,有兩個(gè)選擇:
配置 Spring 將 Action 作為 bean 托管,使用 ContextLoaderPlugin
,
并且在 Spring context中設(shè)置依賴關(guān)系。
繼承 Spring 的 ActionSupport
類并且
使用getWebApplicationContext() 方法獲取 Spring 管理的 bean。
ContextLoaderPlugin
是 Struts 1.1+ 的插件,用來(lái)為 Struts 的 ActionServlet
加載 Spring context文件。
這個(gè)context引用 WebApplicationContext
(由 ContextLoaderListener
加載)
作為它的父類。默認(rèn)的context文件是映射的 Servlet 的名字,加上 -servlet.xml后綴。
如果 ActionServlet
在 web.xml 里面的定義是 <servlet-name>action</servlet-name>
,
那么默認(rèn)的文件就是 /WEB-INF/action-servlet.xml。
要配置這個(gè)插件,請(qǐng)把下面的 XML 貼到 struts-config.xml 文件中 plug-ins 部分的底端:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/>
context配置文件的位置可以通過(guò) ‘contextConfigLocation
’ 屬性來(lái)自定義。
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/action-servlet.xml,/WEB-INF/applicationContext.xml"/> </plug-in>
也可以使用這個(gè)插件加載所有的配置文件,這在使用測(cè)試工具(例如 StrutsTestCase)的時(shí)候特別有用。
StrutsTestCase 的 MockStrutsTestCase
不會(huì)在啟動(dòng)的時(shí)候初始化 Listener,
將你所有的配置文件放在plug-in里面是一種解決方案。(有個(gè) 已記錄的 bug
就是針對(duì)這個(gè)問(wèn)題的,但是已經(jīng)被標(biāo)記為“無(wú)須改正”)。
在 struts-config.xml 中配置好插件以后,你可以配置Sping來(lái)管理
Action
。Spring (1.1.3以后的版本) 提供下面兩種方式:
用 Spring 的DelegatingRequestProcessor
重載 Struts
默認(rèn)的 RequestProcessor
。
將 <action-mapping>
的 type
屬性設(shè)為
DelegatingActionProxy
。
這兩種方法都允許在 action-servlet.xml 文件中管理你的 Action 以及依賴關(guān)系。 連接 struts-config.xml 和 action-servlet.xml 中的 Action 的橋梁 是 action-mapping 的“path”和 bean 的“name”。如果在 struts-config.xml 文件中有如下配置:
<action path="/users" .../>
你必須在 action-servlet.xml 中將 Action bean 的名字定義為 “/users”:
<bean name="/users" .../>
為了在 struts-config.xml 文件中配置
DelegatingRequestProcessor
,你需要重載 <controller> 元素的 “processorClass” 屬性。
下面的幾行應(yīng)該放在 <action-mapping> 元素的后面。
<controller> <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/> </controller>
增加這些設(shè)置之后,不管你查詢?nèi)魏晤愋偷?Action,Sping都自動(dòng)在它的context配置文件中尋找。 實(shí)際上,你甚至不需要指定類型。下面兩個(gè)代碼片斷都可以工作:
<action path="/user" type="com.whatever.struts.UserAction"/> <action path="/user"/>
如果使用 Struts 的 modules 特性,則 bean 命名必須含有 module 的前綴。
舉個(gè)例子,如果一個(gè) Action 的定義為 <action path="/user"/>
,而且它的 module 前綴為“admin”,
那么它應(yīng)該對(duì)應(yīng)名為 <bean name="/admin/user"/>
的 bean。
如果在 Struts 應(yīng)用中使用了 Tiles,則需要配置 <controller> 為
DelegatingTilesRequestProcessor
如果你有一個(gè)自定義的 RequestProcessor
并且不能夠使用
DelegatingRequestProcessor
或者
DelegatingTilesRequestProcessor
,你可以使用
DelegatingActionProxy
作為你 action-mapping 中的類型。
<action path="/user" type="org.springframework.web.struts.DelegatingActionProxy" name="userForm" scope="request" validate="false" parameter="method"> <forward name="list" path="/userList.jsp"/> <forward name="edit" path="/userForm.jsp"/> </action>
action-servlet.xml 文件中的bean定義依然不變,不管你使用了自定義的
RequestProcessor
還是 DelegatingActionProxy
。
如果把 Action
定義在Spring的context文件里,那么 Spring bean 容器的所有特性都可用了:
比如,依賴注入,再比如,為每個(gè)請(qǐng)求初始化一個(gè)新的 Action
實(shí)例。
如果要使用這個(gè)特性,Action bean 定義中需要聲明scope="prototype"。
<bean name="/user" scope="prototype" autowire="byName" class="org.example.web.UserAction"/>
正如前面提到的,可以使用 WebApplicationContextUtils
類從
ServletContext 中獲得 WebApplicationContext
。
另一個(gè)簡(jiǎn)單的辦法是繼承 Spring 的 Action
類。舉個(gè)例子,除了繼承 Struts 的
Action
之外,你也可以繼承 Spring 的
ActionSupport
類。
ActionSupport
類提供了一些便利的方法,例如 getWebApplicationContext()。
下面的例子展示了如何在 Action 中使用它:
public class UserAction extends DispatchActionSupport { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { if (log.isDebugEnabled()) { log.debug("entering 'delete' method..."); } WebApplicationContext ctx = getWebApplicationContext(); UserManager mgr = (UserManager) ctx.getBean("userManager"); // talk to manager for business logic return mapping.findForward("success"); } }
Spring 包含了所有標(biāo)準(zhǔn) Struts Action 的子類 - Spring 版本在類名末尾附加了 Support:
ActionSupport
,
DispatchActionSupport
,
LookupDispatchActionSupport
and
MappingDispatchActionSupport
.
應(yīng)該選擇最適合你項(xiàng)目的集成方式。繼承使得你的代碼更可靠,并且你確切地知道依賴關(guān)系是如何被解析的。
另一方面,使用 ContextLoaderPlugin
允許你方便地在context XML 文件里面增加新的
依賴關(guān)系。這兩種集成方法,不管哪一種 Spring 都提供了相當(dāng)好用的選項(xiàng)。