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

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

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

    posts - 4,  comments - 4,  trackbacks - 0
    轉: 作者:David Teare

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

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

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

    簡介

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

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

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

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

    定義Ajax

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

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

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

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

    Ajax的工作原理

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

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

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

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

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

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

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

      讓我們利用Ajax實現自己的基本投票系統。

    原始的Ajax:直接使用XmlHttpRequest

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

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

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

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

      下一步是發出一個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();
        }
      }
    }
    
    

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

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

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

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

      一旦服務器處理完XmlHttpRequest并返回給瀏覽器,使用req.onreadystatechange指派所設置的回調方法將被自動調用。
    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);
        }
      }
    } 
    

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

    屬性

    描述

    onreadystatechange

    每次狀態改變所觸發事件的事件處理程序

    readyState

    對象狀態值:

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

    responseText

    從服務器進程返回的數據的字符串形式

    responseXML

    從服務器進程返回的DOM兼容的文檔數據對象

    status

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

    statusText

    伴隨狀態碼的字符串信息

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

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

    Ajax: DWR方式

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

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

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

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

    引入DWR

      如同在“原始的Ajax”一節所演示的那樣,直接使用XmlHttpRequest創建異步請求非常麻煩。不僅JavaScript代碼冗長,而且必須考慮服務器端為定位Ajax請求到適當的服務所需做的工作,并將結果封送到瀏覽器。

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

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

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

    應用程序細節:DWR分析

      關于應用程序,首先要注意的是,它是一個標準的Java應用程序,使用分層架構(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代碼公開的。注意,已經要求公開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,看看哪些服務可用。結果如下:

    圖3. 可用的服務

      單擊ajaxSampleSvc鏈接,查看有關如何在HTML頁面內直接使用服務的示例實現。其中包含的兩個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是動態生成的:

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

      現在可以使用JavaScript對象ajaxSampleSvc替換所有的XmlHttpRequest代碼,從而重構raw-ajax.html文件。可以在dwr-ajax.html文件中看到改動的結果;下面是新的JavaScript函數:

    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域對象序列化為一個JavaScript對象,允許在它上面調用諸如numberOfVotes()和voteAverage()之類的方法。在動態生成并插入到DIV元素“votes”中的HTML代碼內使用這些數據。

    下一步工作

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

    • Ajax最佳實踐

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

    • 管理跨請求的狀態

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

    • 調試技巧

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

    結束語

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

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

    下載

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

    參考資料

    原文出處

    An Introduction To Ajax

    http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html

    posted on 2006-10-19 17:38 sheng999 閱讀(111) 評論(0)  編輯  收藏 所屬分類: ajax技術

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


    網站導航:
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    歡迎光臨,一起努力,創造設計.

    常用鏈接

    留言簿(1)

    隨筆檔案(4)

    文章分類(2)

    文章檔案(2)

    新聞分類(1)

    新聞檔案(2)

    搜索

    •  

    積分與排名

    • 積分 - 1731
    • 排名 - 4139

    最新評論

    閱讀排行榜

    評論排行榜

    SHENG 設 計 在 線
    主站蜘蛛池模板: 国产无遮挡吃胸膜奶免费看| 日本最新免费网站| 国产无遮挡色视频免费观看性色| 国产精品美女久久久免费 | 和日本免费不卡在线v| 亚洲av色福利天堂| 黄色网址在线免费| 国产美女无遮挡免费视频 | 亚洲成a人片7777| 成人免费视频77777| 久久精品国产亚洲5555| 国产激情久久久久影院老熟女免费 | 亚洲国产美国国产综合一区二区 | 国产成人精品免费午夜app| 午夜精品一区二区三区免费视频 | 国产精品亚洲综合网站| 久久免费视频99| 又大又黄又粗又爽的免费视频| 最新亚洲人成无码网站| 最近免费最新高清中文字幕韩国| 国产免费啪嗒啪嗒视频看看| 日日摸夜夜添夜夜免费视频 | 羞羞漫画页面免费入口欢迎你| 亚洲黄黄黄网站在线观看| a级片在线免费看| 亚洲综合激情六月婷婷在线观看| 麻豆安全免费网址入口| 青青在线久青草免费观看| 亚洲色无码国产精品网站可下载 | 久久青青成人亚洲精品| 国产精品亚洲小说专区| 成人A级毛片免费观看AV网站| 亚洲AV成人无码网站| 亚洲精品~无码抽插| 在线视频免费观看爽爽爽| 亚洲爆乳无码精品AAA片蜜桃| 国产亚洲精品福利在线无卡一| 狠狠入ady亚洲精品| 久久精品国产精品亚洲艾| 高清国语自产拍免费视频国产| 亚洲免费无码在线|