河南人民廣播電臺 映像網(wǎng) 黃星辰
1.利用Servlet階段,使用request和response對象接收和反饋客戶端的請求。它是開發(fā)Web應(yīng)用程序的基石,在Web應(yīng)用程序中,Servlet 是一個基本的Web 組件,開發(fā)Web 應(yīng)用的許多技術(shù),如JSP及一些Web層的框架都是建立在其基礎(chǔ)之上。Servlet的缺點是在Java 代碼中兼有業(yè)務(wù)和邏輯,不利于程序設(shè)計和界面開發(fā)。
2.JSP技術(shù)階段,JSP是在標(biāo)記語言中以<%@…%>的形式嵌入Java代碼,使得頁面會話可以調(diào)用后臺Bean來處理事件,但是仍然沒有將表示層和業(yè)務(wù)層分割開來,往往是互相嵌套,這就要求美工人員要懂技術(shù),技術(shù)人員要懂美工,不利于程序的維護(hù)。隨后JSP引入了標(biāo)簽庫,來分離業(yè)務(wù)邏輯,經(jīng)過SUN公司的標(biāo)準(zhǔn)化之后,就形成了JSTL(Java Standard TabLibrary)。JSTL 對于頁面顯示以及顯示邏輯的弱耦合已經(jīng)實現(xiàn),方便了Web 的開發(fā)。但隨著Web應(yīng)用程序規(guī)模的不斷擴大,如今現(xiàn)有的JSTL技術(shù)已越來越無法滿足開發(fā)者的需求,復(fù)雜的業(yè)務(wù)流程和頁面之間的交互都需要程序員自己編寫代碼實現(xiàn),加大了開發(fā)難度。
3.框架開發(fā)階段,所謂框架就是可重用的,半完成的應(yīng)用程序,可以用來產(chǎn)生專門的定制程序。為了適應(yīng)新的開發(fā)環(huán)境,一個中間件廠商開發(fā)出了像Struts、Spring、Hibernate以及后來出現(xiàn)的JSF 等框架。這些框架為Web 應(yīng)用程序開發(fā)提供了模板,開發(fā)人員只要配置好相應(yīng)的參數(shù)就可以完成對Web應(yīng)用程序的開發(fā)。更重要的是,這些框架在不長的時間內(nèi)相互融合,現(xiàn)在的Web應(yīng)用程序開發(fā)都用到了一種或多種框架。
基于JCP制定的Web應(yīng)用框架標(biāo)準(zhǔn)而開發(fā)的JSF框架技術(shù),采用了模型—視圖—控制器(MVC)的設(shè)計模式,憑借良好定義的請求處理生命周期和豐富的組件層次結(jié)構(gòu),大大提高了基于Java的Web用戶界面開發(fā)的簡易性。MVC框架模型如圖1所示。
圖1 M VC 框架模型
JSF技術(shù)提供了一個表現(xiàn)和行為徹底隔離的能力,使得先前只有在客戶端UI 體系(DOM)下完成的細(xì)粒度隔離移到了服務(wù)器端,客戶端只需解釋標(biāo)準(zhǔn)的HTML語法,從而達(dá)到了完全瘦客戶端的目標(biāo)。JSF另一個主要特點在于,JSF利用熟悉的UI組件和Web 級概念,并不把開發(fā)者局限在某種特定的腳本技術(shù)或標(biāo)記語言。JSF提供了一個JSP標(biāo)簽庫,實現(xiàn)與JSP的綁定,但開發(fā)者完全可以用另外的表現(xiàn)技術(shù),因為它直接依賴于JavaServletAPI。以用戶界面組件為主的JSF與以頁面為中心的Struts框架不盡相同,它對應(yīng)用程序的各個部分劃分得比較清晰。利用JSF實現(xiàn)的MVC結(jié)構(gòu)如圖2所示。
圖2 利用JSF 實現(xiàn)的M VC 結(jié)構(gòu)
由圖1,圖2可知,JSF的控制器部分,由FacesServlet、動作處理方法、動作監(jiān)聽器方法和Faces 配置文件組成。JSF 的視圖部分基于用戶界面組件,組件構(gòu)成組件樹,用戶界面組件具有快速應(yīng)用程序開發(fā)工具的特征,優(yōu)于Struts。此外,JSF具有事件粒度細(xì)化的新特性,每個用戶界面組件可以觸發(fā)事件,不像Struts 只有在提交頁面時才能觸發(fā)一個事件,JSF中事件的粒度細(xì)化為組件級別,而不是表單級別。JSF的核心部件如圖3所示。
圖3 JSF 核心部件
圖3中用戶界面組成組件樹,構(gòu)成JSF視圖。用戶在與視圖上的組件相互交映時觸發(fā)了事件,事件通過事件監(jiān)聽器處理,在處理事件的過程中訪問應(yīng)用程序的模型對象,最后,導(dǎo)航系統(tǒng)根據(jù)這個邏輯結(jié)果來選擇下一個應(yīng)該呈現(xiàn)的視圖,呈現(xiàn)視圖的任務(wù)可以由組件自身直接完成,也可委派給專門的呈現(xiàn)器來完成。但有時碰到的特殊情況,僅用上面的步驟是無法完成的。如在要求輸入字符串的文本框中輸入數(shù)字或日期,或者輸入的是字符串,卻是無效數(shù)據(jù)等,于是在JSF中引入了轉(zhuǎn)換和驗證機制,來協(xié)助用戶組件更好的完成任務(wù)。在數(shù)據(jù)類型轉(zhuǎn)換、驗證及處理事件的過程中一旦發(fā)生錯誤,便產(chǎn)生相應(yīng)的消息,并顯示給用戶,提示用戶下一步的策略。
JSF的事件監(jiān)聽器Listener是建立在JavaBean的事件處理機制上的,與JavaBean 的事件模型一樣,JSF 框架中有強類型的事件類和監(jiān)聽器接口,應(yīng)用程序可以通過類Listener 和Event 來處理UI組件生成的事件。當(dāng)用戶與用戶界面組件交互時會觸發(fā)某種類型的事件,事件監(jiān)聽器根據(jù)組件上的EL表達(dá)式的值來確定待處理的事件。
當(dāng)一個對象A 依賴于B,則對象B 對A 有控制權(quán),如若B 發(fā)生變化,對象A 也一定隨之發(fā)生變化。而控制反轉(zhuǎn)IOC 就是讓這種對象間的依賴關(guān)系發(fā)生轉(zhuǎn)移。它要求“程序不應(yīng)依賴實現(xiàn),而是依賴接口”。也有人把IOC 稱為依賴注入。為了達(dá)到控制反轉(zhuǎn)的目的,容器或者框架需要引入一個裝配者對象,在JSF中就是托管Bean的任務(wù)。對象依賴關(guān)系如圖4所示。
圖4 對象依賴關(guān)系
Backing Bean 不再依賴業(yè)務(wù)服務(wù)的具體實現(xiàn)對象,而是被托管Bean所依賴,此時托管Bean還依賴于具體的業(yè)務(wù)實現(xiàn)。將Backing Bean和具體的業(yè)務(wù)服務(wù)實現(xiàn)配置在faces文件中供托管Bean使用,無須對托管Bean代碼做更改,Backing Bean具體的業(yè)務(wù)服務(wù)的實現(xiàn)無須再改動其代碼了,而是更改相應(yīng)的配置文件,大大降低了程序的耦合度。依賴注入分為接口注入、設(shè)值注入和構(gòu)造子注入3種類型。實際應(yīng)用中,后兩種出現(xiàn)較多。
1.UI 組件。JSF 的UI 組件是真正意義上的UI 組件,能極大地簡化程序員的工作,如,在頁面上放置一個文本輸入框,這個輸入框立即具備了數(shù)據(jù)填充、界面更新、事件偵聽、動作觸發(fā)、有效性檢查和類型轉(zhuǎn)換的功能。更為重要的是,程序員只需根據(jù)業(yè)務(wù)邏輯編寫核心業(yè)務(wù)代碼,JSF會保證代碼在合適的時候被執(zhí)行,完全不用考慮代碼與代碼之間該如何來配合。
2.事件驅(qū)動模式。事件是面向?qū)ο蠓椒ǖ闹匾M成部分,對象之間通過事件進(jìn)行溝通和交流,使得一個或多個對象能夠?qū)α硪粋€對象的行為作出響應(yīng),共同合作去完成一項業(yè)務(wù)邏輯。通常,編寫Web 程序時,程序員要為對象之間的溝通設(shè)計機制,編寫代碼。雖然溝通的內(nèi)容屬于業(yè)務(wù)邏輯,但溝通的機制顯然與業(yè)務(wù)沒有太大關(guān)系,程序員因此為業(yè)務(wù)邏輯之外的功能浪費了時間。JSF改變了這種狀況。JSF的事件和偵聽模式與大家熟悉的Javabean 的事件模式類似,有Java 基礎(chǔ)的程序員并不需要學(xué)習(xí)任何新的東西。JSF的UI組件可以產(chǎn)生事件,如,當(dāng)頁面上一個文本輸入框的內(nèi)容被修改時,會發(fā)出一個“值改變事件”。另一個對象如果對“值改變事件”感興趣,只需注冊為該對象的偵聽者,并編寫處理例程,即可命令JSF在事件發(fā)生時自動調(diào)用處理例程。JSF做了所有該做的事,留給程序員的只有業(yè)務(wù)邏輯代碼的編寫。
3.用戶界面到業(yè)務(wù)邏輯的直接映射。如,表單提交是Web編程最常見的任務(wù),也是最復(fù)雜的任務(wù)之一。當(dāng)用戶在網(wǎng)頁上點擊“確定”按鈕時,瀏覽器將生成一個HTTP請求,發(fā)往服務(wù)器端的某個Servlet,執(zhí)行該Servlet 的service 方法。在service 方法中,HTTP請求需要經(jīng)歷解碼、類型轉(zhuǎn)換、有效性驗證、狀態(tài)保存、數(shù)據(jù)更新等環(huán)節(jié),處理這些環(huán)節(jié)的所有細(xì)節(jié),對程序員來說是沉重的負(fù)擔(dān)。在JSF下,這些工作的很大一部分都由框架承擔(dān)了,在程序員看來,這個過程是透明的,用戶界面端的HTTP請求可以直接映射到后端的一個事件處理例程,JSF起到了承前啟后的作用。
4.程序員和網(wǎng)頁設(shè)計人員的分工。在JSP中,程序員和網(wǎng)頁設(shè)計人員的工作有時是互相交織、無法區(qū)分的。這是因為JSP頁面中摻入了網(wǎng)頁設(shè)計人員所不熟悉的一些JSP標(biāo)簽,甚至是晦澀的Java代碼。要求網(wǎng)頁設(shè)計人員理解這些標(biāo)簽和代碼是不現(xiàn)實的,不符合分工合作的原則。在JSF中,框架為網(wǎng)頁設(shè)計人員提供了一套標(biāo)準(zhǔn)的UI組件,在工具的支持下,可以通過拖放簡單地添加到網(wǎng)頁上,然后設(shè)置某些顯示屬性來滿足視覺要求。網(wǎng)頁設(shè)計人員不需要知道UI組件背后的復(fù)雜代碼,而程序員也不需要再處理任何與視覺相關(guān)的細(xì)節(jié),程序員所做的只是給UI組件綁定類的屬性或方法。雖然程序員和網(wǎng)頁設(shè)計人員需要修改同一份文件,但他們各司其職,各得其所,互不干擾。程序員和網(wǎng)頁設(shè)計人員工作的明確劃分,是JSF在易用性方面邁出的一大步。
5.請求處理生命周期的多階段劃分。雖然都是建立在Servlet基礎(chǔ)之上,但JSF的生命周期要比JSP復(fù)雜得多。JSP的生命周期非常簡單,頁面被執(zhí)行時,HTML標(biāo)記立即被生成了,生命周期隨即結(jié)束。而一個完整的JSF請求—處理生命周期被精心規(guī)劃為6個階段,典型的JSF請求需要經(jīng)歷所有階段,某些特殊的請求也可以跳過一些階段。階段的細(xì)分,顯然引入了更多的處理,但JSF框架會管理這一切,所以,程序員在獲得更多控制能力的同時,工作量并沒有增加。
6.全面的用戶自定義支持。JSF為程序員提供了很多默認(rèn)的組件和類,通常情況下,JSF 的這些默認(rèn)組件和類足以滿足Web開發(fā)的需要。但是,考慮到在某些應(yīng)用場合,框架的默認(rèn)行為也許不符合業(yè)務(wù)的要求,JSF特別允許程序員編寫自己的組件和類,來滿足客戶的特殊需求。例如,程序員可以編寫自己的UI組件,甚至可以創(chuàng)建自己的EL解釋器,來支持非標(biāo)準(zhǔn)的EL表達(dá)語言。
JSF 技術(shù)是基于MVC 模式的開發(fā)框架,它提供了豐富的用戶組件UI,較完美地將JSP,Servlet,JavaBeans 結(jié)合起來,提高了開發(fā)效率。并且JSF實現(xiàn)了一個開放的架構(gòu),允許開發(fā)人員創(chuàng)建自己的組件,或者在現(xiàn)有的組件上繼承,開發(fā)功能更強大的組件,體現(xiàn)了JSF的靈活性和可延展性。相信隨著JSF技術(shù)的不斷完善,基于JSF 框架的Web 應(yīng)用將會越來越多,JSF 的運用范圍也會更加廣泛。