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

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

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

    AJAX brief introduction ---bea2bea comes

    作為J2EE開發(fā)人員,我們似乎經(jīng)常關注“后端機制(backend mechanics)”。我們通常會忘記,J2EE的主要成功之處在Web應用程序方面;許多原因使得人們喜歡利用Web開發(fā)應用程序,但主要還是因為其易于部署的特點允許站點以盡可能低的成本擁有上百萬的用戶。遺憾的是,在過去幾年中,我們在后端投入了太多的時間,而在使我們的Web用戶界面對用戶自然和響應靈敏方面卻投入不足。

      本文介紹一種方法,Ajax,使用它可以構(gòu)建更為動態(tài)和響應更靈敏的Web應用程序。該方法的關鍵在于對瀏覽器端的JavaScript、DHTML和與服務器異步通信的組合。本文也演示了啟用這種方法是多么簡單:利用一個Ajax框架(指DWR)構(gòu)造一個應用程序,它直接從瀏覽器與后端服務進行通信。如果使用得當,這種強大的力量可以使應用程序更加自然和響應靈敏,從而提升用戶的瀏覽體驗。

      該應用程序中所使用的示例代碼已打包為單獨的WAR文件,可供下載。

    簡介

      術語Ajax用來描述一組技術,它使瀏覽器可以為用戶提供更為自然的瀏覽體驗。在Ajax之前,Web站點強制用戶進入提交/等待/重新顯示范例,用戶的動作總是與服務器的“思考時間”同步。Ajax提供與服務器異步通信的能力,從而使用戶從請求/響應的循環(huán)中解脫出來。借助于Ajax,可以在用戶單擊按鈕時,使用JavaScript和DHTML立即更新UI,并向服務器發(fā)出異步請求,以執(zhí)行更新或查詢數(shù)據(jù)庫。當請求返回時,就可以使用JavaScript和CSS來相應地更新UI,而不是刷新整個頁面。最重要的是,用戶甚至不知道瀏覽器正在與服務器通信:Web站點看起來是即時響應的。

      雖然Ajax所需的基礎架構(gòu)已經(jīng)出現(xiàn)了一段時間,但直到最近異步請求的真正威力才得到利用。能夠擁有一個響應極其靈敏的Web站點確實激動人心,因為它最終允許開發(fā)人員和設計人員使用標準的HTML/CSS/JavaScript堆棧創(chuàng)建“桌面風格的(desktop-like)”可用性。

      通常,在J2EE中,開發(fā)人員過于關注服務和持久性層的開發(fā),以至于用戶界面的可用性已經(jīng)落后。在一個典型的J2EE開發(fā)周期中,常常會聽到這樣的話,“我們沒有可投入UI的時間”或“不能用HTML實現(xiàn)”。但是,以下Web站點證明,這些理由再也站不住腳了:

      所有這些Web站點都告訴我們,Web應用程序不必完全依賴于從服務器重新載入頁面來向用戶呈現(xiàn)更改。一切似乎就在瞬間發(fā)生。簡而言之,在涉及到用戶界面的響應靈敏度時,基準設得更高了。

    定義Ajax

      Adaptive Path公司的Jesse James Garrett這樣定義Ajax

      Ajax不是一種技術。實際上,它由幾種蓬勃發(fā)展的技術以新的強大方式組合而成。Ajax包含:

    • 基于XHTMLCSS標準的表示;
    • 使用Document Object Model進行動態(tài)顯示和交互;
    • 使用XMLHttpRequest與服務器進行異步通信;
    • 使用JavaScript綁定一切。

      這非常好,但為什么要以Ajax命名呢?其實術語Ajax是由Jesse James Garrett創(chuàng)造的,他說它是“Asynchronous JavaScript + XML的簡寫”。

    Ajax的工作原理

      Ajax的核心是JavaScript對象XmlHttpRequest。該對象在Internet Explorer 5中首次引入,它是一種支持異步請求的技術。簡而言之,XmlHttpRequest使您可以使用JavaScript向服務器提出請求并處理響應,而不阻塞用戶。

      在創(chuàng)建Web站點時,在客戶端執(zhí)行屏幕更新為用戶提供了很大的靈活性。下面是使用Ajax可以完成的功能:

    • 動態(tài)更新購物車的物品總數(shù),無需用戶單擊Update并等待服務器重新發(fā)送整個頁面。
    • 提升站點的性能,這是通過減少從服務器下載的數(shù)據(jù)量而實現(xiàn)的。例如,在Amazon的購物車頁面,當更新籃子中的一項物品的數(shù)量時,會重新載入整個頁面,這必須下載32K的數(shù)據(jù)。如果使用Ajax計算新的總量,服務器只會返回新的總量值,因此所需的帶寬僅為原來的百分之一。
    • 消除了每次用戶輸入時的頁面刷新。例如,在Ajax中,如果用戶在分頁列表上單擊Next,則服務器數(shù)據(jù)只刷新列表而不是整個頁面。
    • 直接編輯表格數(shù)據(jù),而不是要求用戶導航到新的頁面來編輯數(shù)據(jù)。對于Ajax,當用戶單擊Edit時,可以將靜態(tài)表格刷新為內(nèi)容可編輯的表格。用戶單擊Done之后,就可以發(fā)出一個Ajax請求來更新服務器,并刷新表格,使其包含靜態(tài)、只讀的數(shù)據(jù)。

      一切皆有可能!但愿它能夠激發(fā)您開始開發(fā)自己的基于Ajax的站點。然而,在開始之前,讓我們介紹一個現(xiàn)有的Web站點,它遵循傳統(tǒng)的提交/等待/重新顯示的范例,我們還將討論Ajax如何提升用戶體驗。

    Ajax可用于那些場景?——一個例子:MSN Money頁面

      前幾天,在瀏覽MSN Money頁面的時候,有一篇關于房地產(chǎn)投資的文章引起了我的好奇心。我決定使用站點的“Rate this article”(評價本文)功能,鼓勵其他的用戶花一點時間來閱讀這篇文章。在我單擊vote按鈕并等待了一會兒之后,整個頁面被刷新,在原來投票問題所在的地方出現(xiàn)了一個漂亮的感謝畫面。

      而Ajax能夠使用戶的體驗更加愉快,它可以提供響應更加靈敏的UI,并消除頁面刷新所帶來的閃爍。目前,由于要刷新整個頁面,需要傳送大量的數(shù)據(jù),因為必須重新發(fā)送整個頁面。如果使用Ajax,服務器可以返回一個包含了感謝信息的500字節(jié)的消息,而不是發(fā)送26,813字節(jié)的消息來刷新整個頁面。即使使用的是高速Internet,傳送26K和1/2K的差別也非常大。同樣重要的是,只需要刷新與投票相關的一小節(jié),而不是刷新整個屏幕。

      讓我們利用Ajax實現(xiàn)自己的基本投票系統(tǒng)。

    原始的Ajax:直接使用XmlHttpRequest

      如上所述,Ajax的核心是JavaScript對象XmlHttpRequest。下面的示例文章評價系統(tǒng)將帶您熟悉Ajax的底層基本知識:http://tearesolutions.com/ajax-demo/raw-ajax.html。注:如果您已經(jīng)在本地WebLogic容器中安裝了ajax-demo.war,可以導航到http://localhost:7001/ajax-demo/raw-ajax.html

      瀏覽應用程序,參與投票,并親眼看它如何運轉(zhuǎn)。熟悉了該應用程序之后,繼續(xù)閱讀,進一步了解其工作原理細節(jié)。

      首先,您擁有一些簡單的定位點標記,它連接到一個JavaScriptcastVote(rank)函數(shù)。
    function castVote(rank) {
      var url = "/ajax-demo/static-article-ranking.html";
      var callback = processAjaxResponse;
      executeXhr(callback, url);
    }
    

      該函數(shù)為您想要與之通信的服務器資源創(chuàng)建一個URL并調(diào)用內(nèi)部函數(shù)executeXhr,提供一個回調(diào)JavaScript函數(shù),一旦服務器響應可用,該函數(shù)就被執(zhí)行。由于我希望它運行在一個簡單的Apache環(huán)境中,“cast vote URL”只是一個簡單的HTML頁面。在實際情況中,被調(diào)用的URL將記錄票數(shù)并動態(tài)地呈現(xiàn)包含投票總數(shù)的響應。

      下一步是發(fā)出一個XmlHttpRequest請求:
    function executeXhr(callback, url) {
      // branch for native XMLHttpRequest object
      if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = callback;
        req.open("GET", url, true);
        req.send(null);
      } // branch for IE/Windows ActiveX version
      else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
          req.onreadystatechange = callback;
          req.open("GET", url, true);
          req.send();
        }
      }
    }
    
    

      如您所見,執(zhí)行一個XmlHttpRequest并不簡單,但非常直觀。和平常一樣,在JavaScript領域,大部分的工作量都花在確保瀏覽器兼容方面。在這種情況下,首先要確定XmlHttpRequest是否可用。如果不能用,很可能要使用Internet Explorer,這樣就要使用所提供的ActiveX實現(xiàn)。

    executeXhr()方法中最關鍵的部分是這兩行:

    req.onreadystatechange = callback;
    req.open("GET", url, true);
    

      第一行定義了JavaScript回調(diào)函數(shù),您希望一旦響應就緒它就自動執(zhí)行,而req.open()方法中所指定的“true”標志說明您想要異步執(zhí)行該請求。

      一旦服務器處理完XmlHttpRequest并返回給瀏覽器,使用req.onreadystatechange指派所設置的回調(diào)方法將被自動調(diào)用。
    function processAjaxResponse() {
      // only if req shows "loaded"
      if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
          502 502'votes').innerHTML = req.responseText;
        } else {
          alert("There was a problem retrieving the XML data:
    " +
          req.statusText);
        }
      }
    } 
    

      該代碼相當簡潔,并且使用了幾個幻數(shù),這使得難以一下子看出發(fā)生了什么。為了弄清楚這一點,下面的表格(引用自http://developer.apple.com/internet/webcontent/xmlhttpreq.html)列舉了常用的XmlHttpRequest對象屬性。

    屬性

    描述

    onreadystatechange

    每次狀態(tài)改變所觸發(fā)事件的事件處理程序

    readyState

    對象狀態(tài)值:

    • 0 = 未初始化(uninitialized)
    • 1 = 正在加載(loading)
    • 2 = 加載完畢(loaded)
    • 3 = 交互(interactive)
    • 4 = 完成(complete)

    responseText

    從服務器進程返回的數(shù)據(jù)的字符串形式

    responseXML

    從服務器進程返回的DOM兼容的文檔數(shù)據(jù)對象

    status

    從服務器返回的數(shù)字代碼,比如404(未找到)或200(就緒)

    statusText

    伴隨狀態(tài)碼的字符串信息

      現(xiàn)在processVoteResponse()函數(shù)開始顯示出其意義了。它首先檢查XmlHttpRequest的整體狀態(tài)以保證它已經(jīng)完成(readyStatus == 4),然后根據(jù)服務器的設定詢問請求狀態(tài)。如果一切正常(status == 200),就使用innerHTML屬性重寫DOM的“votes”節(jié)點的內(nèi)容。

      既然您親眼看到了XmlHttpRequest對象是如何工作的,就讓我們利用一個旨在簡化JavaScript與Java應用程序之間的異步通信的框架來對具體的細節(jié)進行抽象。

    Ajax: DWR方式

      按照與文章評價系統(tǒng)相同的流程,我們將使用Direct Web Remoting(DWR)框架實現(xiàn)同樣的功能。

      假定文章和投票結(jié)果存儲在一個數(shù)據(jù)庫中,使用某種對象/關系映射技術來完成抽取工作。為了部署起來盡可能地簡單,我們不會使用數(shù)據(jù)庫進行持久性存儲。此外,為使應用程序盡可能通用,也不使用Web框架。相反,應用程序?qū)囊粋€靜態(tài)HTML文件開始,可以認為它由服務器動態(tài)地呈現(xiàn)。除了這些簡化措施,應用程序還應該使用Spring Framework關聯(lián)一切,以便輕松看出如何在一個“真實的”應用程序中使用DWR。

      現(xiàn)在應該下載示例應用程序并熟悉它。該應用程序被壓縮為標準的WAR文件,因此您可以把它放置到任何一個Web容器中——無需進行配置。部署完畢之后,就可以導航到http://localhost:7001/ajax_demo/dwr-ajax.html來運行程序。

      可以查看HTML 源代碼,了解它如何工作。給人印象最深的是,代碼如此簡單——所有與服務器的交互都隱藏在JavaScript對象ajaxSampleSvc的后面。更加令人驚訝的是,ajaxSampleSvc服務不是由手工編寫而是完全自動生成的!讓我們繼續(xù),看看這是如何做到的。

    引入DWR

      如同在“原始的Ajax”一節(jié)所演示的那樣,直接使用XmlHttpRequest創(chuàng)建異步請求非常麻煩。不僅JavaScript代碼冗長,而且必須考慮服務器端為定位Ajax請求到適當?shù)姆账枳龅墓ぷ鳎⒔Y(jié)果封送到瀏覽器。

      設計DWR的目的是要處理將Web頁面安裝到后端服務上所需的所有信息管道。它是一個Java框架,可以很輕松地將它插入到Web應用程序中,以便JavaScript代碼可以調(diào)用服務器上的服務。它甚至直接與Spring Framework集成,從而允許用戶直接向Web客戶機公開bean。

      DWR真正的巧妙之處是,在用戶配置了要向客戶機公開的服務之后,它使用反射來生成JavaScript對象,以便Web頁面能夠使用這些對象來訪問該服務。然后Web頁面只需接合到生成的JavaScript對象,就像它們是直接使用服務一樣;DWR無縫地處理所有有關Ajax和請求定位的瑣碎細節(jié)。

      讓我們仔細分析一下示例代碼,弄清它是如何工作的。

    應用程序細節(jié):DWR分析

      關于應用程序,首先要注意的是,它是一個標準的Java應用程序,使用分層架構(gòu)(Layered Architecture)設計模式。使用DWR通過JavaScript公開一些服務并不影響您的設計。

      下面是一個簡單的Java服務,我們將使用DWR框架直接將其向JavaScript代碼公開:

    package com.tearesolutions.service;
    
    public interface AjaxSampleSvc { 
      Article castVote(int rank);
    }
    

      這是一個被簡化到幾乎不可能的程度的例子,其中只有一篇文章可以投票。該服務由Spring管理,它使用的bean名是ajaxSampleSvc,它的持久性需求則依賴于ArticleDao。詳情請參見applicationContext.xml。

      為了把該服務公開為JavaScript對象,需要配置DWR,添加dwr.xml文件到WEB-INF目錄下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE dwr PUBLIC
     "-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN"
     "http://www.getahead.ltd.uk/dwr/dwr.dtd">
    	
    <dwr>
     <allow>
      <create creator="spring" javascript="ajaxSampleSvc">
       <param name="beanName" value="ajaxSampleSvc" />
      </create>
      <convert converter="bean" match="com.tearesolutions.model.Article"/>
      <exclude method="toString"/>
      <exclude method="setArticleDao"/>
     </allow>
    </dwr>
    

      dwr.xml文件告訴DWR哪些服務是要直接向JavaScript代碼公開的。注意,已經(jīng)要求公開Spring bean ajaxSampleSvc。DWR將自動找到由應用程序設置的SpringApplicationContext。為此,必須使用標準的servlet過濾器ContextLoaderListener來初始化Spring ApplicationContext。

      DWR被設置為一個servlet,所以把它的定義添加到web.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD 
     Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    
    <web-app>
     <display-name>Ajax Examples</display-name>
    
     <listener>
      <listener-class>
          org.springframework.web.context.ContextLoaderListener
      </listener-class>
     </listener>
    	
     <servlet>
      <servlet-name>ajax_sample</servlet-name>
      <servlet-class>com.tearesolutions.web.AjaxSampleServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
     </servlet>
    
     <servlet>
      <servlet-name>dwr-invoker</servlet-name>
      <display-name>DWR Servlet</display-name>
      <description>Direct Web Remoter Servlet</description>
      <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
      <init-param>
       <param-name>debug</param-name>
       <param-value>true</param-value>
      </init-param>
     </servlet>
    
     <servlet-mapping>
      <servlet-name>ajax_sample</servlet-name>
      <url-pattern>/ajax_sample</url-pattern>
     </servlet-mapping>
    
     <servlet-mapping>
      <servlet-name>dwr-invoker</servlet-name>
      <url-pattern>/dwr/*</url-pattern>
     </servlet-mapping>
    </web-app>
    

      做完這些之后,可以加載http://localhost:7001/ajax-demo/dwr,看看哪些服務可用。結(jié)果如下:

    圖3. 可用的服務

      單擊ajaxSampleSvc鏈接,查看有關如何在HTML頁面內(nèi)直接使用服務的示例實現(xiàn)。其中包含的兩個JavaScript文件完成了大部分的功能:
    <script type='text/javascript' 
       src='/ajax-demo/dwr/interface/ajaxSampleSvc.js'></script>
    <script type='text/javascript' 
       src='/ajax-demo/dwr/engine.js'></script>
    

    ajaxSampleSvc.js是動態(tài)生成的:

    function ajaxSampleSvc() { }
    
    ajaxSampleSvc.castVote = function(callback, p0)
    { 
      DWREngine._execute(callback, '/ajax-demo/dwr', 
     'ajaxSampleSvc', 'castVote', p0);
    }
    

      現(xiàn)在可以使用JavaScript對象ajaxSampleSvc替換所有的XmlHttpRequest代碼,從而重構(gòu)raw-ajax.html文件。可以在dwr-ajax.html文件中看到改動的結(jié)果;下面是新的JavaScript函數(shù):

    function castVote(rank) {
      ajaxSampleSvc.castVote(processResponse, rank);
    }
    function processResponse(data) {
     var voteText = "

    Thanks for Voting!

    " + "

    Current ranking: " + data.voteAverage + " out of 5

    " + "

    Number of votes placed: " + data.numberOfVotes + "

    "; 502 502'votes').innerHTML = voteText; }

      驚人地簡單,不是嗎?由ajaxSampleSvc對象返回的Article域?qū)ο笮蛄谢癁橐粋€JavaScript對象,允許在它上面調(diào)用諸如numberOfVotes()和voteAverage()之類的方法。在動態(tài)生成并插入到DIV元素“votes”中的HTML代碼內(nèi)使用這些數(shù)據(jù)。

    下一步工作

       在后續(xù)文章中,我將繼續(xù)有關Ajax的話題,涉及下面這些方面:

    • Ajax最佳實踐

      像許多技術一樣,Ajax是一把雙刃劍。對于一些用例,其應用程序其實沒有必要使用Ajax,使用了反而有損可用性。我將介紹一些不適合使用的模式,突出說明Ajax的一些消極方面,并展示一些有助于緩和這些消極方面的機制。例如,對Netflix電影瀏覽器來說,Ajax是合適的解決方案嗎?或者,如何提示用戶確實出了一些問題,而再次單擊按鈕也無濟于事?

    • 管理跨請求的狀態(tài)

      在使用Ajax時,最初的文檔DOM會發(fā)生一些變化,并且有大量的頁面狀態(tài)信息存儲在客戶端變量中。當用戶跟蹤一個鏈接到應用程序中的另一個頁面時,狀態(tài)就丟失了。當用戶按照慣例單擊Back按鈕時,呈現(xiàn)給他們的是緩存中的初始頁面。這會使用戶感到非常迷惑!

    • 調(diào)試技巧

      使用JavaScript在客戶端執(zhí)行更多的工作時,如果事情不按預期方式進行,就需要一些調(diào)試工具來幫助弄清出現(xiàn)了什么問題。

    結(jié)束語

      本文介紹了Ajax方法,并展示了如何使用它來創(chuàng)建一個動態(tài)且響應靈敏的Web應用程序。通過使用DWR框架,可以輕松地把Ajax融合到站點中,而無需擔心所有必須執(zhí)行的實際管道工作。

      特別感謝Getahead IT咨詢公司的Joe Walker和他的團隊開發(fā)出DWR這樣神奇的工具。感謝你們與世界共享它!

    下載

      本文中演示的應用程序源代碼可供下載:ajax-demo.war(1.52 MB)。

    參考資料

    posted on 2005-12-23 10:47 大樹 閱讀(124) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統(tǒng)計

    公告

    本期話題
    能源行業(yè)資產(chǎn)管理咨詢
    資產(chǎn)管理信息化方案提供
    資產(chǎn)管理相關行業(yè)培訓
    大型企業(yè)軟件體系架構(gòu)整合
    資產(chǎn)管理信息系統(tǒng)實施
    信息集成
    信息孤島

    常用鏈接

    留言簿(6)

    隨筆檔案(45)

    文章檔案(7)

    新聞檔案(1)

    相冊

    wallgate management consulting

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产精品亚洲精品日韩已满| 全部免费毛片在线| 国产成人无码区免费网站| 亚洲码国产精品高潮在线| 鲁丝片一区二区三区免费| 久久亚洲AV无码精品色午夜麻豆 | 免费人成视频在线| 亚洲冬月枫中文字幕在线看| 一级毛片在线免费视频| 免费一级毛片不卡在线播放| 男女交性无遮挡免费视频| 又大又粗又爽a级毛片免费看| 污污的视频在线免费观看| 一级毛片免费毛片一级毛片免费| 亚洲国产精品精华液| WWW国产成人免费观看视频| 亚洲美女人黄网成人女| 无遮挡呻吟娇喘视频免费播放| 情侣视频精品免费的国产| 在线观看免费a∨网站| 久久久久亚洲AV成人网人人软件| 日韩在线观看免费完整版视频| 免费国产叼嘿视频大全网站| 免费无码又爽又刺激聊天APP| 亚洲欧洲精品成人久久曰| 免费国产不卡午夜福在线| 国产成人无码免费看片软件| 亚洲国产精品无码中文字| 黄色网站软件app在线观看免费| 91天堂素人精品系列全集亚洲| 亚洲mv国产精品mv日本mv| 三年片免费高清版 | 亚洲1区2区3区精华液| 亚洲色偷偷狠狠综合网| 无码乱人伦一区二区亚洲一| 亚洲免费二区三区| 亚洲国产精品视频| 91麻豆国产免费观看| 色窝窝亚洲AV网在线观看| 成年男女男精品免费视频网站 | 无码av免费毛片一区二区 |