摘要:JavaServer Faces作為一種新興的Web表現(xiàn)層框架,正在受到越來越多的關(guān)注。本文描述了JSF的幾大優(yōu)勢(shì),以及這些優(yōu)勢(shì)所帶來的Web開發(fā)的重大變革,從而試圖說明JSF將會(huì)在眾多競(jìng)爭(zhēng)者中脫穎而出,成為Web表現(xiàn)層框架的主流。
1. 引子:我與JSF的第一次親密接觸
2004年3月,當(dāng)我著手開發(fā)我的第一個(gè)Web程序時(shí),我選擇了JSP。作為一個(gè)傳統(tǒng)的桌面程序員,而且是老程序員,向Web程序員的轉(zhuǎn)變是異常痛苦的。3個(gè)月的時(shí)間,程序總算完成了,但從此對(duì)JSP恨之入骨。凌亂的書寫格式,數(shù)據(jù)和界面的混雜,尤其是嵌入到頁面里的Scriptlet,讓我搞不清自己是編程序的還是寫網(wǎng)頁的。
因此,當(dāng)接到第二版的開發(fā)任務(wù)時(shí),我毫不猶豫地放棄了JSP,尋找一種替代技術(shù)。上網(wǎng)一搜,卻發(fā)現(xiàn)框架多如牛毛,評(píng)論文章各執(zhí)一詞,莫衷一是,讓我徹底迷失了。猶豫搖擺不定之際,sun的J2EE Tutorial文檔中關(guān)于JavaServer Faces技術(shù)的介紹吸引了我:UI、component、event、listener這些在桌面程序中熟悉的字眼,讓我在Web開發(fā)中找到了桌面程序員的一些感覺。
象開發(fā)桌面程序那樣開發(fā)web程序,這是我選擇JSF的初衷。基于這樣膚淺的認(rèn)識(shí),跌跌撞撞上路了,在工期和新技術(shù)的雙重壓力之下,超負(fù)荷的工作令人透不過氣來,但每每從JSF中發(fā)掘出令人驚喜的新特性,又給我?guī)順O大的滿足感。第二版終于完成時(shí),日歷恰好翻過一個(gè)整月。JSF帶來的效率提升是顯著的。
事實(shí)上,到現(xiàn)在為止,我對(duì)于JSF還只能說是初步了解,遠(yuǎn)未達(dá)到掌握,更談不上精通,但這并不妨礙我視JSF為Web開發(fā)的首選框架。尤其是對(duì)于新手,如果還沒有在Struts、Tiles、Spring、Tapestry等框架中走得太遠(yuǎn),那么,集中你有限的精力踏上JSF之路吧。
2. JSF優(yōu)勢(shì)之一:UI組件(UI-component)
UI組件(UI-component)一直是桌面程序的專利,web程序中,雖然HTML定義了基本的UI標(biāo)簽,但要使這些UI標(biāo)簽像UI組件那樣工作,還需要很多代碼片斷來處理數(shù)據(jù)及其表現(xiàn)形式,而且有效地組織這些代碼片斷使其協(xié)調(diào)一致也是一件繁瑣的工作。JSF的UI組件是真正意義上的UI組件,能極大地簡化程序員的工作,例如,在頁面上放置一個(gè)文本輸入框,這個(gè)輸入框立即具備了數(shù)據(jù)填充、界面更新、事件偵聽、動(dòng)作觸發(fā)、有效性檢查和類型轉(zhuǎn)換的功能。更為重要的是,程序員只需根據(jù)業(yè)務(wù)邏輯編寫核心業(yè)務(wù)代碼,JSF會(huì)保證代碼在合適的時(shí)候被執(zhí)行,完全不用考慮代碼與代碼之間該如何來配合。
3. JSF優(yōu)勢(shì)之二:事件驅(qū)動(dòng)模式
事件是面向?qū)ο蠓椒ǖ闹匾M成部分,對(duì)象之間通過事件進(jìn)行溝通和交流,使得一個(gè)或多個(gè)對(duì)象能夠?qū)α硪粋€(gè)對(duì)象的行為作出響應(yīng),共同合作去完成一項(xiàng)業(yè)務(wù)邏輯。通常,編寫Web程序時(shí),程序員要為對(duì)象之間的溝通設(shè)計(jì)機(jī)制,編寫代碼。雖然溝通的內(nèi)容屬于業(yè)務(wù)邏輯,但溝通的機(jī)制顯然與業(yè)務(wù)沒有太大關(guān)系,程序員因此為業(yè)務(wù)邏輯之外的功能浪費(fèi)了時(shí)間。JSF改變了這種狀況。JSF的事件和偵聽模式與大家熟悉的Javabean的事件模式類似,有Java基礎(chǔ)的程序員并不需要學(xué)習(xí)任何新的東西。JSF的UI組件可以產(chǎn)生事件,例如,當(dāng)頁面上一個(gè)文本輸入框的內(nèi)容被修改時(shí),會(huì)發(fā)出一個(gè)“值改變事件”。另一個(gè)對(duì)象如果對(duì)“值改變事件”感興趣,只需注冊(cè)為該對(duì)象的偵聽者,并編寫處理例程,即可命令JSF在事件發(fā)生時(shí)自動(dòng)調(diào)用處理例程。JSF做了所有該做的事,留給程序員的只有業(yè)務(wù)邏輯代碼的編寫。
4. JSF優(yōu)勢(shì)之三:用戶界面到業(yè)務(wù)邏輯的直接映射
舉個(gè)例子,表單提交是Web編程最常見的任務(wù),也是最復(fù)雜的任務(wù)之一。當(dāng)用戶在網(wǎng)頁上點(diǎn)擊“確定”按鈕時(shí),瀏覽器將生成一個(gè)HTTP請(qǐng)求,發(fā)往服務(wù)器端的某個(gè)Servlet,執(zhí)行該Servlet的service方法。在service方法中,HTTP請(qǐng)求需要經(jīng)歷解碼、類型轉(zhuǎn)換、有效性驗(yàn)證、狀態(tài)保存、數(shù)據(jù)更新等環(huán)節(jié),處理這些環(huán)節(jié)的所有細(xì)節(jié),對(duì)程序員來說是沉重的負(fù)擔(dān)。在JSF下,這些工作的很大一部分都由框架承擔(dān)了,在程序員看來,這個(gè)過程是透明的,用戶界面端的HTTP請(qǐng)求可以直接映射到后端的一個(gè)事件處理例程,JSF起到了承前啟后的作用。
5. JSF優(yōu)勢(shì)之四:程序員和網(wǎng)頁設(shè)計(jì)人員的分工 在JSP中,程序員和網(wǎng)頁設(shè)計(jì)人員的工作有時(shí)候是互相交織、無法區(qū)分的。這是因?yàn)镴SP頁面中摻入了網(wǎng)頁設(shè)計(jì)人員所不熟悉的一些JSP標(biāo)簽,甚至是晦澀的Java代碼。要求網(wǎng)頁設(shè)計(jì)人員理解這些標(biāo)簽和代碼是不現(xiàn)實(shí)的,不符合分工合作的原則。在JSF中,框架為網(wǎng)頁設(shè)計(jì)人員提供了一套標(biāo)準(zhǔn)的UI組件,在工具的支持下,可以通過拖放簡單地添加到網(wǎng)頁上,然后設(shè)置某些顯示屬性來滿足視覺要求。網(wǎng)頁設(shè)計(jì)人員不需要知道UI組件背后的復(fù)雜代碼,那是程序員的事,而程序員也不需要再處理任何與視覺相關(guān)的細(xì)節(jié),程序員所做的只是給UI組件綁定類的屬性或方法。雖然程序員和網(wǎng)頁設(shè)計(jì)人員需要修改同一份文件,但他們各司其職,各得其所,互不干擾。程序員和網(wǎng)頁設(shè)計(jì)人員工作的明確劃分,是JSF在易用性方面邁出的一大步。
6. JSF優(yōu)勢(shì)之五:請(qǐng)求處理生命周期的多階段劃分 雖然都是建立在Servlet基礎(chǔ)之上,但JSF的生命周期要比JSP復(fù)雜得多。JSP的生命周期非常簡單,頁面被執(zhí)行時(shí),HTML標(biāo)記立即被生成了,生命周期隨即結(jié)束。而一個(gè)完整的JSF請(qǐng)求-處理生命周期被精心規(guī)劃為6個(gè)階段,典型的JSF請(qǐng)求需要經(jīng)歷所有階段,某些特殊的請(qǐng)求也可以跳過一些階段。階段的細(xì)分,顯然引入了更多的處理,但JSF框架會(huì)管理這一切,所以,程序員在獲得更多控制能力的同時(shí),工作量并沒有增加。
7. JSF優(yōu)勢(shì)之六:伴隨工具而生存
JSF帶來了Web編程的巨大變革,變革的強(qiáng)烈程度超出了很多工具廠商的預(yù)料,以至于現(xiàn)在可供JSF使用的工具非常缺乏。缺乏工具支持的JSF只會(huì)令人敬而遠(yuǎn)之,因此,JSF在設(shè)計(jì)之初就為工具廠商預(yù)留了用武之地。在為數(shù)不多的JSF工具中,sun的Java Studio Creator是一個(gè)優(yōu)秀的開發(fā)環(huán)境;Borland的Jbuilder在JSF1.1時(shí)曾經(jīng)是非常好用的開發(fā)工具,可惜現(xiàn)在對(duì)JSF1.2的支持沒有跟上;Eclipse下JSF的插件很多,但真正支持所見即所得的JSF插件都是收費(fèi)的,例如Bea的Workshop for JSF、Exadel的JSF Studio等等;此外,Oracle和IBM也有JSF的開發(fā)工具。隨著工具的不斷涌現(xiàn),用JSF開發(fā)Web程序?qū)?huì)越來越方便和快速。
8. JSF優(yōu)勢(shì)之七:全面的用戶自定義支持
前面提到,JSF將極大地簡化Web程序的開發(fā),作為一個(gè)相對(duì)復(fù)雜的框架,JSF是如何做到這點(diǎn)的呢?原來JSF為程序員提供了很多默認(rèn)的組件和類,通常情況下,JSF的這些默認(rèn)組件和類足以滿足Web開發(fā)的需要了。但是,考慮到在某些應(yīng)用場(chǎng)合,框架的默認(rèn)行為也許不符合業(yè)務(wù)的要求,JSF特別允許程序員編寫自己的組件和類,來滿足客戶的特殊需求。例如,程序員可以編寫自己的UI組件,甚至可以創(chuàng)建自己的EL解釋器,來支持非標(biāo)準(zhǔn)的EL表達(dá)語言。
9. JSF優(yōu)勢(shì)之八:Web開發(fā)的官方標(biāo)準(zhǔn)之一
JSF的1.0版本發(fā)布于2004年2月份,當(dāng)時(shí)是作為一項(xiàng)獨(dú)立的Web技術(shù)推出的。經(jīng)過1.1版到現(xiàn)在最新的1.2版,短短的兩年多時(shí)間,JSF終于在2006年年中成為Java EE 5的組成部分,上升為Web開發(fā)的官方標(biāo)準(zhǔn)之一。Java EE 5最重要的使命就是簡化Java的開發(fā),而JSF無疑為這一使命立下了汗馬功勞。在Web框架層出不窮甚至有些泛濫成災(zāi)的今天,Sun以JSF來樹立標(biāo)準(zhǔn),對(duì)Java的發(fā)展是有益的。Sun在Java領(lǐng)域的領(lǐng)袖地位不容動(dòng)搖,對(duì)于Java程序員來說,始終追隨業(yè)界領(lǐng)袖的步伐,也許是避免技術(shù)落伍的最好方法。
10. 結(jié)束語:
該你了,JSF! 考察某項(xiàng)技術(shù)的流行程度,google的關(guān)鍵字搜索不失為一種簡便易行的方法。為了便于說明,我們選擇目前最熱門的Struts與JSF進(jìn)行比較。在google中分別輸入關(guān)鍵字“Struts”和“JSF”,看看google返回的網(wǎng)頁數(shù)量。令我們感興趣的不是網(wǎng)頁的絕對(duì)數(shù)量,而是JSF網(wǎng)頁數(shù)量與Struts網(wǎng)頁數(shù)量的比值。我們看到,對(duì)于英文網(wǎng)頁,這個(gè)比值是0.6,日文網(wǎng)頁是1.0,繁體中文網(wǎng)頁是0.8,而簡體中文網(wǎng)頁只有0.4。表1列出了具體的數(shù)據(jù)和比值。
英文網(wǎng)頁數(shù)量(萬) 日文網(wǎng)頁數(shù)量(萬) 繁體網(wǎng)頁數(shù)量(萬) 簡體網(wǎng)頁數(shù)量(萬)
JSF Struts JSF Struts JSF Struts JSF Struts
719 1170 145 140 10 13 59 138
JSF / Struts = 0.6 JSF / Struts = 1.0 JSF / Struts = 0.8 JSF / Struts = 0.4
雖然這樣的比較方法不夠嚴(yán)謹(jǐn),但0.4的比例從一個(gè)側(cè)面說明JSF在國內(nèi)還沒有流行起來,用“方興未艾”四個(gè)字來描述JSF的這種狀況,是再合適不過了。由于歷史的原因,國內(nèi)的軟件技術(shù)一直亦步亦趨地跟著國外跑,這不是我們希望的,但我們不得不承認(rèn),因此,從國外的情況來推論,我們有理由相信,JSF必將成為國內(nèi)程序員追捧的對(duì)象。正如某位哲人說的那樣,JSF是早晨八、九點(diǎn)鐘的太陽,希望寄托在JSF身上。
11. 后記:不同的聲音
客觀地說,JSF并非完美,業(yè)界對(duì)JSF的評(píng)價(jià)也褒貶不一。例如,由于JSF過于復(fù)雜,其學(xué)習(xí)曲線明顯長于其他框架如Struts等,這在一定程度上妨礙了JSF的推廣;此外,JSF的推出略顯倉促,1.0版在使用中發(fā)現(xiàn)很多bug,以至于sun匆忙發(fā)布的1.1版主要是為了修正這些bug;還有,在JSF1.2版之前,JSP和JSF的融合有嚴(yán)重的缺陷,這主要是由于二者不同的生命周期造成的,不過,1.2版在這方面作出了改進(jìn),現(xiàn)在,JSP和JSF可以在一個(gè)項(xiàng)目中相安無事了。
JSF的不足之處還有很多,比如UI組件不夠豐富、具體實(shí)現(xiàn)的可選擇余地過窄、使用JSF開發(fā)的實(shí)際項(xiàng)目不多、sun的參考實(shí)現(xiàn)還存在諸多bug、短期內(nèi)缺乏工具支持等等,尤其是在國內(nèi),JSF的中文文檔和書籍相當(dāng)缺乏。但是,不管怎樣,這些都是JSF成長道路上必須經(jīng)歷的磨難,我相信,Sun會(huì)努力的。