基于模板的Web表示層技術(shù) (摘自《Spring開發(fā)指南》)
傳統(tǒng)的JSP技術(shù)為Web表現(xiàn)層技術(shù)提供了靈活、豐富的功能支持。然而,站在工程的角度
而言,過于凌亂的JSP Script也成為系統(tǒng)維護的頭號大敵。
JSP 代碼幾乎等同于Java 代碼,在提供了最豐富的特性支持的同時,也為系統(tǒng)的開發(fā)帶
來一些隱患,程序員往往天馬行空,不為羈束,在JSP 中將業(yè)務(wù)邏輯、數(shù)據(jù)邏輯、表現(xiàn)邏輯代
碼相混雜,代碼重用性、系統(tǒng)可維護性極低。特別是在參與開發(fā)人員眾多,技術(shù)水平良莠不齊
的情況下,縱使技術(shù)經(jīng)理一再強調(diào)設(shè)計規(guī)范的約束,但人本的約束總是難以控制,隨著開發(fā)過
程進展和產(chǎn)品上線壓力的增大,規(guī)范約束逐漸薄弱,于是難以避免的造成代碼的混亂,可維護
性的下降。
面對這個問題,眾多組織和廠商開始研發(fā)自己的表現(xiàn)層框架,試圖通過一個隔離的表現(xiàn)層
框架,強行將表現(xiàn)層和邏輯層相剝離。時間似乎退回到了最初Web 端只支持Servlet 技術(shù)的
時代(那時候或多或少各個公司都有自己的模板實現(xiàn))。不過,現(xiàn)在的模板技術(shù)經(jīng)過長時間的
發(fā)展,已經(jīng)將表現(xiàn)層的能力發(fā)揮得淋漓盡致,不失為JSP技術(shù)之外的一個明智選擇。
模板技術(shù)相對傳統(tǒng)JSP技術(shù)有以下三個主要優(yōu)勢:
1. 在技術(shù)層面,將表現(xiàn)邏輯與業(yè)務(wù)邏輯相分離。
2. 為人員之間的分工提供了一個良好的分界點。頁面美工只需專著關(guān)心模板的設(shè)計,而程序員則專注于業(yè)務(wù)邏輯的實現(xiàn)。二者重合點明顯減少。
3. 如果需要,模板引擎可脫離Web 容器單獨運行,這為系統(tǒng)可能的移植需求提供了更多的彈性空間(這一特性在應(yīng)用中也許并不會有太大的實際意義,只是提供了一種附加選擇)。
目前Spring支持一下幾種模板技術(shù):
1. XSLT
XSLT是基于XML的表現(xiàn)層模板技術(shù),伴隨著XML的大量使用。XSLT也日漸成熟,并
迅速成為主流表現(xiàn)層技術(shù)之一。XSLT作為一個通用表現(xiàn)層框架,擁有最好的平臺適應(yīng)性,
幾乎所有的主流程序設(shè)計語言都提供了XLST支持,現(xiàn)有的XLST模板可以簡單的移植到不
同的語言平臺,如將J2EE應(yīng)用中的XSLT移植到.net平臺,這樣的可移植性是其他專用
模板技術(shù),如Velocity和Freemarker難以達到的。
筆者在2001年在一個原型項目中采用了XSLT作為表現(xiàn)層實現(xiàn),由于當(dāng)時XSLT尚不
成熟,XSLT解析器效率低下,因此在正式產(chǎn)品開發(fā)中使用其他技術(shù)作為替代。在2003年
中,經(jīng)過技術(shù)探討,決定再次在項目實施中引入XSLT 技術(shù),相對兩年前,此時的XSLT
技術(shù)已經(jīng)相當(dāng)成熟,解析器的效率也大大改善。經(jīng)過半年時間的項目研發(fā),產(chǎn)品上線,并
取得了令人滿意的表現(xiàn)。不過,在之后的項目回顧過程中,筆者認為,目前在項目中大量
采用XSLT技術(shù)尚不可取,上述項目開發(fā)過程中,XSLT技術(shù)提供了極佳的擴展性和重用性,
也保證了業(yè)務(wù)邏輯和表示邏輯的清晰劃分,然而,最大的問題是,XSLT缺乏強有力的編輯
器支持。雖然通過XML/XSLT 技術(shù)成全了設(shè)計上近乎完美的表現(xiàn),但卻為界面開發(fā)帶來了
極大難度,以至后期復(fù)雜界面的修改都需要消耗極大的人力,得不償失。
筆者在項目開發(fā)中所用的XSLT 編輯器為StylusStudio 和XmlSpy,目前這兩款編
輯器可以算是XSLT開發(fā)的首選,提供了豐富的特性和可視化編輯功能。但即便如此,XLST
繁雜苛刻的語法和調(diào)試上的難度也為開發(fā)工作帶來了極大的障礙。
此外,也許是最重要的一點,xslt在性能上的表現(xiàn)尚不盡如人意。經(jīng)過多年的發(fā)展,
XSLT解析/合成器的性能相對最初已經(jīng)大為改觀,但依然與其他模板技術(shù)存在著較大差距。
據(jù)實地測試,F(xiàn)reeMarker和Velocity對于同等復(fù)雜度的表現(xiàn)層邏輯,平均處理速度是
XSLT 的10 倍以上,這是一個不得不正視的性能溝壑。同時,XSLT 的內(nèi)存占用也是
FreeMarker 和Velocity 的數(shù)倍有余(XSLT 中,每個節(jié)點都是一個Java 對象,大量
對象的存儲對內(nèi)存占用極大,同時大量對象的頻繁創(chuàng)建和銷毀也對JVM 垃圾收集產(chǎn)生了較
大負面影響)。在上述項目中,由于硬件上的充分冗余(8G RAM, 4CPU),才使得這些
性能上的影響相對微弱。
因此,目前在項目中大量引入XSLT技術(shù)尚需仔細考量。
2. Velocity
Velocity是Apache Jakarta項目中的一個子項目,它提供了豐富強大的模板功能。
作為目前最為成熟的模板支持實現(xiàn),Velocity 在諸多項目中得到了廣泛應(yīng)用,不僅
限于Web 開發(fā),在眾多代碼生成系統(tǒng)中,我們也可以看到Velocity 的身影(如
Hibernate中的代碼生成工具)。
3. FreeMarker
FreeMarker是Velocity之外的另一個模板組件。
與Velocity 相比,F(xiàn)reeMarker 對表現(xiàn)邏輯和業(yè)務(wù)邏輯的劃分更為嚴格,
Freemarker在模板中不允許對Servlet API進行直接操作(而Velocity可以),
如FreeMarker 中禁止對HttpServletRequest 對象直接訪問(但可以訪問
HttpServletRequest對象中的Attribute)。通過更加嚴格的隔離機制,牽涉邏
輯處理的操作被強制轉(zhuǎn)移到邏輯層。從而完全保證了層次之間的清晰性。
另外一個Velocity無法實現(xiàn)的特性,也是最具備實際意義的特性:FreeMarker對
JSP Tag提供了良好支持。這一點可能存在一點爭議,JSP技術(shù)的最大問題就是容易
在頁面中混入邏輯代碼。而FreeMarker 對JSP Tag 的支持似乎為這個問題又打開
了大門。這一點上,我們可以將FreeMarker看作是僅允許使用TAG的JSP頁面(實
際上,F(xiàn)reeMarker的表達式語法與EL語法也非常類似)。
從開發(fā)角度而言,只允許使用TAG的JSP頁面,已經(jīng)在很大程度上保證了頁面表現(xiàn)邏
輯與業(yè)務(wù)邏輯的分離。程序員在JSP Script中混雜邏輯代碼的原因,大部分是出于
慵懶,只要無法在頁面模板中直接編寫Java代碼,相信程序員也不會去專門編寫一個
JSP TAG來刻意違反層次劃分原則。
對JSP TAG 的支持為FreeMarker 帶來了極大的活力,目前開源社區(qū)中已經(jīng)有了為
數(shù)眾多的成熟Taglib,如DisplayTag、Struts Menu等,這些功能豐富,成熟可
靠的Taglib,將為產(chǎn)品開發(fā)提供極大的便利。另一方面,這也為代碼重用提供了另一
個可選途徑,避免了大部分模板實現(xiàn)在這一點上的不足。
就筆者的經(jīng)驗,對于Web開發(fā)而言,F(xiàn)reeMarker在生產(chǎn)效率和學(xué)習(xí)成本上更具優(yōu)勢,
而Velocity 的相對優(yōu)勢在于更多第三方工具的支持和更廣泛的開發(fā)和用戶團體(然
而對于一個輕量級模板類庫而言,這樣的優(yōu)勢并不是十分明顯)。
如果沒有Velocity的技術(shù)儲備,而又需要通過技術(shù)上的限定解決視圖/模型的劃分問
題,這里推薦采用FreeMarker作為Spring MVC中的表現(xiàn)層實現(xiàn)。以獲得最好的(學(xué)
習(xí)、開發(fā))成本受益。