<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Vincent.Chan‘s Blog

    常用鏈接

    統計

    積分與排名

    網站

    最新評論

    抽取界面 (II):對基本框架的若干擴展

    級別: 初級

    Martin Gerlach, 軟件工程師, IBM Almaden 研究中心

    2001 年 3 月 01 日

    本 文是作者去年 12 月關于 Web應用前端的那篇文章的續篇。本文介紹對 XML 數據和 XSL樣式表基本框架的若干擴展,并將集中討論應用的后端問題,包括國家語言支持(NLS)、視圖結構強化和性能問題。上一篇文章介紹了利用 XML 和 XSLT構建 Web 應用的基本結構,本文介紹在使 Web應用在線運行之前所要做的準備工作。

    本文是系列文章“抽取界面”的第二篇。為了理解本文出現的概念,您不妨讀一下第一篇文章, 用 XML 和 XSL 構建有良好適應性的 Web 應用前端 ,該文討論了完成此應用所必須的步驟。研究此應用樣例的代碼也能幫助您理解本文的概念。與第一篇文章一樣,本文仍假定您已經熟悉基于 HTTP 協議和 HTTP 請求-響應機制的 Web 應用,同時也假定您曾經用 HTML、甚或 JavaScript 制作過網頁。您應懂得 Java 編程語言,知道如何將 Java servlet 用作 Web 應用的訪問點。

    已討論過的內容

    在第一篇文章中,我介紹了 WebCal,它是一個簡單的、基于 Web 的日歷應用程序,能夠為多個用戶維護日歷。通過這個應用程序,我演示了如何建立一個不僅能夠通過標準 Web 瀏覽器訪問、而且能通過可理解其他格式 ― 例如,WML 和用于語音接口的 VoiceXML ― 的瀏覽器訪問的復雜 Web 應用。那篇文章分三部分討論上述內容:

    • 對 XML 數據和 XSL 樣式表結構化的一種方法
    • 服務器端的 XSL 轉換 ― 用 XSLT 和 XPath 生成輸出結果
    • 用 XSLT 構建 HTML 表單




    回頁首


    本文的內容

    本文也將討論三個主題,但這三個主題并不像第一篇文章討論的三個步驟那樣互相緊密關聯,即它們相互之間不存在特定順序。但每個主題在使 Web 應用在線運行之前的準備工作中都占有重要一席。這三個主題是:

    • 國家語言支持 (NLS):如果面對許多國家的客戶,您將希望提供一個多語言用戶界面。您希望系統自動選擇用戶的首選語言并用該語言顯示與 NLS 相關的信息。
    • 強化應用結構: 通常,Web 應用由許多“視圖”組成。在 WebCal 應用樣例中,視圖或者顯示一個用戶引發的各種事件,或者顯示新事件的輸入表單。登錄頁和注冊頁也是視圖。視圖可以按不同的標準分組。在 WebCal 中,日視圖、周視圖和月視圖都可以看作是日歷視圖,它們共享同一個子導航 ― 用于輸入新事件的鏈接。將視圖按功能分組,開發人員就可以避免重復編碼,從而減輕應用開發工作量,減少錯誤率。
    • 提高性能: 您希望自己的 Web 應用能夠很快作出響應,用戶也不希望點擊一個鏈接后等很長時間。此時,您就會想到使用緩存機制,以更快、更可靠地為用戶提供服務。

    我們先從國家語言支持 (NLS) 著手。如果您對此已經很熟悉,則可轉到下一主題, 強化應用結構。





    回頁首


    國家語言支持 (NLS)

    為應用賦予多語言用戶界面的過程 ― 即加入國家語言支持的過程 ― 稱為“國際化”。國際化是 Java 程序的核心問題,因為 Java 通常被設計在任何地方、在任何平臺上、(尤為重要的是)以任何人的語言運行。Java 語言有一系列內建的國際化功能,在 developerWorks 上有這方面的文章。

    一般而言,關于 NLS 有兩方面的內容:

    • 識別客戶機的首選語言
    • 在應用中的任何地方訪問針對該語言提供的資源

    識別客戶機的首選語言
    就 WebCal 而言(其他 Web 應用也一樣),客戶機可從世界各地方訪問該系統。理想情況下,我們期望以客戶機的首選語言提供用戶界面。主要有兩種方法可用來完成這一任務。

    從 HTTP 請求的 Accept-Language 標頭中可獲得客戶機瀏覽器的語言代碼(例如, en-us 和 de)。該標頭列出了瀏覽器所支持的語言,如清單 1 所示。清單中的第一個值即被作為瀏覽器的(或者說是客戶機的)首選語言。


    清單 1: HTTP Accept-Language 標頭示例
    												
    														
    Accept-Language: en_us;en_ca;de;

    清單 2 中,首選語言是用 HttpServletRequest.getHeader("Accept-Language") 和基本的 Java 字符串操作提取的。

    另一種方法是,我們可以讓 Web 應用的用戶自行選擇首選語言,然后根據用戶的選擇生成語言代碼。您所要做的就是創建一個網頁,其中含有供用戶選擇首選語言的表單。具體實施細則請參閱 第一篇文章 的步驟 3,“使用表單”。

    用戶首選項與瀏覽器的語言環境

    通過讓用戶選擇將瀏覽器的語言環境用作他的語言(或語言環境)首選項,您就可以將用戶首選項和瀏覽器輸入結合起來使用。這也適用于其它類似的首選項,例如 12 小時制和 24 小時制。

    我們為什么要研究 HTTP 標頭或用戶首選項的解析過程呢?在獨立的國際化 Java 應用程序中,語言代碼是通過查詢系統獲得的。在查詢過程中, ResourceBundle 類負責為系統語言代碼查找正確的資源。但是,在我們的應用樣例中,用戶的語言(客戶機語言)完全與應用所在系統的語言(服務器語言)無關,我們不得不用一個固定的語言代碼代表用戶的首選語言。

    訪問針對客戶機首選語言提供的資源
    一旦成功地獲得正確的客戶機語言代碼,我們就需要使用固定的語言代碼查找翻譯文本。 清單 3 說明了如何使用清單 2 中的 Locale 對象 locale 完成此項工作。

    在第一篇文章中,我介紹過一個基于 XML/XSL Web 應用框架的應用樣例。在該框架中,我們需要區分需要 NLS 的兩個不同場所:在 Java 代碼中和在 XSL 樣式表中。

    Java 中的 NLS
    必須在 Java 中完成待顯示文本的 NLS 查找工作。就此處的情形而言,XML 數據可以包含待顯示文本 ― 也就是通過 XSL 轉換將 XML 數據復制為客戶機所要求的格式。在這種情況下,可以使用 ResourceBundle 類(請參閱 清單 3 )來查找已翻譯好的字符串常量,并將國際化字符串置入 XML 數據中。

    XSL 中的 NLS
    有些用戶界面可能需要使用特殊的輸出格式。例如,我們或許不希望在 Web 瀏覽器上和 WAP 電話上顯示完全一樣的輸入域標簽。對 WAP 電話而言,我們可能希望使用很短的標簽,而在 Web 瀏覽器中,標簽就可以長一些,還可以加入幫助內容輪翻顯示等功能。在這種情況下,同一個視圖的適用于不同格式的 XSL 樣式表就可以包含不同的文本。在 WebCal 的 XSL 樣式表中,我使用了許多字符串常量: LoginUsername PasswordDayWeekMonth 、本周的每一天,等等。為了將它們國際化,一種方案是實現 XSL 中的資源包查找,另一種方案是在 XML 生成期間(即在 Java 中)完成查找,同時把所需的全部翻譯內容添加到 XML 文檔中供樣式表使用。

    利用我在 WebCal 中使用過的 James Clark 的 XSL 處理器 XT(請參閱 參考資源 ),上面的兩種方案都能實現。XT 允許回調在 XSL 處理期間訪問處于 classpath 中的任何類的靜態方法。

    設想我們在 com.ibm.almaden.webcal.WebCalUtils 中有一個靜態查找方法,如 清單 4所示。

    如果能從 XML 中獲得語言代碼(也就是,如果 Java 代碼已在 XML 生成期間加入語言代碼),您就可以從您的式樣表中調用此方法。另一方面,假如語言代碼已經被作為根元素 webcallang 屬性加入 XML 數據中,則您也可以使用 清單 5中重點介紹的 XSL 指令完成查找工作。

    為保證此代碼樣例順利工作, lsLookUp()請參閱清單 4 )使用的資源包必須在每個語言文件中定義關鍵字 SUNDAY、MONDAY 等等。盡管可以使用非字符串的數據類型在 XSL 和靜態 Java 方法之間傳遞參數,但我建議使用字符串傳遞,以避免過多的轉換開銷。

    國際化的其他方面 除了語言之外,關于 NLS 和國際化還有許多問題。如果您還計劃使用時間、日期、或者貨幣符號,您可能需要使用更靈活的顯示方式和輸入域。

    對于從 XSL 中調用的方法,存在過載能力方面的一些限制。詳細信息請參閱 XT 文檔(請參閱 參考資源)。與在 XML 生成期間完成查找并在 XSL 處理之前將翻譯好的字符串包括在 XML 數據中的方法相比較,使用進入 Java 的回調不會產生相同的性能結果。

    NLS 小結
    這一部分詳細分析了國家語言支持問題,說明了如何確定用戶的首選語言以及如何用 Java 或 XSL 樣式表針對這種首選語言執行 NLS 查找。

    下面講解如何改進應用結構,以使代碼更易于維護和擴展。





    回頁首


    強化應用結構

    仔細觀察 WebCal 應用樣例,您會注意到所有的日歷視圖不僅共享相同的主導航和通用鏈接(Home 和 Logout),而且還共享包含新事件(New Event)鏈接的相同子導航條。第一篇文章介紹應用樣例時,我認為每個視圖的子導航是互不相同的。

    在復雜的 Web 應用中,您或許需要將視圖按功能分組 ― 例如,分為布局和導航 ― 這樣,您就不必一遍又一遍地為每個視圖進行定義,而且在需要變動時您只需修改一段代碼,無需再修改組中每個視圖的樣式表。這一點在 WebCal 應用樣例中沒有使用,不過分組方法基本上有二種:

    • 在導航元數據中定義組
    • 使用XSL 層疊樣式表

    在導航元數據中定義組 (WebCal: /web/<format>/navigation.xml)
    觀察 web/html/navigation.xml 中的 navigation.xml 文件,可以發現日歷視圖的以下 xml 代碼:


    清單 6: 未分組的視圖
    												
    														
    <actions>
    ...
    <action name="ShowDay">
    <sub-nav>
    <link type="internal" text="New Event" href="ShowNewEvent">
    <pass-param name="date"/>
    </link>
    </sub-nav>
    </action>
    <action name="ShowWeek">
    <sub-nav>
    <link type="internal" text="New Event" href="ShowNewEvent">
    <pass-param name="date"/>
    </link>
    </sub-nav>
    </action>
    <action name="ShowMonth">
    <sub-nav>
    <link type="internal" text="New Event" href="ShowNewEvent">
    <pass-param name="date"/>
    </link>
    </sub-nav>
    </action>
    ...
    </actions>

    顯然,這種結構難于維護:如果要為三個日歷視圖添加一個新的子導航鏈接,就必須在所有三個 <action> 元素中添加。如清單 7 所示,通過分組的視圖維護 XML 不是更容易嗎?


    清單 7: 分組視圖
    												<actions>
    ...
    <group name="calendar">
    <sub-nav>
    <link type="internal" text="New Event" href="ShowNewEvent">
    <pass-param name="date"/>
    </link>
    </sub-nav>
    <action name="ShowDay">
    <sub-nav/> <!-- no view specific sub navigation -->
    </action>
    <action name="ShowWeek">
    <sub-nav/> <!-- no view specific sub navigation -->
    </action>
    <action name="ShowMonth">
    <sub-nav/> <!-- no view specific sub navigation -->
    </action>
    </group>
    ...
    </actions>

    這樣一來,您就可以將新的子導航鏈接添加到 <group> 節點的 <sub-nav> 節點中,它就會在所有三個日歷視圖中顯示出來。由于只需要在一個地方定義該鏈接,從而提高了結構的可維護性。對本例而言似乎,這似乎沒有帶來什么好處,但實際的 Web 應用要比 WebCal 復雜得多。

    為簡單起見,我們假定分組以后再沒有未分組的視圖。這意味著 navigation.xml 文件中的 <actions> 元素再沒有 <action> 子元素。 <actions> 元素只有 <group> 子元素,后者至少再帶有一個 <action> 子元素。(通常,這表示在 <group> 節點之外不會有 <action> )。同樣,負責為視圖生成 XML 的 Java 代碼中也要包括包含此視圖(或者 action)的 XML 元素 ― 例如, <groupname>calendar</groupname> ,如清單 8 所示。


    清單 8: 視圖 XML
    												
    														
    <webcal>
    <http-params>
    <param name="action" value="ShowWeek"/>
    <param name="date" value="2001-02-11"/>
    </http-params>

    <groupname>calendar</groupname>
    <user>...</user>
    <navigation> ... </navigation> <!-- groups and actions as shown above -->
    <now date="2000-11-07T15:30"/>
    <week date="2001-02-11" previous="2001-02-04" next="2001-02-18">
    <day date="2001-02-11"/>
    ...
    </week>
    </webcal>


    在第一篇文章的清單 26 中,我介紹過一段為視圖創建子導航鏈接的 XSL 代碼。 清單9 是一段用視圖分組創建子導航的 XSL 代碼,它說明了如何從 XML 數據中獲取當前的 action 和 group (如清單 8 所示)。(在該清單中, action 代表 HTTP 的 action 參數在服務器上觸發的一些具體操作。每個這樣的操作都生成一個視圖,并會顯示這個顯示。)

    在 WebCal 中,子導航是區分視圖和組的唯一導航標準,但更復雜的應用可能會有若干個由分組機制處理的參數。另外一種分組機制要使用 XSL 層疊樣式表。

    XSL 層疊樣式表
    <xsl:include> 除了在導航元數據中完成分組外,還可以在樣式表中用于控制主面板 (main panel)(例如, WeekViewMain.xsl )。這樣,某個組的視圖樣式表就會包括該組中所有視圖使用的 XSL 模板。這就好比許多 Java 方法調用一個工具方法。第一篇文章介紹了如何由 frame.xsl 定義的總框架和與具體視圖相關的主面板來構建所有視圖。在同組視圖的總面板中,可以包括一個與具體組相關的“內層框架”樣式表,它產生組中所有視圖共同具有的那些響應。最后,內層框架再調用與具體視圖相關的樣式表,就像在 frame.xsl 中調用主模板那樣。這種“層疊”機制如圖 1 所示。


    圖 1:子框架

    “層疊”機制能應用到任何一層,從而形成組嵌套。

    小結:強化應用結構
    本部分介紹了如何對應用提供的視圖進行分組,以便于開發和更改管理。我推薦了兩種實現分組的方法:

    • 允許在 XML 元數據中定義組 ― 例如,在導航信息中。
    • 使用 XSL 層疊樣式表。




    回頁首


    性能:緩存探討

    現在我們研究一下我們的 Web 應用的性能。有多種方法可用來提高類似 WebCal 樣例那樣的原始應用的性能,最強有力的方法之一便是緩存。

    生成 XML、然后再用 XSLT 將它轉換成客戶機首選格式的過程涉及許多步驟。根據對系統需求的不同,可以在幾個不同的起點引入緩存。基本而言,可以通過對轉換的中間結果進行緩存來提高性能,此處可以使用 URL 請求(就是 action 名和所有的 HTTP 參數)、用戶名和預期格式的組合,并將該組合用作緩存的散列鍵。

    存在三種緩存方法,它們可以結合使用:

    • 緩存 XSL 樣式表
    • 緩存 XML
    • 緩存響應,表示 XML 已經用 XSL 樣式表轉換成了用戶的首選格式。

    下面將對三種方法逐一深入探討。

    緩存 XSL 樣式表
    觀察第一篇文章中的 XSL 轉換代碼(清單 16),可以發現每次將對一個請求的 XML 響應(或者新產生的,或者從緩存中獲取的)轉換為客戶機的首選格式時,在實際轉換發生之前總要完成以下兩個步聚:

    • 創建 XSLProcessor 類的一個實例
    • 上面創建的處理器對轉換所需的樣式表進行分析。

    XSLProcessor 實例可以在樣式表分析完成后進行緩存,以備后用。由于處理器與請求者和參數無關,緩存散列鍵就可以僅由 HTTP 的 action 參數值組成。該參數決定了要顯示的視圖和客戶機的首選格式(例如 HTML)。這樣,當用戶請求某個視圖后,緩存的處理器實例就可用來處理其他用戶對此視圖的請求。

    此方案的好處在于避免了每次請求視圖時都要實例化一個 XSLProcessor 實例并進行樣式表分析。這就意味著一個緩存的處理器可以被所有用戶使用,效率很高。

    此方案可在 WebCal 的 WebCalUtilities.transform(...) 方法中實現,如 清單 10 所示。它將樣式表 URI 作為散列鍵,其中包含 action 的名稱和格式(URI 的格式如下: http://localhost/webcal/<format>/<actioname>.xsl )。

    緩存 XML
    WebCal 已經實現了一項簡單的性能優化:navigation.xml 文件或用于其他格式的文件在 servlet 首次被加載并初始化時就同時被讀入。產生的導航 XML 文檔碎片先接格式緩存,然后在響應客戶機請求時添加到所生成的視圖 XML中。

    下一步是緩存在響應請求時創建的完整 XML 文檔。為此,您只需使用一個 hashtable 或者一個類似的集合來存儲 XML 文檔。這樣,每當用戶返回到他們已經訪問過的頁面時,URL 請求總會或多或少有些相似之處 ― 至少相關的參數、用戶名、action 名稱、期望格式、視圖特定的參數將會是相同的。如果用這些參數計算散列鍵,則很容易在緩存中找到同一視圖的舊版本。該方法的好處在于不用頻繁地訪問后端應用(數據庫、EJB 等)。

    該方法可以在 WebCal 的 ShowAction.displayResult() 方法中實現。但我更喜歡下面的方法,盡管相似卻更有效。其代碼樣例參見清單 1113

    緩存響應
    這一方法是剛介紹的 XML 緩存和樣式表緩存的結合。緩存響應的優勢是,如果之前曾有過同樣的請求并且結果仍存在緩存中,那么就可以在很短的時間內直接從服務器上得到響應。它的工作機制與上面介紹的 XML 緩存方法很相似,只是在這里整個轉換過程的最后結果都被緩存,使用的散列鍵與上面的相同。此方法的優點是訪問后端的頻率較低, 并且不必反復分析樣式表。

    此方法可以在 WebCal 的 ShowAction.displayResult() 方法中實現,如清單 1113所示。

    為了讓 清單 11 正常運行,必須對 ShowAction.java 或其超類 Action.java 作一定的修改,如清單 12 所示:


    清單 12: 修改后的 Action 類 (在 Action.java 或 ShowAction.java 中)
    												
    														

    在 Action.java :
    protected static Hashtable cache = new Hashtable();
    ...
    // 字節數組的包裝(內部類)
    protected class CachedResponse
    {
    public byte[] responseBytes;
    public CachedResponse(byte[] responseBytes)
    {
    this.responseBytes = responseBytes;
    }
    }


    最后,執行 XSL 轉換的方法還應返回轉換的結果,以便將其保存在緩存中。我在此處選擇 byte[] (字節數組)作為數據類型是因為它獨立于任何具體的字符編碼。 清單 13 顯示了必要的修改。

    缺點:緩存清除和依賴性
    利用緩存提高性能有幾個缺點。每當一個用戶通過 Web 應用接口作了某些更改時,XML 緩存或響應緩存必須執行相關性檢查。從緩存中刪除需要更新的頁面。

    處理此問題最簡單的辦法是為作出更改的用戶清除緩存。但是,如果系統允許用戶間交互 ― 例如,數據共享、小組日歷、會議邀請和調度變更 ― 則當僅有一個用戶更改某些數據時,所有用戶的緩存都要被清除。

    為了獲得更高的效率,緩存還應當保存每個頁面的相關性信息 ― 頁面所依賴的那部分系統。例如,WebCal 中的星期視圖依賴于用戶登錄的那一周所創建、修改和刪除的事件。相關性信息及其它附加信息,例如比較緩存數據日期與后端(數據庫)數據日期的時間戳,可以存儲于 清單 12 定義的 CachedResponse 類中。

    正面評價:不必清除 XSL 處理器緩存。與樣式表關聯的 XSL 處理器可以一直使用到樣式表改變為止,但樣式表的更改一般不會在運行時發生。

    不僅僅是緩存
    緩存中的信息可用來分析用戶行為,例如登錄后通常進行什么操作。使用這些信息,可以預先生成頁面并以動態鏈接方式提供給用戶,也可只將預先生成的頁面保存于緩存中,當客戶機發出請求時即可快速訪問。

    性能:學有所獲
    本部分介紹了如何使用不同的緩存方法提高應用的性能:緩存 XSL 處理器實例,緩存 XML,以及緩存 XSL 轉換的實際結果。緩存的內容可用于統計計算,這反過來又可用來預先生成用戶在會話期間可能會請求的頁面。





    回頁首


    小結

    在第一篇文章中,我介紹了使用 XML 和 XSL 轉換創建可擴展 Web 應用的基礎知識。本文接著介紹了如何添加一些高級功能。

    主要內容是:

    • 使用國家語言支持實現多語言全球訪問
    • 強化應用結構,以方便維護、更改管理以及進一步的開發。
    • 緩存是如何提高性能的。

    要使 Web 應用更富有專業色彩并使它們能夠隨時在線運行,所有這些都是很重要的因素。





    回頁首


    參考資料

    下載 WebCal 應用樣例(Windows .zip 格式)。





    回頁首


    關于作者

    Martin Gerlach,在 IBM Almaden 研究中心計算機科學部從事畢業后研究工作 擁有德國漢堡應用科學大學的計算機科學學位。可以通過 mgerlac@almaden.ibm.com 與 Martin 聯系。


    posted on 2006-03-21 23:30 Vincent.Chen 閱讀(298) 評論(0)  編輯  收藏 所屬分類: XML

    主站蜘蛛池模板: 国产免费一区二区三区VR| 亚洲免费视频观看| 午夜亚洲国产成人不卡在线| 亚洲日本成本人观看| 最近2019中文字幕mv免费看| 亚洲综合激情五月丁香六月| 永久免费av无码网站大全| 亚洲av成人一区二区三区在线播放| 日韩一级免费视频| 男女猛烈无遮掩视频免费软件| 亚洲国产精品不卡毛片a在线| 一级毛片免费全部播放| 亚洲精品卡2卡3卡4卡5卡区| 又粗又大又长又爽免费视频| 色多多A级毛片免费看| 中文字幕亚洲无线码| 久久青草免费91线频观看站街| 亚洲一区二区在线视频| 2020久久精品国产免费| 亚洲AV综合色区无码一二三区| 午夜亚洲av永久无码精品| a级毛片在线免费看| 亚洲另类小说图片| 亚洲A∨精品一区二区三区| a级日本高清免费看| 亚洲伊人久久大香线蕉啊| 日韩免费视频在线观看| 成人免费区一区二区三区| 亚洲乱码卡一卡二卡三| 国产乱色精品成人免费视频| 中国国产高清免费av片| 亚洲国产成人久久77| 午夜国产大片免费观看| 男人进去女人爽免费视频国产| 亚洲av片不卡无码久久| 亚洲一区二区三区免费| 3344免费播放观看视频| 羞羞的视频在线免费观看| 亚洲AV永久无码精品水牛影视| 好爽…又高潮了毛片免费看| 中国极品美軳免费观看|