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

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

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

    靈魂-放水

    為學日益,為道日損。

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks

    Patrick Gan (patgan@us.ibm.com), 應用程序卓越創新服務中心的高級 IT 專家, IBM

    Asynchronous JavaScript + XML (Ajax)是個相當新的術語(有些人說它是舊酒裝新瓶),在不同的 Web 開發社區中,都引起了很大的爭議,其中包括 Java EE 社區。Ajax 技術通過消除過多的 Web 頁面刷新,提高了應用程序的可用性。而且 Ajax 二者通吃的技術,同時利用了客戶端和服務器端代碼,向 Web 用戶呈現了幾乎無縫的用戶界面。Ajax 被鼓吹成 Web 開發復興(或稱為 Web 2.0)的一個主要推動者。

    作為用心的 Java EE 開發人員,您可能已經閱讀了許多關于 Ajax 的 how-to 文章,并對它會給應用程序帶來的可能改進而興奮。但是 Ajax 基于異步通信的模式要怎樣才適合您的 Java EE 應用程序呢?這篇文章通過研究在 Java EE 應用程序的設計、開發、執行和測試各階段引入 Ajax 會帶來的影響,將幫助您回答這個問題。我的目的不是不鼓勵使用 Ajax 或者暗示您可能遇到的問題是 Ajax 技術固有的問題。相反,我是為了幫助您規劃并減輕這些問題,好讓您更有效而順利地利用 Ajax。

    解決設計缺陷

    相當一段時間以來,Java 社區一直在努力把好的設計模式應用到與 Web 有關的應用程序開發上。其中使用最廣泛的一個模式就是模型-視圖-控制器(MVC)。一些開放源碼框架,例如 Apache Struts,就基于這個設計模式/架構(請參閱 參考資料)。MVC 的眾多優勢包括:問題隔離 和減少冗余代碼。

    問題隔離在整個應用程序架構中使用預先協商好的接口,從而讓應用程序開發項目中的每個開發人員都專注于自己特定的角色。例如,模型層的開發人員側重于 JDBC、企業 JavaBean(EJB)組件或者與底層數據持久技術接口的 Java 類這一類的技術。視圖層開發人員側重于 Java 服務器頁面(JSP)技術、標記庫和其他與表示有關的技術。控制器層隔離及協調模型和視圖,把進入的請求路由到后端持久性調用,同時維護問題的清晰隔離。圖 1 演示了 MVC 架構:


    圖 1. MVC 架構
    MVC 架構

    把 Ajax 引入 Java EE Web 應用程序對于問題的隔離(以及開發人員角色的隔離)是有意義的。在某些情況下,Ajax 會把大量 JavaScript 代碼帶回視圖層(JSP)頁面。表 1 描述了沒有 Ajax 的視圖層,還指出了需要的代碼(假設控制器層由 servlet 實現,視圖層由 JSP 技術實現。(在下一節 處理開發困境 我將解釋同步和異步請求的區別。)


    表 1. 沒有 Ajax 的 MVC:與典型的視圖層序列有關的代碼數量

    序列 說明 要求代碼?
    在調用同步請求之前 準備表單提交需要的腳本代碼
    調用異步請求 由按鈕或鏈接調用引起表單提交;DOM 元素的值自動設置到 HttpRequest(通過 GETPOST)。 否:所需要的只是調用頁面提交的途徑。
    處理同步請求的響應 在服務器端代碼執行完成后,通常會向 JSP 發送回一個對象(通過 HttpRequest 或保存在 HttpSession 中)。這時,在 JSP 中可以通過 HttpRequestHttpSession 訪問這個對象(通過腳本或某些標記庫),只需要編寫極少的腳本就可以顯示對象的內容。 是:最少的腳本。

    對比表 1 和表 2,表 2 描述了 Ajax 的 MVC 視圖層,同樣假設控制層由 servlet 實現,視圖層由 JSP 技術實現。


    表 2. 有 Ajax 的 MVC:與典型的視圖層序列有關的代碼數量

    序列 說明 需要代碼?
    在調用異步請求之前 需要用 JavaScript 代碼檢索出 Ajax 調用需要的 DOM 元素的值。
    調用異步請求 需要用 JavaScript 代碼創建 XMLHTTPRequest 并把(以前搜集的)DOM 元素值與之關聯并發送(XMLHTTPRequest.send())。
    處理異步請求的響應 在服務器端代碼執行完成后,要用 JavaScript 代碼得到請求(從 XML 響應流中)并把值相應地填充到適當的 DOM 元素。

    可以看出,由于使用了 Ajax,視圖層的腳本編寫量增加了,從而導致三個明顯缺陷:

    • JSP 要求大量的 JavaScript 代碼。
    • 這個設計破壞了角色問題的隔離。
    • 設計重新帶回了單一 JSP(模式 1 方法:一堆 HTML、CSS 代碼、圖片和腳本代碼),這是一種反模式,極難閱讀和維護(請參閱 參考資料)。

    有幾個選項可以避免或者至少減輕這些設計缺陷:

    • 設計時腦子里記著重用:不幸的是,編寫特定于 Ajax 支持的代碼通常很難避免。請計劃和設計腳本代碼,以便能夠最大限度地重用它。

    • 采用客戶端 MVC 方法:可以合并使用客戶端 MVC 方法,詳見 Dave Crane 等編寫的 Ajax in Action(請參閱 參考資料)。這種方法可以促進問題的隔離,但是增加了復雜性,所以使用的時候要仔細考慮。

    • 使用 Ajax 框架:存在多個開放源碼的 Ajax 框架,例如 Direct Web Remoting (DWR)(請參閱 參考資料),它們做了很好的工作,可以用最少的編碼,就把 Ajax 模式集成到 Java EE 應用程序。

    • 重新評估設計的正確性:實際上,Ajax 為 Web 應用程序提供了桌面應用程序的屬性。如果一個 Web 應用程序中大多數客戶端交互都利用 Ajax,那么這個應用程序可能最好設計成桌面應用程序。

    處理開發困境

    在 Java Web 開發中使用 Ajax 時,重要的是完整理解同步異步 通信模型的區別(請參閱 參考資料)。對異步通信模型支持的缺乏,會對客戶端開發、與 Web 框架的集成、標記庫的使用、IDE 的使用以及線程的行為有影響。

    在同步請求/響應通信模型中,總是瀏覽器(與 Web 服務器、應用服務器或 Web 應用程序相對)發起請求(通過 Web 用戶)。接著,Web 服務器、應用服務器或 Web 應用程序響應進入的請求。在處理同步請求/響應對期間,用戶不能繼續使用瀏覽器。

    圖 2 中的序列圖演示了傳統 Web 應用程序的同步通信模型。請注意在服務器的生命線上,來自客戶機的數據提交和服務器端的處理是緊密耦合的。


    圖 2. 同步通信序列
    同步通信序列

    在異步請求/響應通信模型中,瀏覽器(通過 Web 用戶)到 Web 服務器、應用服務器或 Web 應用程序的通信(以及反過來)是解耦的。在異步請求/響應對的處理中,Web 用戶在當前異步請求被處理時還可以繼續使用瀏覽器。一旦異步請求處理完成,異步響應就被通信(從 Web 服務器、應用服務器或 Web 應用程序)回客戶機頁面。典型情況下,在這個過程中,調用對 Web 用戶沒有影響;他們不需要等候響應。

    圖 3 的序列圖演示了異步通信模型。請注意第一個 dataSubmission (由服務器端處理)和第一個返回的 dataSubmission,兩個都用紅圈圈上了。這些序列是解耦的。這個圖示還強調了一個重要方面(后面將詳細介紹,請參閱 線程問題):在這個模型中,可以發生多個提交(線程)。


    圖 3. 異步通信序列
    異步通信序列

    客戶端影響

    在向 Web 應用程序引入 Ajax 時,開發團隊需要注意幾個風險,主要與生成的 HTML 頁面及其與瀏覽器的交互方式有關。這些問題在 Chris Laffra 兩部分的 Considering Ajax 系列中有詳細介紹(請參閱 參考資料)。有些需要記住的要點是:

    • 可能沒打開腳本功能:出于各種原因,在許多用戶的瀏覽器上禁止了 JavaScript 支持。

    • 跨瀏覽器支持增加了代碼需求:支持多種瀏覽器和多個瀏覽器版本的應用程序,要求的腳本代碼可能會增多,因為瀏覽器解釋 DOM 對象的方式有細微的差異(所以操作這些元素的 JavaScript 代碼也有差異)。

    • JavaScript 不安全:在多數瀏覽器中,可以選擇查看源代碼選項,查看到與 HTML 頁面關聯的 JavaScript 源代碼。在使用 Ajax 模式時,要確保腳本代碼中實現的邏輯不是敏感邏輯。

    與 Web 框架集成

    試著把 Ajax 開發與所選的 Java EE Web 框架集成,是很自然的。但是有些 Java EE Web 框架對異步通信模型提供直接可以使用的支持。要體會這個事實的意義,需要理解 servlet 處理同步和異步通信的方式。圖 4 顯示了處理同步請求的傳統 servlet 序列:


    圖 4. 處理同步請求的 Servlet 序列
    傳統 Servlet 序列(同步)

    圖 4 對于 Java EE Web 開發人員來說應當相當熟悉。來自瀏覽器的請求先由控制器 servlet 的 service() 處理。servlet 可以從 HttpRequest 檢索到需要的任何值(以參數的形式或者以屬性的形式)。一旦控制器處理完成,結果就發送回 HttpRequest (或 HttpSession),而 RequestDispatcher 則把控制轉發(或包含)回頁面。

    圖 5 顯示了處理異步請求的 servlet 序列:


    圖 5. 處理異步請求的 Servlet 序列
    Servlet 序列(異步)

    圖 5 中的序列與同步序列略有不同。來自瀏覽器的請求先由控制器 servlet 的 service() 處理。servlet 可以從 HttpRequest 檢索到需要的任何值(以參數的形式或者以屬性的形式)。一旦控制器處理完成,HttpServletResponse 的內容類型必須設置成 XML。而且,控制器邏輯的結果要用 PrintWriter 寫入。這時,RequestDispatcher 的使用被越過。

    這個(異步序列)恰恰是多數 Java EE Web 框架不支持的,從而造成與 Ajax 的集成非常困難。不支持異步通信模型的 Portlet 和 JavaServer Faces (JSF)框架面臨著同樣的問題。

    克服這個問題也有一些選項:

    • 與 Web 框架并存: 不必等待內置的 Ajax 支持或者在所選的框架中強行實現 Ajax 支持,可以使用獨立的 servlet 來處理全部異步請求。DWR 就使用了這種方式。這種方式的不足在于 Ajax 請求不能方便地利用框架的特性。

    • 與 Web 框架集成:通過使用免費的擴展或編寫定制的擴展,可以設計出與所選 Web 框架集成的途徑。

    • 遷移到支持 Ajax 的框架:更新的框架開始支持異步通信模型。其中一個是 Apache Shale(請參閱 參考資料)。

    使用標記庫

    大量使用標記庫(taglib)在 Java 的 Web 應用程序開發中是很普遍的。像許多 Java EE Web 框架一樣,有些標記庫現在也不支持異步通信模型,沒有把通過 XMLHttpRequest 提交的數據轉換成 HttpServletRequest (以及反過來)的途徑。實際上,不支持異步通信的標記庫,在 Ajax XMLHttpRequest 調用期間不工作。可用的選項有:

    • 放棄使用不支持異步模型的標記庫:把現在由標記庫生成的代碼遷移到 HTML/JavaScript 代碼。(如果 Web 應用程序高度依賴標記庫,這種方式最終會造成視圖層頁面尺寸的增大。)

    • 解決問題:使用已經解決了這個問題的 Ajax 框架。示例之一就是 DWR(請參閱 ExecutionContext.forwardToString())。 在這種情況下,可以繼續使用以前一直使用的標記庫。

    • 使用支持 Ajax 的標記庫:使用支持異步模型的標記庫,例如 Ajax JSP 標記庫(AjaxTags)(請參閱 參考資料)。

    用 IDE 進行開發與調試

    有許多 JavaScript 調試工具可以幫助開發人員開發 JavaScript 解決方案。但是,傳統的 Java 開發環境不允許檢查 XMLHTTPRequest 和與 Ajax 相關的其他東西的值。

    一個解決方案是利用 AJAX Toolkit Framework(ATF)(請參閱 參考資料)。ATF 是個 Eclipse 插件,帶有增強的 JavaScript 編輯特性,例如編輯時語法檢查,內嵌的 Mozilla Web 瀏覽器,內嵌的 DOM 瀏覽器,內嵌的 JavaScript 調試器。ATF 還包含 Personality Builder 功能,這個功能可以幫助任何 Ajax 運行時框架構建 IDE 特性,從而加入到 ATF 支持的運行時環境集中。

    線程問題

    在典型的同步 Web 應用程序中,有些領域對按鈕或鏈接點擊要求更長一點的處理時間。沒有耐心和沒經驗的 Web 用戶通常會不止一次地點擊按鈕或鏈接,以為可以幫助加快處理速度,從而引發多重表單提交。其他時候,用戶認為需要雙擊(就像桌面應用程序那樣)。Web 應用程序中的多重表單提交在某些情況下是無害的。而在其他情況下,副作用可能造成嚴重的線程問題或爭用情況(此時多個線程競爭執行一個代碼塊)。例如,在銀行應用程序中多次點擊轉帳按鈕,可能造成不希望的多次轉帳。

    既支持同步通信模型又支持異步通信模型的 Web 應用程序會發現,如果它的功能沒有正確分析和規劃,那么自己就處在了相似的困境中。支持兩種通信模型的應用程序在某個頁面上可能混合了服務器端調用(即,或者同步,或者異步,或者混合了同步和異步)。就像在多重點擊場景中一樣,異步調用可能處理得慢些。如果應用程序不做預防,用戶可能會在異步線程正在處理時又調用了一個同步調用,因為頁面沒有刷新,所以無法阻止頁面上的進一步活動。結果是兩個線程并發處理。雖然不是由 Web 頁面上的同一按鈕或鏈接引發,這類情況還是會造成服務器端的線程問題(與多重點擊問題類似)。

    例如,以圖 6 所示的銀行應用程序的轉賬頁面為例:


    圖 6. 轉帳示例
    轉賬示例

    對于這個示例,用紅色表示的轉賬按鈕引發一個 Ajax 調用。退出鏈接(黃色)引發同步調用。如果不耐煩或沒有經驗的用戶點擊了紅色按鈕之后接著又點擊黃色鏈接(假設兩個鏈接在代碼中有共同的路徑),就會發生爭用情況。

    一般來說,有兩種方式可以避免這類情況發生。第一種方式是客戶端解決方案。一旦點擊了一個鏈接或按鈕,就用 JavaScript 確保禁止后續的頁面提交,直到當前線程執行完成。第二個解決方案是允許多線程提交,但是依賴于服務器端代碼中的同步來避免爭用情況。如果引入同步來解決這個問題,請記住 Java EE Web 組件(servlet、portlet、JSF 等)是多線程的。要當心大段代碼的同步(特別是與請求/響應生命周期處理有關的代碼)。在效果上,同步的誤用,會把應用程序變成單線程應用程序,從而降低吞吐率。

    ?

    克服性能缺陷

    使用 Ajax 還有可能影響基于 Java EE Web 的應用程序的性能。允許每個請求上有額外線程的可能性,可能會影響兩個資源。

    首先,servlet 容器的線程池 可能受到影響。線程池指定 Web 容器中允許并發運行的線程的最大數量。每個客戶機請求需要一個線程。但是,一個客戶機請求不一定等于一個用戶請求。瀏覽器可能為一個用戶請求要求多個客戶機請求。例如,提交表單的一個用戶可能要求多個客戶機請求(其中包含提交表單的值、檢索 GIF 文件、檢索 JavaScript 文件、檢索 CSS 文件)。如果允許并發地提交同步和異步請求,就意味著每個用戶請求至少要支持多出一個的線程消耗(用于 Ajax 請求)。雖然為每個用戶請求多增加一個線程的可能性看起來不多,但是當應用程序處在負載之下時,影響就明顯了(這時每個用戶請求多出的一個額外線程乘上平均用戶數量)。顯示,這種情況有可能影響 servlet 容器的性能。

    另一個可能受影響的資源是數據庫連接池。典型的 Java EE Web 應用程序支持一個用戶請求的兩類序列:淺(shallow)請求和 深(deep)請求。淺請求是執行服務器端代碼但是不訪問持久性存儲(例如數據庫)就完成請求的 Web 頁面發出的請求。深請求是執行服務器端代碼并訪問持久性存儲才能完成請求的 Web 頁面發出的請求。

    在深請求序列中(假設需要數據庫連接),數據庫連接池的這些方面可能會由于允許多個線程而受到影響:

    • 等待連接的線程的平均數量
    • 以毫秒為單位的連接的平均等候時間
    • 連接被使用的平均時間

    所以,可能需要提高連接池的平均大小或連接數量。

    對付測試

    Java 開發人員一直在不斷地努力為 Java SE 和 Java EE 代碼提供單元測試工具。由于 Ajax 的引入造成瀏覽器內的 JavaScript 增多,對可靠的 JavaScript 單元測試框架也提出了要求。現在可用的框架有 JsUnit、Selenium 和 HttpUnit(請參閱 參考資料)。

    這些框架提供了為 JavaScript 函數開發單元測試的工具,可以操縱 Web 頁面上的 DOM 元素。它們允許把單元測試組織成測試套件。Selenium 的瀏覽器兼容性測試特性允許在不同的瀏覽器和操作系統上測試 JavaScript 函數。它利用 JavaScript 和 Iframe 在瀏覽器中嵌入了測試自動引擎。這項技術應當可以在任何支持 JavaScript 的瀏覽器中工作,對于支持多個瀏覽器和瀏覽器版本的應用程序來說特別有用。Selenium 和 JsUnit 都支持持續集成:可以把 JavaScript 單元測試和測試套件集成到自動構建過程。

    結束語

    把 Ajax —— 就像其他技術或模式一樣 —— 引入 Java EE 應用程序,也有它的優勢和不足。本文提供了把 Ajax 集成到 Java EE Web 應用程序的概述。Ajax 的異步通信模型與傳統 Java EE Web 應用程序內置就支持的同步模型有很大不同。為了避免盲目,請確保在采用 Ajax 之前對潛在的問題領域有全面的事前規劃。

    Java EE 框架對 Ajax 的支持和工具在不斷改進。未來有望會有框架自帶的 Ajax 支持來降低集成的復雜性。基于 JSF 的 Apache Shale 和基于 servlet 的 DWR 是兩個希望您保持關注的框架。



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1155119

    posted on 2006-09-08 15:12 放水老倌 閱讀(277) 評論(0)  編輯  收藏 所屬分類: J2EE
    主站蜘蛛池模板: 97人伦色伦成人免费视频 | 亚洲视频在线观看免费| 无遮挡a级毛片免费看| 国产免费小视频在线观看| 亚洲日韩精品无码专区| 日韩精品成人无码专区免费| 亚洲国产成人99精品激情在线| 日本h在线精品免费观看| 亚洲国产精品成人久久久| 色播精品免费小视频| 亚洲天堂2016| 女人张开腿给人桶免费视频| 最新亚洲人成网站在线观看| 亚洲国产a级视频| 成人精品视频99在线观看免费| 欧洲亚洲综合一区二区三区| 免费一级做a爰片久久毛片潮喷| 国产天堂亚洲精品| 亚洲一区二区精品视频| 叮咚影视在线观看免费完整版| 色婷婷六月亚洲婷婷丁香| 一本无码人妻在中文字幕免费| 亚洲AV成人无码久久WWW| 国产成人毛片亚洲精品| 久久久久久久久久国产精品免费| 亚洲免费视频观看| 中文字幕无码视频手机免费看| 亚洲综合无码无在线观看| 免费看国产一级特黄aa大片| 成人A毛片免费观看网站| 亚洲的天堂av无码| 国产免费资源高清小视频在线观看| j8又粗又长又硬又爽免费视频| 亚洲成人午夜在线| 国产黄色片在线免费观看| 99热在线日韩精品免费| 亚洲欧洲综合在线| 亚洲成片观看四虎永久| 亚洲综合免费视频| 欧洲美女大片免费播放器视频| 久久亚洲伊人中字综合精品|