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