擴(kuò)展Struts框架
一個(gè)好的軟件框架應(yīng)該具備可擴(kuò)展特性。在Struts框架中提供了許多可擴(kuò)展之處,不放將其稱(chēng)為可擴(kuò)展點(diǎn)(Extension Point)。以下是Struts的擴(kuò)展點(diǎn):
· 一般性擴(kuò)展點(diǎn):Struts插件(PlugIn)、擴(kuò)展Struts配置類(lèi)。
· 控制器的擴(kuò)展點(diǎn):擴(kuò)展ActionServlet類(lèi)、RequestProcessor類(lèi)和Action類(lèi)。
· 視圖的擴(kuò)展點(diǎn):擴(kuò)展Struts客戶化標(biāo)簽。
· 模型的擴(kuò)展點(diǎn):擴(kuò)展SessionContainer類(lèi)和ApplicationContainer類(lèi)。
1.
Struts插件(PlugIn)
Struts1.1框架提供了動(dòng)態(tài)插入和加載組件的功能,這種組件被成為Struts插件。Struts插件實(shí)際上就是一個(gè)Java類(lèi),它在Struts應(yīng)用啟動(dòng)時(shí)被初始化,在應(yīng)用關(guān)閉時(shí)被銷(xiāo)毀。任何作為插件的Java類(lèi)都應(yīng)該實(shí)現(xiàn)org.apache.struts.action.PlugIn接口。PlugIn接口包括兩個(gè)方法:
public interface PlugIn {
/**
* Notification that the
specified application module is being started.
*/
public void
init(ActionServlet servlet, ApplicationConfig config)
throws
ServletException;
/**
* Notification that the
application module is being shut down.
*/
public void destroy();
}
一個(gè)Struts應(yīng)用可以包含一個(gè)或多個(gè)插件。在Struts應(yīng)用啟動(dòng)時(shí),Struts框架調(diào)用每個(gè)插件類(lèi)的init()方法進(jìn)行初始化。在插件的初始化階段,可以完成一些初始化操作,如建立數(shù)據(jù)庫(kù)連接,或者和遠(yuǎn)程系統(tǒng)的連接等。
當(dāng)應(yīng)用被關(guān)閉時(shí),Struts框架就會(huì)調(diào)用每個(gè)插件類(lèi)的destroy()方法,destroy()方法可以用來(lái)完成釋放資源的人物,如關(guān)閉數(shù)據(jù)庫(kù)連接或遠(yuǎn)程系統(tǒng)連接等。
除了創(chuàng)建插件類(lèi)外,還需要在Struts配置文件中配置插件,Struts框架在啟動(dòng)時(shí)將根據(jù)相關(guān)的配置信息來(lái)初始化插件。與插件對(duì)應(yīng)的配置元素為<plug-in>。
根據(jù)Struts配置文件的DTD定義,在Struts配置文件中,<plug-in>元素必需位于其他配置元素的后面。此外,如果在配置文件中配置了多個(gè)插件,Struts框架將按照它們?cè)谂渲梦募械南群箜樞騺?lái)一次初始化他們。
2.
擴(kuò)展Struts的配置類(lèi)
在Struts應(yīng)用啟動(dòng)時(shí),Struts配置文件中的所有信息都會(huì)被讀到內(nèi)存中,這些信息存放在org.apache.struts.config包的相應(yīng)配置類(lèi)的實(shí)例中。
多數(shù)配置元素都由一個(gè)className屬性,這個(gè)屬性用來(lái)設(shè)置和配置元素對(duì)應(yīng)的配置類(lèi)。每個(gè)配置元素都有默認(rèn)配置類(lèi),Struts框架允許對(duì)這些莫爾那配置類(lèi)進(jìn)行擴(kuò)展。
3.
控制器擴(kuò)展點(diǎn)
Struts框架在控制器中提供了許多可擴(kuò)展之處,允許擴(kuò)展ActionServlet、RequestProcessor和Action類(lèi),來(lái)實(shí)現(xiàn)各種客戶化功能。
3.1 擴(kuò)展ActionServlet類(lèi)
在Struts1.1以前的版本中,Struts應(yīng)用通常都需要擴(kuò)展ActionServlet類(lèi),來(lái)實(shí)現(xiàn)各種定制的控制功能。在Struts1.1中,擴(kuò)展ActionServlet類(lèi)不再是必需的。不過(guò)在某些情況下,根據(jù)實(shí)際情況需要,可不妨擴(kuò)展ActionServlet類(lèi)。
當(dāng)Struts應(yīng)用啟動(dòng)時(shí)會(huì)加載ActionServlet類(lèi)并調(diào)用它的init()方法,來(lái)對(duì)Struts框架進(jìn)行初始化。如果需要修改Struts框架的初始化行為,可以創(chuàng)建一個(gè)org.apache.struts.action.ActionServlet類(lèi)的子類(lèi),然后覆蓋它的init()方法。
接下來(lái),應(yīng)該在web.xml文件中對(duì)自定義的ActionServlet進(jìn)行配置。
在Struts1.1中,預(yù)處理HTTP請(qǐng)求的具體操作由RequestProcessor類(lèi)來(lái)完成。因此,如果需要對(duì)預(yù)處理HTTP請(qǐng)求的方式進(jìn)行客戶化,可以擴(kuò)展RequestProcessor類(lèi)。
3.2 擴(kuò)展RequestProcessor類(lèi)
如果擴(kuò)展了RequestProcessor類(lèi),應(yīng)該在Struts配置文件中通過(guò)<controller>元素對(duì)自定義的RequestProcessor類(lèi)進(jìn)行配置。
<controller>元素的processorClass屬性用來(lái)指定使用的RequestProcessor類(lèi)。Struts框架在啟動(dòng)時(shí)會(huì)創(chuàng)建這個(gè)RequestProcessor類(lèi)的實(shí)例,并利用它來(lái)處理所有的HTTP請(qǐng)求。由于每個(gè)子應(yīng)用模塊都有各自的配置文件,因此可以為每個(gè)子應(yīng)用模塊配置不同的RequestProcessor類(lèi)。
RequestProcessor類(lèi)的一個(gè)擴(kuò)展點(diǎn)為processPreprocess()方法。在RequestProcessor基類(lèi)中,該方法不執(zhí)行任何操作,志軍誒返回true。
RequestProcessor類(lèi)在process()方法中處理請(qǐng)求,Process()方法在調(diào)用Action的execute()方法之前,就會(huì)調(diào)用processPreprocess()方法,如果processPreprocess()方法返回true,則表示繼續(xù)按正常的流程處理請(qǐng)求。
在自定義的RequestProcessor類(lèi)中,可以覆蓋processPreprocess()方法來(lái)執(zhí)行特定的邏輯。如果在某些條件下希望終止處理請(qǐng)求,只需讓processPreprocess()方法false即可。在這種情況下,仍需要以編程的方式來(lái)決定如何轉(zhuǎn)發(fā)或重定向請(qǐng)求。
Servlet 2.3 API提供了Servlet過(guò)濾器,它可以實(shí)現(xiàn)和processPreprocess()方法相同的功能。Servlet過(guò)濾器也可以用來(lái)執(zhí)行客戶化的預(yù)處理請(qǐng)求操作,Web容器先調(diào)用Servlet過(guò)濾器,再把請(qǐng)求轉(zhuǎn)發(fā)給Struts控制器。
與擴(kuò)展RequestProcessor類(lèi)相比,通過(guò)Servlet過(guò)濾器來(lái)預(yù)處理請(qǐng)求有兩大弱點(diǎn):
3.3 擴(kuò)展Action類(lèi)
Struts框架的Action類(lèi)是最頻繁的擴(kuò)展點(diǎn)。對(duì)于具體的Struts應(yīng)用,可以先為應(yīng)用創(chuàng)建一個(gè)擴(kuò)展Struts Action類(lèi)的Action基類(lèi),在這個(gè)Action基類(lèi)中定義應(yīng)用中所有Action的一些公共邏輯,它可以作為其他Action的父類(lèi)。這種處理方式可以提高代碼的可重用性,減少代碼的重復(fù)。
4.
擴(kuò)展視圖組件
一般說(shuō)來(lái),沒(méi)有必要擴(kuò)展視圖組件,因?yàn)椴煌膽?yīng)用有不同的外觀和界面,一個(gè)應(yīng)用的JSP頁(yè)面不大可能適用于另一個(gè)不同的應(yīng)用。不過(guò),可以擴(kuò)展Struts客戶化標(biāo)簽,因?yàn)闃?biāo)簽處理器為常規(guī)的Java類(lèi),可以通過(guò)定義子類(lèi)的方式來(lái)擴(kuò)展它們,這些擴(kuò)展后的客戶化標(biāo)簽?zāi)軌虮徊煌膽?yīng)用重用。
Struts HTML標(biāo)簽庫(kù)中的標(biāo)簽對(duì)視圖內(nèi)容的影響最大。因此可以擴(kuò)展這些標(biāo)簽來(lái)創(chuàng)建客戶化的應(yīng)用外觀。當(dāng)擴(kuò)展了標(biāo)簽后,應(yīng)該定義存放這些標(biāo)簽的標(biāo)簽庫(kù)。盡管可以把自定義的標(biāo)簽加入到標(biāo)準(zhǔn)的Struts標(biāo)簽庫(kù)中,但是這會(huì)使將應(yīng)用升級(jí)到新的Struts版本變得更加麻煩。所以建議定義單獨(dú)的標(biāo)簽庫(kù),來(lái)存放和特定應(yīng)用相關(guān)的客戶化標(biāo)簽。
一旦為客戶華標(biāo)簽庫(kù)創(chuàng)建了TLD文件,并且在web.xml中注冊(cè)了標(biāo)簽庫(kù),就可以在JSP文件中方便地使用這些標(biāo)簽了。
5.
擴(kuò)展模型組件
Struts框架本身沒(méi)有在模型層提供現(xiàn)成的模型組件,因此擴(kuò)展模型組件不屬于Struts技術(shù)。
6.
小結(jié)
本篇文檔歸納了Struts框架的所有可擴(kuò)展點(diǎn)。Struts框架的可擴(kuò)展性使開(kāi)發(fā)者可以方便地定制客戶化功能,提高應(yīng)用的靈活性和多各種需求的可適應(yīng)性。然而,實(shí)現(xiàn)更多的功能使要花費(fèi)更大代價(jià)的,應(yīng)該避免濫用Struts的可擴(kuò)展特性。Struts由核心包加上很多工具包構(gòu)成。它們已經(jīng)提供了很多現(xiàn)成的功能。因此不要盲目地?cái)U(kuò)展Struts框架,在決定編寫(xiě)擴(kuò)展代碼前,務(wù)必先確認(rèn)Struts沒(méi)有提供現(xiàn)成的您需要的功能。否則,重復(fù)的功能會(huì)導(dǎo)致應(yīng)用結(jié)構(gòu)的混亂,將來(lái)還得花費(fèi)額外的經(jīng)歷來(lái)清除重復(fù)功能。
此外,必需考慮擴(kuò)展后的框架是否會(huì)和將來(lái)的新的Struts版本兼容,從Struts 1.0到Struts 1.1就發(fā)生了很大的改動(dòng)。在先有的Struts版本的API中,如果有的類(lèi)的方法已經(jīng)聲明將要被廢棄,應(yīng)該盡量不要覆蓋這些方法,否則,當(dāng)采用新的Struts版本時(shí),就不得不對(duì)應(yīng)用做相應(yīng)的升級(jí)。
閱讀材料:《精通Struts:基于MVC的Java Web設(shè)計(jì)與開(kāi)發(fā)》
2005年05月19日 2:37 AM