日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

集成JSP/JSF和XML/XSLT

 starsiday 2006-08-09
集成JSP/JSF和XML/XSLT
作者:Erik Bru… 文章來源:gceclub 點擊數(shù):193 更新時間:2006-6-4
【字體:

如果您有任何疑問,請到開發(fā)論壇上提問。

簡介

大家期待已久的JavaServer FacesTM(JSF)版本1.0和JavaServer PagesTM(JSP)版本2.0終于發(fā)布,它們承諾要改變J2EE開發(fā)人員構(gòu)建Web應(yīng)用程序的方式。與此同時,可擴展樣式表語言轉(zhuǎn)換(Extensible Stylesheet Language Transformation,XSLT)版本2.0已經(jīng)處于規(guī)范制定的最后階段,而許多開發(fā)人員正在認真地考慮基于XML的表示層,尤其是當(dāng)應(yīng)用程序以多種設(shè)備為目標,或者要求外觀定制時。

本文說明了一點,即JSF 1.0和JSP 2.0是邏輯演變的結(jié)果,而這種演變早在servlet編程的早期就開始了。借助諸如JSP 1.1、Struts 1.0和JSLT 1.0這些里程碑式的技術(shù),Java技術(shù)已經(jīng)逐漸集成了來自實際開發(fā)領(lǐng)域的多種成功技術(shù)。接著,本文介紹了Model 2X,它結(jié)合了JSP技術(shù)和XML處理,是上述演變的延續(xù),并且增強了表示層的靈活性。

為了更好地理解本文中討論的概念,您應(yīng)該具有JSP、XML和Web應(yīng)用程序架構(gòu)方面的基本知識。與JSF概念的某些相似性將會大有幫助。

注意:書寫本文過程中所使用的JSF規(guī)范的版本是JavaServer Faces 1.0 Specification Early Access Draft,版本日期為2002年9月6日。該規(guī)范將在未來不斷完善。所使用的JSF實現(xiàn)是Sun Reference implementation v1.0,Early Access 2(EA2)。

本文涉及到的所有源代碼都可以從下面的網(wǎng)址下載得到:
http://www./model2x/tss

對于Java開發(fā)人員來說,下面列舉的都是激動人心的時刻。在撰寫本文的時候(2003年2月):

  • JavaServer Pages 2.0和Java ServletTM 2.4規(guī)范計劃定稿。
  • 自從2002年6月以來,JavaServer Pages Standard Tag LibraryTM規(guī)范已經(jīng)定稿。
  • 獲得期望最高的JavaServer Faces 1.0正處于開發(fā)階段且進展順利。

即便您能夠做到與時俱進,規(guī)范和首字母縮寫詞的豐富程度還是令人望而卻步。好消息是,所有這些技術(shù)都彼此相關(guān),且設(shè)計為彼此互補。

  • Java Servlet是Java Web技術(shù)的基礎(chǔ)。Java Servlet規(guī)范解決了如何打包和部署應(yīng)用程序的問題,并描述了用于生成動態(tài)內(nèi)容的服務(wù)器端組件(即servlet)。
  • JavaServer Pages(JSP)構(gòu)建在servlet技術(shù)之上,為生成諸如HTML這樣的文本內(nèi)容提供了一種頁面模板方法。
  • JavaServer Pages Standard Tag Library(JSTL)是一個標準JSP動作(也稱為標簽)的集合,它簡化了JSP頁面的開發(fā)工作。頁面作者可以使用JSTL構(gòu)建高級頁面邏輯,而不用了解Java或其他腳本語言。
  • JavaServer Faces(JSF)提供了一個可擴展的、基于組件的、工具友好的服務(wù)器端UI框架,該框架可以與JSP及JSTL很好地集成。

下圖說明了各種技術(shù)之間的相關(guān)性:

圖1:技術(shù)堆棧

從前…

在開始實現(xiàn)JSP之前,服務(wù)器端的Java應(yīng)用程序通過在Java代碼中嵌入字符串來生成HTML。例1說明了從servlet生成簡單的HTML表的過程。

代碼如下:

MyTableData tableData = MyDAO.queryData();
            PrintWriter writer = response.getWriter();
            writer.println("<table border=\"1\">");
            for (int i = 0; i < tableData.getData().length; i++) {
            writer.println("<tr>");
            writer.println("<td>");
            writer.println(tableData.getData()[i]);
            writer.println("</td>");
            writer.println("</tr>");
            }
            writer.println("</table>");
            

生成的結(jié)果如下所示:

Item 0
Item 1
Item 2
Item 3

例1:一個從Servlet生成的HTML表

這個模型存在以下問題:

  • 在Java代碼中包含HTML字符串,不僅工作繁重,而且難于閱讀。
  • 每次靜態(tài)字符串改變時,需要重新編譯、打包和部署Java代碼。

許多頁面包含大量的靜態(tài)的、非生成的文本(需要是可編輯的),以及相對較少的動態(tài)生成的內(nèi)容。為此,在現(xiàn)實世界中,針對這個問題的解決方案大都基于頁面模板的機制。模板系統(tǒng)使得固定文本和動態(tài)動作的交叉變得更加自然。在Java世界中,當(dāng)前使用的最受歡迎的模板是JSP。

JSP的早期

借助JSP,HTML和Java代碼可以同時出現(xiàn)在一個JSP文件中。JSP文件也稱為JSP頁面。JSP引擎動態(tài)裝載并編譯JSP頁面。這使得開發(fā)流程變得更加簡易。另外,不要求Java代碼生成靜態(tài)的模板文本。只有動態(tài)的動作才要求使用Java。

例1可以被重寫為下面的JSP 1.1代碼片斷:

<%
            MyTableData tableData = MyDAO.queryData();
            %>
            <table border="1">
            <%
            for (int i = 0; i < tableData.getData().length; i++) {
            %>
            <tr>
            <td>
            <%= tableData.getData()[i] %>
            </td>
            </tr>
            <% }%>
            </table>
            

例2:使用JSP顯示一個表

HTML代碼被書寫為模板文本。Java代碼被封裝在稱為scirptlet的結(jié)構(gòu)體中。語言的混合晦澀難懂,大部分非Java開發(fā)人員對此都力不能及。這使得在開發(fā)過程中劃分任務(wù)和角色變得困難。

在例2中,業(yè)務(wù)邏輯是直接從JSP頁面被調(diào)用的。通常,開發(fā)人員在JSP頁面中實現(xiàn)一些或甚至全部的業(yè)務(wù)邏輯。這并沒有指定頁面與業(yè)務(wù)邏輯的交互,因此強制程度降低了很多。對于大型的項目來說,除非開發(fā)人員的技術(shù)素養(yǎng)非同一般,否則這種行為將導(dǎo)致代碼變得非模塊化,而且難于維護。

例2說明了以下問題必須得到解決:

  • JSP頁面本身的易讀性。
  • 缺乏分離業(yè)務(wù)邏輯和表示邏輯的模型。

JSP 1.1規(guī)范于1999年11月定稿。自從JSP 1.1以來,JSP最佳實踐已經(jīng)取得了顯著的進展,雖然它們當(dāng)時實際上還不存在,但是這種樣式的JSP頁面仍然普及開來。要解決JSP 1.1的問題,必須在JSP技術(shù)上構(gòu)建框架。

Struts和MVC

Struts是實現(xiàn)了解決這些問題的架構(gòu)而且基于JSP的第一批框架之一:

  • 提供有助于執(zhí)行條件、迭代和數(shù)據(jù)選擇的標簽庫,增強JSP的易讀性。bean 和logic標簽庫用于完成上述任務(wù)。
  • 使用MVC(模型/視圖/控制器)架構(gòu)。借助MVC,業(yè)務(wù)邏輯和表示邏輯得以分離開來。

在Struts中,MVC架構(gòu)是以頁面為基礎(chǔ)工作的。它是通過叫做Model 2的混合架構(gòu)來實現(xiàn)的,涉及到servlet與JSP文件的協(xié)作。

下圖說明了在Struts中,MVC的不同部分(模型、視圖和控制器)之間的關(guān)系。Struts提供了控制器servlet。模型是在一個實現(xiàn)或調(diào)用業(yè)務(wù)邏輯的動作類中實現(xiàn)的,而視圖是在一個JSP頁面中實現(xiàn)的。您仍然能夠在JSP頁面中實現(xiàn)業(yè)務(wù)邏輯,但實際上不鼓勵這種做法。

圖2:Struts、MVC和Model 2

MVC架構(gòu)相當(dāng)重要,因為它將使代碼自然而然地模塊化,不論是開發(fā)小組還是單個開發(fā)人員,都可以從中獲益匪淺。當(dāng)幾個開發(fā)人員一起工作時,較容易劃分角色:一個開發(fā)人員專門處理業(yè)務(wù)邏輯,同時其他人負責(zé)構(gòu)建實際的Web頁面。想要了解有關(guān)MVC的更多信息,請參見本文結(jié)尾的參考資料。

例3顯示了使用Struts重寫例2中JSP代碼片斷的結(jié)果:

<table border="1">
            <logic:iterate id="data" name="tableData" property="data">
            <tr>
            <td>
            <bean:write name="data"/>
            </td>
            </tr>
            </logic:iterate>
            </table>
            

例3:使用 Struts顯示一個表

現(xiàn)在,調(diào)用業(yè)務(wù)邏輯的代碼實現(xiàn)在一個單獨的動作類(沒有給出)中,這個動作類傳遞一個名為tableData的JavaBean給JSP頁面。例4顯示了上述bean的樣子:

public class TableData {
            private String[] data;
            public String[] getData() {
            return data;
            }
            ...
            }
            

例4:簡單的 JavaBean

logic:iterate標簽的name和property屬性指定了bean的data屬性元素上的一次迭代。property屬性還支持嵌套的和索引的引用,它們構(gòu)成了JSP 2.0中使用的表達式語言(Expression Language,EL)和JSTL的實際先驅(qū)。例3說明,通過實現(xiàn)MVC并提供足夠的標簽庫,您可以在JSP文件中完全不使用Java代碼。

步入JSTL和JSP 2.0

Struts標簽庫和表達式語言存在限制??紤]下面例子中的代碼,它的功能是使用另外一列和交替的行顏色構(gòu)造一個HTML表:

代碼如下:

<%
            MyTableData tableData = MyDAO.queryData();
            %>
            <table border="1">
            <%
            for (int i = 0; i < tableData.size(); i++) {
            String cellColor = (i % 2 == 0) ? "gray" : "white";
            %>
            <tr>
            <td bgcolor="<%= cellColor %>">
            <%= i %>
            </td>
            <td bgcolor="<%= cellColor %>">
            <%= tableData.get(i) %>
            </td>
            </tr>
            <% }%>
            </table>
            

生成了如下所示的結(jié)果:

0 Item 0
1 Item 1
2 Item 2
3 Item 3

例5:使用Scriptlet的復(fù)雜例子

在例5中,不能使用Struts標簽替換所有的scriptlet,因為迭代包括一個數(shù)據(jù)元素、一個位置索引和一次Struts標簽庫不能處理的計算。

針對這些限制的解決方案是引入JSTL和JSP 2.0。JSLT實質(zhì)上是Struts標簽庫的一個經(jīng)過深思熟慮的更好的版本。標簽的集合更加一致而完備。JSTL引入了表達式語言(EL),這種語言松散地基于JavaScript和XPath。JSP 2.0天生就支持這種EL。

除了對EL的天生支持,JSP 2.0還具有以下新特性:

特 性 描 述
表達式語言API 標簽庫實現(xiàn)者能夠輕易地利用JSP 2.0的 EL實現(xiàn)。
實現(xiàn)定制JSP動作的新工具
  • 簡化的Java API使得在Java中書寫定制標簽更加容易。
  • 開發(fā)人員能夠在標簽文件中書寫定制的JSP動作,而不用書寫、編譯和打包Java應(yīng)用程序。
增強的可配置性 在單個頁面或在整個應(yīng)用程序中,顯式地禁止使用scriptlets 很容易做到。

另外還有一些與使用JSTL和EL相關(guān)的優(yōu)點:

優(yōu) 點 描 述
XML 和 HTML的一致性 JSTL/EL聯(lián)合起來可以產(chǎn)生酷似XML文檔的JSP頁面。結(jié)果不僅更易于閱讀,而且更易于被開發(fā)工具處理。例如,圖形工具能夠檢測或插入迭代器標簽,而如果使用Java書寫迭代,迭代器標簽便越發(fā)復(fù)雜得多。
Language constraints EL將自身的作用范圍限制在表達式上。標簽庫提供一個定義良好的動作集合。這很有益處,因為Java誘使Web頁面作者在頁面中書寫業(yè)務(wù)邏輯,從而打破了MVC模型。

例5可以使用JSTL標簽庫和JSP 2.0全部重寫,如例6所示:

<table border="1">
            <c:forEach items="${tableData.data}" var="currentData" varStatus="status">
            <c:set var="cellColor">
            <c:choose>
            <c:when test="${status.index % 2 == 0}">gray</c:when>
            <c:otherwise>white</c:otherwise>
            </c:choose>
            </c:set>
            <tr>
            <td bgcolor="${cellColor}">
            ${status.index}
            </td>
            <td bgcolor="${cellColor}">
            ${currentData}
            </td>
            </tr>
            </c:forEach>
            </table>
            

例6:使用 JSTL和 JSP 2.0書寫的例子

最新的規(guī)范明確支持書寫腳本更少的頁面,這標志著JSP開發(fā)的一個轉(zhuǎn)折點。從純化論者認為的HTML"tag soup"與Java scriptlet的無形混合,到幾乎純粹的命名空間感知的XML文件,JSP頁面在最佳實踐方面發(fā)生了重大變化。結(jié)果是語法更加一致,頁面作者的工作負擔(dān)減輕,與工具的集成更加容易,以及可以更好地控制業(yè)務(wù)邏輯與表示邏輯的分離。

JSP的前景

對于與用戶的交互有限而且簡單的動態(tài)Web頁面來說,JSP 2.0、JSTL和MVC就能提供您所需要的全部功能。但是如果要開發(fā)復(fù)雜的、基于Web的用戶界面,您不得不做大量的工作,以便提取請求參數(shù)、驗證并處理它們、將它們呈現(xiàn)回為HTML控件,等等。整個過程冗長乏味,而且極易出現(xiàn)錯誤。

長期以來,桌面應(yīng)用程序已經(jīng)使用了基于組件的層次MVC框架,比如降低構(gòu)建用戶界面的難度的Swing。此類框架將用戶界面的各個元素公開為以Container/Containee關(guān)系組織的組件。這種方法為自身提供了使用圖形工具構(gòu)建用戶界面的能力。它還允許組件重用,以及在開發(fā)過程中進行更好的角色分離。

圖3:包含控件的窗體

通常,Web應(yīng)用程序具有簡化的控件集合和有限的交互性,但在其他方面與桌面應(yīng)用程序區(qū)別不大。我們很自然地想到,要試著將在桌面上使用的模型應(yīng)用程序到服務(wù)器端的世界中去。這也是JSF專家組選出的解決方案。服務(wù)器端的應(yīng)用程序與桌面應(yīng)用程序相去甚遠,所以JSF需要一個新的處理模型及API,從而代替Swing中模型和API的使用。

像Struts一樣,JSF符合MVC架構(gòu)。它提供一個控制器servlet,并且允許使用呈現(xiàn)程序的視圖和使用組件類及基于事件的機制的模型分離開來。借助JSF,MVC可以工作在單獨組件的層次上。

開發(fā)人員能夠在JSP文件中使用XML標記來描述組件之間的相互關(guān)系,而不用書寫Java代碼來組裝JSF組件,而后者正是Swing的做法。聯(lián)合使用JSF與JSP是可選的,但這是眾望所歸的首選技術(shù)。例如,JSF附帶有一組標準的用戶界面組件,可以在JSP中通過Standard JSF Tag Library來使用它們。這允許不擅長Java的web頁面作者也能從事開發(fā)復(fù)雜用戶界面的任務(wù)。它還使得實現(xiàn)圖形工具更加容易。本文稍后將討論這樣的一個例子。

當(dāng)與JSP一起使用時,因為同時使用了控制器servlet和JSP頁面,JSF可以被看作是一個Model 2架構(gòu)。

JSF的承諾包括重用、角色分離和易于使用的工具,從而降低了實現(xiàn)服務(wù)器端用戶界面的門檻,并縮短了其所需的時間。

本文的余下部分專門講述JSF特殊的呈現(xiàn)方面。想要了解JSF架構(gòu)的更多信息,包括它的API和處理模型,請參見本文結(jié)尾部分的參考資料。

JSF呈現(xiàn)

用戶界面的呈現(xiàn)在于生成信息以使其對用戶可見。在服務(wù)器端編程領(lǐng)域中,信息通常包括HTML、CSS和JavaScript。呈現(xiàn)涉及到發(fā)送字符流給Web瀏覽器。

呈現(xiàn)JSF層次是一個遞歸過程,在此過程中,每個使用Java書寫的組件都有機會呈現(xiàn)自身。JSF提供了兩個選擇:

  • 直接從組件呈現(xiàn)。這種做法不能修改組件本身的代碼,所以也就不能修改呈現(xiàn)的樣式。
  • 委派給聚集在稱為RenderKit的實體中的單獨呈現(xiàn)程序類。組件的代碼不需要修改,但是改變樣式仍然需要修改RenderKit中的Java代碼。

這兩個選擇都不是基于模板的,而且就像在剛開始使用servlet的時候,它們還要求非標準的解決方案或者從Java代碼生成HTML。早期訪問版本的JSF附帶的呈現(xiàn)程序便是以這種方式實現(xiàn)的。無論何時呈現(xiàn)需要改變,組件開發(fā)人員都不得不卷入到其中。與JSP日益提倡的角色分離相比,這是一種嚴重的,而且?guī)缀跏遣荒芾斫獾牡雇恕?/p>

HTML有一種伴生語言,稱為CSS,特別為樣式而設(shè)計。假如在JSF的HTML RrnderKit for the Standard User Interface Component中,能夠使用CSS支持,那么CSS便能夠解除JSF呈現(xiàn)的限制。例如,可以使用支持CSS的瀏覽器中的style屬性來選擇按鈕的背景顏色:

<input type="button" value="Button 1" style="color: red"/>
            <input type="button" value="Button 2" style="color: blue"/>
            

例7:使用 CSS選擇樣式

通過允許保持組件的呈現(xiàn)代碼不變,即便是在另外的呈現(xiàn)方面改變時也是如此,CSS的使用部分地解決了樣式問題。這種方法具有以下限制:

  • 您不能控制使用CSS的樣式的每個方面。
  • 并非每個被部署的Web瀏覽器都支持所有的CSS規(guī)范。

為了說明第一點,考慮一下,您可能想要應(yīng)用程序中的每個表都交替顯示行的顏色,就像例5和6那樣。CSS不支持描述這種行為。

對于不支持最新版本CSS的Web瀏覽器來說,一個流行的不使用CSS的HTML技巧便是通過嵌入表來創(chuàng)建表邊界。

下面的代碼:

<table cellpadding="0" cellspacing="0" border="0" bgcolor="red">
            <tr>
            <td>
            <!-- Original table -->
            <table width="100%">
            <tr>
            <td bgcolor="white">1.1</td>
            <td bgcolor="white">1.2</td>
            </tr>
            <tr>
            <td bgcolor="white">2.1</td>
            <td bgcolor="white">2.2</td>
            </tr>
            </table>
            </td>
            </tr>
            </table>
            

生成的結(jié)果如下所示:

1.1 1.2
2.1 2.2

例8:嵌入表

要處理這種使用JSTL的情況,代碼不得不在應(yīng)用程序的每個JSP頁面中被重復(fù)。如果在開發(fā)過程中,開發(fā)人員不得不在不同的樣式之間來回切換好幾次,例如要處理變化的需求時,修改必須在整個應(yīng)用程序中重復(fù)進行。借助JSF,可以構(gòu)建一個定制的組件,但是這意味著,您必須書寫復(fù)雜的Java代碼。如果要實現(xiàn)這種類型的樣式技術(shù),兩種技術(shù)都幫不上什么忙。

至少有兩種解決方案是可用的:

  • 在類似于JSP 2.0標簽文件的模板文件中實現(xiàn)JSF呈現(xiàn)程序。不論是JSF還是JSP,都不支持這樣的模型,而且在JSF 1.0的最終版本發(fā)行之前,JSF呈現(xiàn)不可能有顯著的改變。
  • 使用XML處理。這種解決方案又稱為Model 2X,將在下一節(jié)中討論。

Model 2X

架構(gòu)

Model 2X最重要的方面是XML轉(zhuǎn)換語言的使用,比如XSL轉(zhuǎn)換(XSL Transformation,XSLT),連同servlet和JSP。下圖說明了Model 2X的基本架構(gòu):

圖4:Model 2X架構(gòu)

servlet或JSP的輸出通常被直接發(fā)送給Web瀏覽器。有了Model 2X之后,在到達Web瀏覽器之前,輸出先要經(jīng)由一個XML轉(zhuǎn)換的階段。為了理解這一點,考慮JSP和XML兩個世界之間的關(guān)系相當(dāng)重要。

JSP和XML

設(shè)計JSP的目的是為了能夠產(chǎn)生任意的文本格式,比如HTML、逗號分隔值(Comma-Separated Value,CSV)以及層疊樣式表(Cascading Style Sheet,CSS)。出于這個理由,您可以使用JSP生成XML文檔。要注意的地方是,JSP不能強制生成格式良好的XML輸出。為了生成格式良好的XML,您不得不采取以下預(yù)防措施:

  • JSP中直接呈現(xiàn)的任何模板文本標記必須是格式良好的。
  • 標簽庫必須生成格式良好的XML。

考慮下面這個例子,即包含有效HTML標簽的JSP代碼片斷:

<body>
            <hr>
            </body>
            

有一種方法可以確保模板文本是格式良好的XML,即書寫Sun所號稱的JSP文檔,而不是常規(guī)的JSP頁面。JSP文檔不過就是JSP頁面的XML版本而已。JSP結(jié)構(gòu)體,比如<% %><%@ %>,不符合XML規(guī)范。在JSP文檔中,它們被相應(yīng)的XML標簽所代替,比如<jsp:directive.include><jsp:scriptlet>標簽。書寫JSP文檔并不是從JSP生成格式良好的XML的要求,但是因為JSP引擎要確保文檔符合XML規(guī)范,它在前面顯示了許多錯誤。

標簽庫經(jīng)常生成HTML。Struts的html標簽庫和標準JSF標簽庫便是如此。使用這種標簽庫時,必須修改它們,以便生成XML,而不是HTML。借助JSF可以輕松完成這項工作,具體方法是書寫一個XML呈現(xiàn)程序,并用它來代替現(xiàn)有的HTML呈現(xiàn)程序。本文稍后將詳細討論這個問題。

執(zhí)行JSP頁面的結(jié)果仍然會得到字符流,即便該頁面符合XML規(guī)范也是如此。不能確保輸出是有效的,或者甚至是格式良好的XML。如果工具需要將JSP輸出處理為XML,如Model 2X中所示,這時便需要一個解析的步驟。

XSLT

XML被JSP頁面生成之后,它就可以被其他工具消費。XSLT便是一個這樣的工具,一種被設(shè)計用來執(zhí)行XML文檔轉(zhuǎn)換的功能語言。

一個簡單的XSLT轉(zhuǎn)換可以通過下面這種方式來表示:

圖5:簡單的XSLT轉(zhuǎn)換

XSLT轉(zhuǎn)換的結(jié)果可能是XML、HTML或者其他任意的文本格式。

XSLT的1.0版本發(fā)布于1999年11月。從那之后,為了將它發(fā)展為XSLT 2.0規(guī)范,許多人付出了大量的勞動。XSLT 2.0基于XPath 2.0,是一種新版本的XML表達式語言,具有更好的一致性,而且包含1.0版本中所沒有的一些特性,比如分組和用戶定義的XPath函數(shù)。

一個XSLT程序被稱為一個樣式表。這個術(shù)語在XSLT 2.0規(guī)范草案中有著清晰的表述:

"術(shù)語樣式表反映了這樣一個事實,即XSLT的重要角色之一便是為XML源文檔添加樣式信息,具體方法是將它轉(zhuǎn)換為由XSL格式化對象(參見[XSL格式化對象])組成的文檔,或者轉(zhuǎn)換為另一種面向表示的格式,比如HTML、XHTML或SVG。"

因此,XSLT這種語言的設(shè)計目的相當(dāng)明確,就是為了解決上述的樣式問題。

JSF和Model 2X

現(xiàn)在,您已經(jīng)能夠理解在Model 2X中,XML和XSLT技術(shù)是如何與JSP和JSF進行交互的。下面的JSP代碼片斷使用了JSF,這段代碼來自當(dāng)前JSF引用實現(xiàn)中的"guessNumber"例子。它包含了HTML模板代碼和構(gòu)建簡單窗體的JSF標簽:

<%@ taglib uri="http://java./j2ee/html_basic/" prefix="faces"%>
            <html>
            <head><title>Hello</title></head>
            <body>
            <h1>Hello</h1>
            <faces:usefaces>
            <faces:form id="helloForm" formName="helloForm">
            <table>
            <tr>
            <td>
            <faces:textentry_input id="userNo"
            modelReference="UserNumberBean.userNumber"/>
            </td>
            <td>
            <faces:command_button id="submit" commandName="submit"/><p>
            </td>
            </tr>
            </table>
            <faces:validation_message componentId="userNo"/>
            </faces:form>
            </faces:usefaces>
            </body>
            </html>
            

例9:JSF 例子

執(zhí)行使用XML呈現(xiàn)程序的代碼片斷,可能會輸出以下格式良好的XML文檔:

<html>
            <head><title>Hello</title></head>
            <body>
            <h1>Hello</h1>
            <form method="post" action="/guessNumber/faces/greeting.jsp">
            <table>
            <tr>
            <td>
            <input type="text" name="/helloForm/userNo"/>
            </td>
            <td>
            <input type="submit" name="submit" value="submit"/>
            </td>
            </tr>
            </table>
            </form>
            </body>
            </html>
            

例10:JSF例子的輸出

當(dāng)JSP輸出被解析并被反饋到XSLT轉(zhuǎn)換器時,您可以輕松地應(yīng)用程序樣式。下圖說明了處理模型,同時也是Model 2X的一個特殊例子:

圖6:JSF和XSLT呈現(xiàn)模型

例如,要將應(yīng)用程序中的每個按鈕呈現(xiàn)為紅色,使用下面的XSLT模板即可達到目的:

<!-- Find all input elements with a "submit" type attribute -->
            <xsl:template match="input[@type = ‘submit‘]">
            <!-- Copy the element found -->
            <input>
            <!-- Copy all existing attributes -->
            <xsl:copy-of select="@*"/>
            <!-- Add a "style" attribute -->
            <xsl:attribute name="style">color: red</xsl:attribute>
            </input>
            </xsl:template>
            

例10:使用一個XSLT 模板添加樣式

XSLT模板并不限于在由JSF呈現(xiàn)程序生成的標記上使用。例如,它可以使用同樣的技術(shù)生成頁面布局。例11說明了如何插入一個表,該表包含一個標題行以及包含原始文檔主體的第二行:

<!-- Match the body element -->
            <xsl:template match="body">
            <!-- Copy the element found and set a background color -->
            <body bgcolor="white">
            <table border="0">
            <!-- Create a header row -->
            <tr>
            <td>Header</td>
            </tr>
            <tr>
            <td>
            <!-- Copy the actual body -->
            <xsl:apply-templates/>
            </td>
            </tr>
            </table>
            </body>
            </xsl:template>
            

例11:創(chuàng)建一個頁面布局

Model 2X的優(yōu)點包括:

優(yōu) 點 描 述
更好的模塊化和靈活性 樣式可以被集中化。書寫一個樣式表就可以處理一個應(yīng)用程序的所有外觀。外觀可以在整個應(yīng)用程序中被重用。運行時,同一應(yīng)用程序中的不同外觀可以按照需要進行切換。
快速轉(zhuǎn)向 無須對Java代碼做任何修改。JSF 呈現(xiàn)程序只要書寫一次,就可以被所有頁面使用。當(dāng)應(yīng)用程序正在運行時,XSLT樣式表可以被重新裝載,而且變化幾乎是瞬時的。
強大的表現(xiàn)功能 XSLT是一種特別適合于操作XML的語言,也因此適合操作XHTML。操作的可能性是無窮的。XPath是一種表達式語言,它比JSP 2.0的EL以及JSTL要更加先進。
標準的一致性 XSLT是一個W3C標準,被廣泛采用。這意味著多個廠商針對它開發(fā)出了大量可用的文檔和工具,包括幾種針對Java的優(yōu)秀的XSLT轉(zhuǎn)換工具。Java API for XML Processing (JAXP)支持XSLT轉(zhuǎn)換。Xalan是一款流行的XSLT轉(zhuǎn)換工具,它與J2SE 1.4捆綁在一起,而且所有一流的應(yīng)用程序服務(wù)器都支持XSLT。
管道技術(shù) XSLT 適合以管道的方式進行處理。下面將詳細討論XML管道。
Familiarity 在特定的條件和迭代器中,幾個JSTL結(jié)構(gòu)體看起來很像XSLT結(jié)構(gòu)體。這使得熟悉JSTL的人學(xué)習(xí)XSLT會更加輕松,反之亦然。

Model 2X的以下限制應(yīng)該引起注意:

限 制 描 述
輔助處理 Model 2X在表示邏輯的執(zhí)行過程中引入了輔助步驟。大多數(shù)時候,性能提升十分有限,而靈活的貿(mào)易性能才是主要的方面。
學(xué)習(xí)曲線 必須學(xué)習(xí)XSLT。對于大多數(shù)用途來說,學(xué)習(xí)XSLT是如此容易,以至于這根本就不成為問題。
要求 因為JSP并不強制輸出格式良好的XML,所以這個任務(wù)便落到了開發(fā)人員的肩上。

XML 管道

Model 2X的使用為JSP處理模型引入了一個新的維度,因為它涉及到幾個順序執(zhí)行的步驟:

  1. 處理整個JSP頁面。根據(jù)常規(guī)的JSP處理模型,模板文本和標簽庫產(chǎn)生輸出。
  2. 輸出被解析為XML。
  3. 執(zhí)行XML處理。

實際上構(gòu)建的是一個兩段式管道??梢詾槊總€階段分配定義良好的角色:

管道的概念使Web應(yīng)用程序的表示層變得模塊化。不用修改JSP頁面,管道就可以被擴展為包含具有不同角色的另外階段,例如:

角 色 描 述
本地化 在單獨的管道階段中執(zhí)行本地化允許本地化JSP標簽庫的輸出,以及修改頁面布局的高級本地化。阿拉伯語的Web頁面可能在右側(cè)呈現(xiàn)其導(dǎo)航欄,而不是左側(cè)。
多種瀏覽器支持 對于支持諸如最新版本的CSS這樣的高級呈現(xiàn)功能的Web瀏覽器來說,一個樣式表可以為其生成輸出,而另一個樣式表可以為老式瀏覽器生成輸出。
多種設(shè)備支持 一個單獨的管道能夠以完全不同的設(shè)備作為目標,比如PDA或手機。
包含 在一個管道階段中,可以從其他JSP頁面構(gòu)建出一個頁面,包括頭、腳和主頁主體。

管道的一個完整例子如圖7所示:

圖7:管道的例子

實現(xiàn)Model 2X

使用JSF實現(xiàn)Model 2X要求:

  1. 為JSF Standard User Interface Component創(chuàng)建一個XML RenderKit。
  2. 連接一個XML解析器,以及一個XSLT轉(zhuǎn)換器(簡單實現(xiàn))或XML管道(高級實現(xiàn))。

下面的代碼說明了對第一步的需要。JSF faces:textentry_input標簽不能生成格式良好的XML輸出:

<INPUT TYPE="text" NAME="name" VALUE="value">
            

生成XML的JSF RenderKit必須生成格式良好的XML元素和屬性。另外,它應(yīng)該遵照以小寫形式創(chuàng)建元素的XHTML慣例:

<input type="text" name="name" value="value"/>
            

JSF的當(dāng)前引用實現(xiàn)沒有附帶一個XML RenderKit,但是對于熟悉JSF的開發(fā)人員來說,書寫這樣一個呈現(xiàn)程序不是什么難事。本文中包含了一個簡單的RenderKit。

使用以下方法可以完成與XML解析器和XSLT轉(zhuǎn)換器的連接:

  • Servlet過濾器。除了生成格式良好的XML之外,JSP頁面不需要別的任何特殊關(guān)照。標簽庫。一個封裝了整個頁面的標簽必須被插入到每一個JSP頁面中。您可以使用JSP 2.0的抬頭與結(jié)尾機制來避免代碼重復(fù)。
  • 您可以基于DOM或SAX來構(gòu)建XML管道邏輯。您可以創(chuàng)建定制的代碼,或者使用現(xiàn)有的解決方案,比如OXF或Cocoon。

想要了解更多細節(jié),請參見本文中使用的示例源代碼。

結(jié)束語

這些年來,JSP技術(shù)已經(jīng)趨于成熟。最佳實踐已經(jīng)表現(xiàn)為在真實應(yīng)用程序中使用JSP的結(jié)果,這導(dǎo)致JSP技術(shù)的核心得到了很大的增強,并使諸如JSTL這樣的新規(guī)范得到發(fā)展。JSF引入了一個期待已久的用戶界面組件模型,但是JSF也表現(xiàn)出其在呈現(xiàn)架構(gòu)中受到限制的地方。眾多開發(fā)人員可能認為這些限制是一個概念上的倒退。

Java開發(fā)人員相當(dāng)熟悉XML技術(shù),但他們沒有必要了解XML是如何被用于增強Web應(yīng)用程序的表示層的。Model 2X是一個簡單的架構(gòu),它構(gòu)建在JSP、JSF和XML技術(shù)的基礎(chǔ)之上,減少了JSF呈現(xiàn)模型的限制,并為J2EE應(yīng)用程序提供了一個靈活的表示層。

盡管JSP有逐漸與XML同化的趨勢,JSP 2.0還是沒有與XML標準完全集成。將來,通過將Model 2X添加到JSP引擎的核心中,JSP應(yīng)該完成這種演變。

參考資料

JavaServer Pages (JSP)
http://java./products/jsp/

Servlet 技術(shù)
http://java./products/servlet/

JSTL 規(guī)范
http:///aboutJava/communityprocess/final/jsr052/

JavaServer Faces (JSF)
http://java./j2ee/javaserverfaces/

Struts和XSLT方面的JavaWorld文章
http://www./javaworld/jw-02-2002/jw-0201-strutsxslt.html

初識 JavaServer Faces(第1部分)
http://www./javaworld/jw-11-2002/jw-1129-jsf.html

XSLT 1.0和XSLT 2.0 (草案)
http://www./TR/xslt, http://www./TR/xslt20/

OXF
http://www./oxf/

Model 2X
http://www./model2x

使用XML管道構(gòu)建Pet Store
http://www./content/orbeon/pet_store.jsp

XML管道簡介
http://www./oxf/whitepaper

Struts
http://jakarta./struts/

The Model-View-Controller (‘MVC‘) 設(shè)計模式
http://jakarta./struts/userGuide/introduction.html#mvc

Apache Xalan for Java
http://xml./xalan-j/index.html

Saxon - The XSLT 處理器
http://saxon./

Cocoon
http://xml./cocoon/

關(guān)于作者

Erik Bruchez專門研究Web應(yīng)用程序架構(gòu)。他是OXF的聯(lián)合架構(gòu)師。OXF是由Orbeon, Inc開發(fā)的一個基于XML的應(yīng)用程序框架。Orbeon, Inc是一家J2EE和XML咨詢公司,創(chuàng)立于1999年,Erik正是這家公司的聯(lián)合創(chuàng)始人之一。Erik曾領(lǐng)導(dǎo)過幾個軟件平臺和應(yīng)用程序的設(shè)計與實現(xiàn),其中包括視頻機頂盒(set-top box)和供應(yīng)鏈管理應(yīng)用程序方面的中間件。在Orbeon之前,Erik曾為Symantec Corp.工作,并為VisualCafe產(chǎn)品線做出了貢獻。Erik從位于瑞士洛桑的瑞士技術(shù)學(xué)院(EPFL)獲得了計算機科學(xué)碩士學(xué)位。

Omar Tazi曾在位于Silicon Valley心臟地帶的幾家高科技公司中擔(dān)任過高級管理職位,包括Symantec、Oracle和WebGain。Omar是Java Community Process Executive Committee的成員,還是眾多JSRs(Java Specification Requests)的活躍成員,并且成為了其中Expert Group的成員。他還經(jīng)常在BEA eWorld和JavaOne這樣的軟件年會上發(fā)言。他的主要興趣在于Java 2 Platform Enterprise Edition(J2EE)、XML和Web service等方面。在橫跨大西洋之前,Omar曾在位于洛桑的瑞士聯(lián)邦技術(shù)學(xué)院中擔(dān)任幾個研究和教學(xué)職位,專攻人工智能算法和面向?qū)ο蟮木幊?。他擁有計算機科學(xué)和電子工程的碩士學(xué)位。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多