摘 要: JavaServer Faces的工作原理及運用JSF開發(fā)Web應(yīng)用程序的一個簡單實例。
關(guān)鍵詞: JSF技術(shù) MVC模式 JSP技術(shù) Web應(yīng)用程序
JSF(Java Server Faces)是SUN公司為了方便Web應(yīng)用程序的設(shè)計,使應(yīng)用程序邏輯設(shè)計和界面設(shè)計脫耦而提出的一種用戶界面程序框架(UI Framework)。它包括一組API和二個自定義標(biāo)記庫,用于UI組件的表示、組件狀態(tài)的管理、客戶端事件的處理、輸入的驗證以及頁面導(dǎo)航的管理等。與傳統(tǒng)的Servlet和JSP技術(shù)相比,JSF能使Web應(yīng)用程序在UI的開發(fā)上更具擴充性和維護性,它有助于Web應(yīng)用程序的開發(fā)人員角色分離。JSF1.0已經(jīng)被SUN公司納入到最新的J2EE1.4 SDK中。
1 JSF出現(xiàn)的背景和技術(shù)優(yōu)勢
使用Java開發(fā)Web應(yīng)用程序經(jīng)歷了幾個發(fā)展階段。一開始是使用Servlet,直接利用request和response對象接收和響應(yīng)客戶端的請求。Servlet的一個顯著缺點是需要在Java代碼中嵌入大量的標(biāo)記語言(如HTML),處理邏輯和顯示邏輯嚴(yán)重耦合,非常不利于程序的維護和界面的設(shè)計?;谶@種情況,SUN又發(fā)展了JSP技術(shù)。與Servlet正好相反,JSP是在標(biāo)記語言中嵌入Java代碼,但它仍沒有實現(xiàn)Web開發(fā)角色的分離,美工設(shè)計人員仍然要在一堆混雜腳本、標(biāo)記和Java程序的代碼中工作,不利于程序的維護。后來,JSP加入了Tab library機制,鼓勵開發(fā)人員使用自定義標(biāo)簽封裝業(yè)務(wù)邏輯,JSP頁面盡可能只出現(xiàn)各種標(biāo)簽。大量自定義JSP標(biāo)簽的出現(xiàn),并經(jīng)過SUN公司的標(biāo)準(zhǔn)化后,形成了JSTL(Java Standard Tab Library)。JSTL技術(shù)基本實現(xiàn)了頁面邏輯和顯示邏輯的脫耦,方便了Web的各種開發(fā)人員。隨著Web應(yīng)用程序規(guī)模的不斷擴大,MVC-Model2體系的概念越來越適用于Web應(yīng)用程序的開發(fā)。經(jīng)過大量實踐的檢驗,它已經(jīng)成為最適合開發(fā)Web應(yīng)用程序的模板。
遵循MVC-Model2架構(gòu)開發(fā)的應(yīng)用程序框架(Framework)已有不少,例如當(dāng)今比較流行的Struts、Tapestry、Turbine等。JSF的出現(xiàn)并不是要代替這些框架,相反,由于技術(shù)的著重點不同,JSF可以和這些Framework很好地協(xié)同工作。JSF基于JSTL技術(shù),著力于解決現(xiàn)有框架不能完成的難題,例如View和Model無法實現(xiàn)完全脫耦、客戶端種類繁多等。JSF是真正徹底的MVC(Model View Controller),圖1為JSF的MVC架構(gòu)。
JSF的技術(shù)重點在View部分,它實現(xiàn)了Web應(yīng)用程序設(shè)計角色的完全分離。JSF網(wǎng)頁設(shè)計者只需要專注于頁面的設(shè)計;應(yīng)用程序開發(fā)者主要關(guān)心Model部分的JavaBean的開發(fā),例如連接JNDI、進行數(shù)據(jù)持久化或調(diào)用EJB等;程序的流程控制則由faces-config.xml專門配置。
JSF還可以根據(jù)不同的客戶端標(biāo)記語言做相應(yīng)的調(diào)整,例如HTML、XUL、XMLForm、Xforms和WML等,使Web應(yīng)用程序能在最小的改動下適應(yīng)不同的客戶端類型,如圖2所示。
其中JSF Core Library負(fù)責(zé)基本程序的運行,包括程序運行生命期控制、事件處理等。RenderKit把服務(wù)器端的UI組件轉(zhuǎn)化成任何一種使用者界面標(biāo)準(zhǔn),支持眾多的標(biāo)記語言。
圖3為一個JSF網(wǎng)頁的生命周期。只有送給java.faces.webap.FacesServlet控制器的HTTP請求才進入這個生命周期。在階段1,系統(tǒng)根據(jù)JSF網(wǎng)頁的內(nèi)容建立一個組件樹,根據(jù)組件樹中每個組件的設(shè)定將對應(yīng)的轉(zhuǎn)換器(Converter)、驗證器(Validator)以及事件處理函數(shù)(Event Handler)與特定組件關(guān)聯(lián),在階段2中系統(tǒng)根據(jù)HTTP request的參數(shù)一一調(diào)用這些組件;然后分別在階段3、4和5中執(zhí)行參數(shù)驗證、模型更新和事件處理;最后系統(tǒng)調(diào)用組件相應(yīng)的方法將它們轉(zhuǎn)化成適當(dāng)?shù)臉?biāo)簽(HTML或者WML等)送到客戶端。
2 JSF應(yīng)用的一個簡單實例
本例展現(xiàn)了使用JSF框架設(shè)計Web應(yīng)用程序的步驟。程序功能是讓用戶在瀏覽器中輸入用戶名和密碼登錄,系統(tǒng)執(zhí)行驗證后返回登錄結(jié)果。關(guān)于基于JSF的詳細開發(fā),可以參考文獻[3]和文獻[4]。
2.1 視圖設(shè)計
視圖(View)部分包括login.jsp和response.jsp文件。前者是一個可以讓用戶輸入登錄名、密碼進行登錄的頁面,后者用于返回用戶的登錄結(jié)果。所有的JSP文件都要加入以下二行,以引入JSF的自定義標(biāo)記庫:
<%@ taglib uri=″http://java.sun.com/jsf/html″prefix=″h″%>
<%@ taglib uri=″http://java.sun.com/jsf/core″prefix=″f″%>
其中l(wèi)ogin.jsp文件的主要代碼如下:
<f:view>
<h:form id=″loginform″>
<h2>Please enter your username and password</h2>
username:
<h:inputText id=″input_username″value=″#{userBean.username}″required=″true″/></br><!--把輸入的信息放入模型(javabean)--!>
<h:message for=″input_username″/></br>
password:
<h:inputSecret id=″input_password″value=″#{userBean.password}″required=″true″>
<f:validateLength minimum=″6″/> <!--這是一個JSF內(nèi)置的驗證器,用于校驗輸入的合法性,這里不允許用戶輸入低于6位長度的密碼--!>
</h:inputSecret></br>
<h:message for=″input_password″/></br><!--在這里顯示校驗出錯信息--!>
<h:commandButton id=″submit″action=″go″value=″Submit″/><!--在faces-config.xml文件中定義go行為的處理--!>
</h:form>
</f:view>
注釋部分說明了View是如何與Model和Controller關(guān)聯(lián)的。
2.2 模型設(shè)計
JSF的模型主要用JavaBean來實現(xiàn),這里定義了一個ValUser.java作為JavaBean,用于存儲和處理頁面?zhèn)魉偷男畔ⅰ?br />
package myjsf;
public class ValUser{
public ValUser( ) { }
String username=null;
String password=null;
//此處省略bean屬性username和password的getter
//和setter方法
// ……
String resultMessage=null;
public String getResultMessage( )//返回登錄結(jié)果
{
if (isValid( ))
this.resultMessage=″valid user,welcome″;
else
this.resultMessage=″invalid user,please login again″;
return this.resultMessage;
}
public void setResultMessage(String resultMessage)
{ }
private boolean isValid( )//檢驗用戶名密碼是否合法
{
if (this.password.trim( ).equals(″123456″))
return true;
else
return false;
}
}
為了方便說明,這里簡單地定義用戶輸入123456就是合法登錄。實際應(yīng)用中,應(yīng)該使用JDBC或其他技術(shù)從數(shù)據(jù)持久層獲取該用戶的密碼進行驗證。這個JavaBean定義了三個屬性,其中username和password從login.jsp中獲取值,resultMessage用于向response.jsp頁面反饋登錄結(jié)果。
2.3 控制器設(shè)計和配置文件
JSF的控制器設(shè)計是在配置文件中完成的。首先需要配置Web應(yīng)用程序的web.xml文件,加入以下內(nèi)容:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet
</servlet-class>
<load-on-startup> 1 </load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/login/*</url-pattern>
</servlet-mapping>
以上內(nèi)容表示只有對相對路徑在login下的頁面請求才交給JSF控制器處理,其他請求則不經(jīng)過該控制器(圖3)。JSF本身的控制文件是faces-config.xml,其中的navigation-rule節(jié)點定義了頁面跳轉(zhuǎn)流程控制,managed-bean節(jié)點定義了JavaBean的信息等,這里不再詳述。
3 結(jié) 論
JSF框架較好地貫徹了MVC-Model2設(shè)計體系的思想,使頁面表示和商業(yè)邏輯脫耦,讓各類Web應(yīng)用程序開發(fā)角色實現(xiàn)真正的各司其職。同時,JSF支持不同的客戶端應(yīng)用,使Web應(yīng)用程序可以很容易地適應(yīng)不同的客戶端訪問協(xié)議。JSF比較適合開發(fā)大型的Web應(yīng)用程序。由于配置過程比較繁瑣,待支持JSF的集成開發(fā)工具或插件發(fā)展成熟時,開發(fā)基于JSF的Web應(yīng)用程序?qū)兊檬州p松和自然。
參考文獻
1 Sun Microsystems.JavaServer Faces Technology Overview. http://java.sun.com/j2ee/javaserverfaces/
2 Gamma E,Helm R,Johnson R et al.Design Patterns:Elements of Reusable Object-Oriented Software.Addison Wesley,1995
3 Sun Microsystems.JavaServer Faces in The J2EE 1.4 Tutorial.http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSFIntro. html
4 Bergsten H.JavaServer Faces.O′Reilly&Associates,2004