Java Votary

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            48 隨筆 :: 1 文章 :: 80 評論 :: 0 Trackbacks

          #

          原文:http://www.aygfsteel.com/eamoi/archive/2005/11/01/17639.html

          有網友反映說《AJAX開發簡略》配文代碼不全。其實應該是全的,只是要把包括框架和兩個示例的程序都整合起來看。這里把全部的代碼貼出來,需要的朋友可以看看。
          sample1_1.jsp:
          <%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
          <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          <title>無標題文檔</title>
          <script language="javascript">
           var http_request = false;
           function send_request(url) {//初始化、指定處理函數、發送請求的函數
            http_request = false;
            //開始初始化XMLHttpRequest對象
            if(window.XMLHttpRequest) { //Mozilla 瀏覽器
             http_request = new XMLHttpRequest();
             if (http_request.overrideMimeType) {//設置MiME類別
              http_request.overrideMimeType('text/xml');
             }
            }
            else if (window.ActiveXObject) { // IE瀏覽器
             try {
              http_request = new ActiveXObject("Msxml2.XMLHTTP");
             } catch (e) {
              try {
               http_request = new ActiveXObject("Microsoft.XMLHTTP");
              } catch (e) {}
             }
            }
            if (!http_request) { // 異常,創建對象實例失敗
             window.alert("不能創建XMLHttpRequest對象實例.");
             return false;
            }
            http_request.onreadystatechange = processRequest;
            // 確定發送請求的方式和URL以及是否同步執行下段代碼
            http_request.open("GET", url, true);
            http_request.send(null);
           }
           // 處理返回信息的函數
              function processRequest() {
                  if (http_request.readyState == 4) { // 判斷對象狀態
                      if (http_request.status == 200) { // 信息已經成功返回,開始處理信息
                          alert(http_request.responseText);
                      } else { //頁面不正常
                          alert("您所請求的頁面有異常。");
                      }
                  }
              }
           function userCheck() {
            var f = document.form1;
            var username = f.username.value;
            if(username=="") {
             window.alert("用戶名不能為空。");
             f.username.focus();
             return false;
            }
            else {
             send_request('sample1_2.jsp?username='+username);
            }
           }
          </script>
          <link href="css/style.css" rel="stylesheet" type="text/css">
          </head>

          <body>
          <form name="form1" action="" method="post">
          用戶名:<input type="text" name="username" value="">&nbsp;
          <input type="button" name="check" value="唯一性檢查" onClick="userCheck()">
          <input type="submit" name="submit" value="提交">
          </form>
          <!--span style="cursor: pointer; text-decoration: underline" onclick="send_request('2.jsp?username=educhina')">Send a request</span-->
          </body>
          </html>

          sample1_2.jsp:
          <%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
          <%
          String playPos = request.getParameter("playPos");
          if("pos_1".equals(playPos)) out.print("用戶名已經被注冊,請更換一個用戶名。");
          else out.print("用戶名尚未被使用,您可以繼續。");
          %>

          sample2_1.jsp:
          <%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
          <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          <title>無標題文檔</title>
          <script language="javascript">
           var http_request = false;
           var currentPos = null;
           function send_request(url) {//初始化、指定處理函數、發送請求的函數
            http_request = false;
            //開始初始化XMLHttpRequest對象
            if(window.XMLHttpRequest) { //Mozilla 瀏覽器
             http_request = new XMLHttpRequest();
             if (http_request.overrideMimeType) {//設置MiME類別
              http_request.overrideMimeType('text/xml');
             }
            }
            else if (window.ActiveXObject) { // IE瀏覽器
             try {
              http_request = new ActiveXObject("Msxml2.XMLHTTP");
             } catch (e) {
              try {
               http_request = new ActiveXObject("Microsoft.XMLHTTP");
              } catch (e) {}
             }
            }
            if (!http_request) { // 異常,創建對象實例失敗
             window.alert("不能創建XMLHttpRequest對象實例.");
             return false;
            }
            http_request.onreadystatechange = processRequest;
            // 確定發送請求的方式和URL以及是否同步執行下段代碼
            http_request.open("GET", url, true);
            http_request.send(null);
           }
           // 處理返回信息的函數
              function processRequest() {
                  if (http_request.readyState == 4) { // 判斷對象狀態
                      if (http_request.status == 200) { // 信息已經成功返回,開始處理信息
                          //alert(http_request.responseText);
              document.getElementById(currentPos).innerHTML = http_request.responseText;
                      } else { //頁面不正常
                          alert("您所請求的頁面有異常。");
                      }
                  }
              }
           //顯示部門下的崗位
           function showRoles(obj) {
            document.getElementById(obj).parentNode.style.display = "";
            document.getElementById(obj).innerHTML = "正在讀取數據..."
            currentPos = obj;
            send_request("sample2_2.jsp?playPos="+obj);
           }
          </script>
          <link href="css/style.css" rel="stylesheet" type="text/css">
          </head>

          <body>
          <table width="200" border="0" cellspacing="0" cellpadding="0">
              <tr>
                  <td height="20"><a href="javascript:void(0)" onClick="showRoles('pos_1')">經理室</a></td>
              </tr>
              <tr style="display:none">
                  <td height="20" id="pos_1">&nbsp;</td>
              </tr>
              <tr>
                  <td height="20"><a href="javascript:void(0)" onClick="showRoles('pos_2')">開發部</a></td>
              </tr>
              <tr style="display:none ">
                  <td id="pos_2" height="20">&nbsp;</td>
              </tr>
          </table>
          <!--a href="javascript:void(0)" onClick="showRoles('pos_1')">測試</a-->
          <!--span style="cursor: pointer; text-decoration: underline" onclick="send_request('2.jsp?username=educhina')">Send a request</span-->
          </body>
          </html>

          sample2_2.jsp:
          <%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
          <%
          String playPos = request.getParameter("playPos");
          if("pos_1".equals(playPos)) out.print("&nbsp;&nbsp;總經理<br>&nbsp;&nbsp;副總經理");
          else if("pos_2".equals(playPos)) out.println("&nbsp;&nbsp;總工程師<br>&nbsp;&nbsp;軟件工程師");
          %>

          posted @ 2005-11-23 20:26 Dion 閱讀(790) | 評論 (0)編輯 收藏

               摘要: http://www.aygfsteel.com/eamoi/archive/2005/10/31/17489.html AJAX開發簡略   文檔說明   參與人員:   作者 網名 聯絡 柯自聰 eamoi   educhina ...  閱讀全文
          posted @ 2005-11-23 20:25 Dion 閱讀(595) | 評論 (0)編輯 收藏

               摘要: ASP服務 ASP是英文Application Service Provider的縮寫,通常中文譯為應用服務提供商,它是指配置、租賃和管理應用解決方案,為商業、個人提供服務的專業化服務公司。通俗地說,ASP是一種業務租賃模式,企業用戶可以直接租用ASP的計算機及軟件系統進行自己的業務管理,從而節省一大筆用于IT產品技術購買和運行的資金。 在國外,ASP最早出現于1998年,是伴隨著互聯...  閱讀全文
          posted @ 2005-11-23 20:23 Dion 閱讀(635) | 評論 (0)編輯 收藏

               摘要: (轉)ASP的行業介紹   一、ASP的概念     1、 幾個比喻    想吃雞蛋,用不著買只母雞回家,想喝牛奶,也不需要牽一頭奶牛回家。同理,在互聯網時代,通過互聯網,企業日常的生產、經營、管理過程中使用的應用服務都可以讓別人幫你打點,你可以節省時間和人力,他們向你收取租金,他們就是ASP...  閱讀全文
          posted @ 2005-11-23 20:22 Dion 閱讀(715) | 評論 (0)編輯 收藏

          ASP英文全稱為Application Service Provider,中文譯為應用服務供應商。 這是隨著Internet革命將人類從工業經濟時代推向電子商務時代,并重塑信息技術(Information Technology,簡稱IT)產業的未來發展方向所應運而生的一種嶄新的產品及服務模式。

          ASP的本質在于:這種應用,從所需的硬件平臺到應用軟件、企業內部資源管理和業務流程的處理,不是發生在企業本地的實施上,而是由特定的供應商提供,并由供應商進行維護、管理及更新,企業(ASP的用戶)通過租賃、承包等方式獲得服務。

          因此,ASP產生和發展的前提條件主要基于以下IT技術的成熟:
           
          Internet
          的普及:Internet逐步深入人們生活,大量的基于Web的解決方案不斷涌現,這些都使得遠程的基于主機的應用方案成為可能。
           
          帶寬不斷增大和價格不斷下降:增長的通信性能和持續減少的帶寬費用,使主機上的應用程序可以通過Internet和瘦客戶機來訪問。
           
          客戶機/服務器環境下的可共享應用:在ASP概念中的遠程訪問,用戶早已經在客戶機/服務器環境下習以為常,這使得遠程訪問和共享應用成為可接受的一種業務模式
           
          瀏覽器成為廣泛接受的圖形界面應用程序:瀏覽器技術的的廣泛應用及開發為基于Web的計算和瘦客戶機的計算聚集了足夠的技術及人力資源,以及良好的用戶基礎。
           
          電子商務解決方案的潛力:先進的電子商務解決方案,與ASP的概念一起分享了許多棘手的業務和技術問題,例如系統的安全性和可靠性。所以,電子商務的巨大動力也在推動ASP的前進。

          幾年前,當應用服務提供商(ASP)剛剛出現時,它似乎是幫助企業投身數字時代的最佳選擇:ASP們開發、運行和維護商用軟件,企業只需按月或按年繳納租費,就可以獲得需要的應用軟件。然而,互聯網泡沫的破裂使ASP的成功如曇花一現,當大多數Start-up公司倒下后,ASP們似乎也偃旗息鼓了。

          究其原因,技術不成熟是關鍵因素。Yankee Group的分析家認為,“5年前,ASP技術還不成熟,它不能定制、不具備離線能力、不能與其他系統集成、缺少這樣或那樣的功能,因此ASP們難以逃生也就成為必然。”但現在情況不同了,一方面是技術的進步使客戶通過Internet訪問商用軟件變得更安全和容易;另一方面是全球經濟的不景氣促使企業再次把目光投向ASP,畢竟,與購買許可證和高昂的維護費用相比,按月或按年付費的軟件使用方式更能節省成本,至少在短時間內是如此。通常情況下,諸如OracleSAP等公司的大型軟件系統都需要有相當大的初期投資,用于軟件的購買、安裝和培訓,一旦投入使用,還必須支付維護和軟件升級費用。與此相反,如果向ASP租用軟件,所有這些投資都可以節省下來,企業所需要付出的不過是每月數百美元的租金而已,況且這筆錢完全可以納入企業的日常開支。

          目前的ASP主要針對企業市場,采用遠程租用的方式,所提供的服務可以是集成硬件、軟件和網絡技術來為大中小各類企業提供應用解決方案;也可以是安裝、配置、定做和管理定制的封裝應用軟件;有些ASP甚至可以提供商務處理咨詢和外包服務。  
          ASP
          不再試圖通過Internet提供為企業網設計的傳統客戶機/服務器應用,而是創建適合Internet傳送的應用。因此它能夠更好地提供可伸縮和定制的應用,更容易與其他系統集成。除了最初的標準軟件以一對多的方式租賃使用之外,新的ASP應用模式還增加了個性化的服務。個性化服務從某種意義上說更接近于傳統的應用軟件系統開發,用戶仍然要為軟件開發支付一筆可觀的開發費用,所不同的是系統賴以傳輸數據的載體是開放的Internet。目前國外有觀點認為,ASP最適合的應用領域是財務、電子商務和客戶關系管理;國內專家則認為,在人力資源管理上ASP也可以有所發揮。此外,新的信息傳輸技術的應用也為ASP彌補了Internet帶來的一些不足,比如VPN可以保證數據的安全性,有利于吸引一些對安全性有更高要求的用戶;寬帶技術則使更快的速度和更豐富的功能成為可能。
          從未來發展來看,影響ASP發展的主要有以下幾個因素
             
          1
          )通訊頻寬的限制
             
          ASP
          商業模式需要有充足的帶寬資源支持,目前我國的通訊基礎設施有了很大的發展,但是帶寬資源還沒到富余的程度,因此,頻寬資源可能會成為制約ASP發展的一個重要因素。
             
          2
          )網絡安全性
             
          網絡的安全性包括了兩層含義:一是技術上能夠抵御黑客的非法侵入,另一層更重要的含義是ASP商本身的職業操守達到一定的層次,顧客的商業秘密不會因ASP自身的原因而泄露。
             
          3
          )社會信用體系
             
          我們看到美國的ASP業發展迅速,應該看到他們多年積累的信用體系其實是ASP發展的關鍵動力。然而,反觀國內的企業,普遍缺乏信用觀念,這極大地增加了ASP用戶的交易成本和投資風險。
             
          4
          )品牌因素
            
          由于ASP這一商業模式本身需要很高的技術要求、安全要求和信用要求,ASP商的品牌因素也特別重要。 

          雖然技術是ASP成功的原動力之一,但是ASP的成功關鍵不僅在于先進技術和人力資源的掌握,也依賴于對相關業務流程和信息管理的行業經驗,因此目前的少數ASP所提供的功能遠不能滿足企業用戶的需要,無法達到真正的ASP所提供的功能。

          從市場前景來看,ASP已經占有了一席之地,它從根本上降低了客戶的TCO。對客戶來說,向ASP租用軟件的風險很小,按照Enterprise Applications Consulting公司的分析家的話來說“你不必購買永久許可而只在某些時候才使用軟件,你所買的就是你所需要的”。除此之外,租用軟件可以減少企業內部對IT人員的需求,甚至有可能取消企業的IT部門,因為有ASP替您維護和升級應用程序。盡管如此,仍然有相當的潛在客戶會擔心租用軟件可能面臨的問題:諸如無法讓第三方來替它處理有價值的數據;或者是擔心托管系統的安全問題以及被托管的系統能否與來自其他廠商的應用系統協同工作。這些技術上的問題都需要被妥善解決,同時也會成ASP技術繼續發展的原動力。但無論怎樣,隨著商用軟件復雜度的增加以及企業降低成本的需求,ASP模式將成為企業IT應用發展的大趨勢。

          以下是軟件公司為某電器有限公司定制的分銷體系解決方案,也許可以從中更深的了解到基于ASP的解決方案的魅力。  

          (1)信息化動因分析  
             
          公司成立于1994年,現有員工近千名,目前的產品主要有食品攪拌機、榨汁機、全自動豆漿機等,2000年其銷售額達1億元。作為一家制造型的企業,產品技術和研發是基礎,產品銷售則是最終目標,所以企業信息化的核心目標是:理順企業管理流程為銷售服務。  
             
          目前公司在全國有近1000個 銷售網點。以前在銷售環節上出的問題比較多,給公司造成了很大的損失。因此,公司制訂出一套規范的業務流程,來監督管理下屬的各地辦事處。改進流程的結果 是實行“兩級管理一級核算”的體制,總公司進行獨立核算。在各地的辦事處只負責銷售,記錄銷售費用,客戶與總公司直接結算。  
             
          這 種方式堵住了管理上漏洞,只是手工重復的勞動比較多。總公司和辦事處之間的信息交流,以前是通過電話、傳真、電子郵件方式實現的,各辦事處手工錄入的大量 數據傳到總公司后,匯總處理時仍然需要再次重復錄入,工作量極其繁重,處理效率非常低。同時,由于人工匯總存在較大的計算出錯可能性,因此上報給企業管理 層的銷售匯總數據的可靠性和及時性都比較差。而且在手工管理模式下,每周只能進行12次銷售匯總數據的統計和報告,無法實現對辦事處存貨、客戶應收帳款等明細數據的實時額度控制。  
           
          (2)
          分銷管理系統解決方案  
             
          針對目前存在的問題,軟件公司提出分銷系統的ASP模 式,即所有數據都集中在總公司的數據庫中,而辦事處只需要登錄進系統,在客戶端將所發生的數據按照系統模塊的要求輸入進去,系統將自動生成各種數據,并允 許相應級別的人實時查詢其相應權限下的所有相關數據。這種模式正好滿足其對眾多分子公司和辦事處的管理要求。同時在實施整個系統時,先將數據存放在軟件公 司的服務器上。在實施完成后,可以選擇兩種方式:一是自己建服務器和數據中心并承擔系統維護工作;二是租用軟件公司提供的網站和數據庫維護增值服務,完全 不再投入硬件和人員。  
            
          實 施系統管理之后,該公司的整體業務流程系統由業務管理子系統和財務管理子系統兩部分構成。業務管理子系統主要功能包括:客戶端電子商務功能、銷售過程管 理、庫存管理、應收帳款管理、各類計劃管理、商品檔案管理、客戶檔案管理、統計查詢、系統管理等;財務管理子系統主要功能為日常費用管理。該分銷管理系統 在 “用友偉庫企業分銷管理軟件”的基礎上進行了適量的二次開發。  
           
          (3)
          分銷管理系統效果評析  
            
          實 施了這套系統以后,以往許多無法解決的問題就迎刃而解。各地辦事處只要正確輸入貨物出入庫數據,系統平臺的總數據累計自動生成,與以往用手工合計的速度相 比有了很大的提升。各辦事處可以進入公司網站,在分銷系統平臺中本辦事處的界面進行操作,減少了運營費用。各地分公司和辦事處均可通過系統提供的業務處理 平臺將每日訂單、銷售、存貨等數據輸入系統,自動處理/生成各類銷售統計報表;管理層可根據不同的權限隨時了解銷售、產品庫存及資金情況,瀏覽系統提供的部分數據分析報告,為管理決策層提供更準確和及時的量化依據。  
             
          由于采用ASP運行模式,實現了異地商務集中管理。海菱公司不需要單獨構建昂貴的數據處理中心;分支機構無需安裝專用的客戶端軟件,采用標準瀏覽器上網即可使用該系統的全部功能,數據處理全部在數據中心完成和存儲,數據安全性高,操作簡單,系統維護成本低。

          posted @ 2005-11-23 20:22 Dion 閱讀(610) | 評論 (0)編輯 收藏

          轉自http://dev2dev.bea.com.cn/techdoc/2005110103.html


          Ajax簡介

          時間:2005-11-01
          作者:David Teare
          瀏覽次數: 1786
          本文關鍵字:ajaxdhtmldwr javascript
          文章工具
          推薦給朋友 推薦給朋友
          打印文章 打印文章

            作為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 @ 2005-11-23 12:53 Dion 閱讀(589) | 評論 (0)編輯 收藏

               摘要: 在Java2平臺企業版中應用異步JavaScript技術和XML(AJAX) ...  閱讀全文
          posted @ 2005-11-23 11:43 Dion 閱讀(1925) | 評論 (4)編輯 收藏

          轉載自TheServerSide網站,介紹使用Spring來創建Observer模式。
          http://www.theserverside.com/articles/article.tss?l=SpringLoadedObserverPattern
           

          This article describes an easy process of implementing the observer pattern in the Spring framework (Spring Core). Also discussed in this article are a few of the Spring Core classes as well as an easy way to start the Spring Framework in any project. Finally, this article shows developers and designers that the Spring framework is a great reason to continue design pattern advocacy in your projects.

          Recently, it seems when developers use the Spring framework to improve their projects they focus only on simple object oriented design techniques. Unfortunately some of the more brilliantly researched patterns are forgotten in place of a brilliant framework (Spring). Although the Factory Pattern and the Singleton Pattern are built into Spring, other patterns such as the Decorator Pattern, the Adapter Pattern, and the Observer Pattern are often forgotten because of the new ideas Spring has to offer. Fortunately, design patterns and the Spring framework can exist in the same application. In this article I show how the commonly used Observer Pattern fits nicely in the Spring Framework.

          Observer Pattern

          The Observer Pattern is also known as a publisher and subscriber design pattern. The pattern is useful when you have one publisher and many subscribers (one-to-many) that are interested in the publisher's state or messages. Additionally, interested subscribers have the ability to register and unregister as they please. Lastly, subscribers are notified of the publisher's messages automatically (that is, by no effort of their own). Figure 1 is an example of a typical observer pattern.

          Figure 1. Observer Pattern


          I chose to use a more widely accepted diagram to describe the Observer Pattern so you will notice that the aforementioned publisher is actually the Subject in this diagram. The subscriber is the Observer in the diagram. The intimate details of the Observer Pattern are far outside of the scope of this article, but a note worthy topic is how the Spring framework can be used to leverage good object oriented design techniques while creating the concrete classes of this pattern.

          A normal concreteObserver class is required to have code similar to this constructor (or a similar “setter” method to achieve the registering of the Observer with the Subject):

          public concreteObserver(Subject s) {
          	s.addListener(this);
          }
          

          Below you will see how the Spring framework wires the two concrete classes together with XML and not with code inside the classes. Ultimately, this allows the developer to avoid any unnecessary coupling of the concrete classes.

          Spring Considerations

          Since this article covers only the most simple implementation of the observer pattern, I utilize only the required Spring framework jars. At a minimum you need to have the spring-core.jar, the spring-context.jar, and the spring-beans.jar from the Spring framework distribution. Also to avoid any run time errors you need the commons-logging.jar from the Apache Commons project in your class path.

          Each of these jars provide a specific role that make using the Spring framework possible. First is the spring-core.jar; this jar is required for all Spring applications. It includes Spring's dependency injection classes as well as other classes that are used to create Spring beans. The spring-context.jar contains the ApplicationContext interface. This interface is used to start the Spring framework in my included example project.

          The last Spring jar is the spring-beans.jar. It contains the DesposibleBean interface which the FileSystemXmlApplicationContext bean sub-interfaces. I do not directly use the DesposibleBean interface but I use the FileSystemXmlApplicationContext bean to located the XML file used to configure the Spring framework. The code that implements these classes is shown in Listing 6.

          Wiring The Observer Pattern with Spring

          To illustrate the Observer Pattern concretely, I chose to create a Town Crier class that sends messages to any registered Town Resident class. To keep this example simple, I developed the same interfaces shown in Figure 1, but the concrete classes are TownCrier and TownResident. All four of these classes are shown in Listings 1 through 4.

          After I created the TownCrier (Listing 3) and two TownResident (Listing 4) classes I created an incomplete version the ObserverContext.xml file (Listing 5). This file contains the Spring definitions of the concrete implementation beans. Since this example is simple, I chose not to use any of the more complex attributes of the bean tag.

          Typical Bean tags for the shown classes:

          	<bean id="townCrier" class="springobserver.TownCrier"/>
          	<bean id="townResident1" class="springobserver.TownResident"/>
          	<bean id="townResident1" class="springobserver.TownResident2"/>
          

          At this point, I was able to run my ExampleRun class (Listing 6), but nothing eventful actually happened. This is because the TownResident classes were not “wired” into the TownCrier class.

          To perform the wiring of the Observer Pattern I chose to use Spring's MethodInvokingFactoryBean class. This process is a very simple way of calling a method on a class and ultimately passing a parameter into method. In this example, the parameter is the bean definition of a townResident. A snapshot of this bean definition is:

          <bean id="registerTownResident1" 
          class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
              <property name="targetObject"><ref local="townCrier"/></property>
              <property name="targetMethod"><value>addListener</value></property>
              <property name="arguments">
              <list>
                <ref bean="townResident1"/>
              </list>
              </property>
          </bean>
          

          As you can see, the targetObject is the townCrier bean, the targetMethod is the addListener method and the argument is the townResident1 bean. This configuration is the only code needed to compose the concrete implementations of the TownCrier with TownResident class.

          Now that I have the beans wired together using the MethodInvokingFactoryBean class, I can run my ExampleRun class and see that my TownResident classes are receiving messages from the TownCrier class. Results shown in Example 1.

          Conclusion

          A few lessons learned in this article include a simple way to start the Spring framework, how to use the MethodInvokingFactoryBean, and an efficient implementation the Observer Pattern in the Spring framework. Since this is a minimal approach to the Spring framework, I was able to show the relationship between the ApplicationContext and it's implementation FileSystemXmlApplicationContext class. This process for starting Spring applications is a very easy way to leverage an incredible framework.

          Part of this framework is the MethodInvokingFactoryBean. When using it you are free to employ any parameter available to you such as an Integer, a String, or in our case, another Spring bean. By allowing you to expose methods in your context xml files you can be as flexible as you can dream. This article has covered the addListener() method of the Observer Pattern. I would like to extend a challenge to you to figure out how to implement the removeListener() method using strictly the Spring framework.

          Lastly, the Observer Pattern is a common and very useful pattern. The practices shown in this article provide an example of how the concrete implementation of the Observer interface can be developed with no additional coupling to the concrete implementation of the Subject interface. This feature of Spring encourages good object oriented design techniques. As a final note, there is really no reason developers and designers can not find ways to marry proven design patterns with beautifully developed frameworks.

          Listing 1. The Observer Interface
          package springobserver;
          public interface Observer {
            public void update(String messageText);
          }
          
          Listing 2. The Subject Interface
          package springobserver;
          public interface Subject {
            public void addListener(Observer o);
            public void removeListener(Observer o);
            public void notifyListeners();
          }
          
          Listing 3. The Town Crier
          package springobserver;
          
          import java.util.ArrayList;
          import java.util.Iterator;
          import java.util.List;
          
          public class TownCrier implements Subject {
          
          	private List townResident = new ArrayList();
          	private String messageText;
          
          	// this message is added so I can give 
          	// this class a reason to call notifyListener.
          	public void setMessage(String message){
          		System.out.println("I'm the Town Crier and " +
          				"I've got a message: " + message);
          		this.messageText = message;
          		this.notifyListeners();
          	}
          	
          	public void addListener(Observer o) {
          		this.townResident.add(o);
          	}
          
          	public void removeListener(Observer o) {
          		if (this.townResident.contains(o)){
          			this.townResident.remove(o);
          		}
          	}
          
          	
          	// call the update method on 
          	// each observer (town resident)
          	public void notifyListeners() {
          		for (Iterator iter = townResident.iterator(); iter.hasNext();) {
          			Observer listener = (Observer) iter.next();
          			listener.update(messageText);
          		}
          	}
          
          }
          
          Listing 4. The Town Residents
          package springobserver;
          
          public class TownResident implements Observer {
          	public void update(String messageText) {
          		System.out.println("Greetings my name is: " + this);
          		System.out.println("I heard: " + messageText);
          	}
          
          -------- new class --------
          package springobserver;
          
          public class TownResident2 implements Observer {
          	public void update(String messageText) {
          		System.out.println("Greetings my name is: " + this);
          		System.out.println("I heard: " + messageText);
          	}
          
          }
          Listing 5. The Application Context XML (ObserverContext.xml)
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
          "http://www.springframework.org/dtd/spring-beans.dtd">
          
          <beans>
          	<!-- This bean is the town crier.  
          	He's responsible for notifying all town residents that are interested in his message -->
          	<bean id="townCrier" class="springobserver.TownCrier"/>
          	
          	<!-- this bean is a town resident interested in the town criers messages -->
          	<bean id="townResident1" class="springobserver.TownResident"/>          
                 
          	<!-- this bean is another town resident interested in the town criers messages -->
          	<bean id="townResident2" class="springobserver.TownResident2"/>
              
              
               <!-- this is a method invoking bean that registers the first town resident with
                    with the town crier -->   
              <bean id="registerTownResident1" 
                class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                <property name="targetObject"><ref local="townCrier"/></property>
                <property name="targetMethod"><value>addListener</value></property>
                <property name="arguments">
                <list>
                  <ref bean="townResident1"/>
                </list>
                </property>
              </bean>
              
              
               <!-- this is a method invoking bean that registers the second town 
                    resident with the town crier -->   
              <bean id="registerTownResident2" 
                class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                <property name="targetObject"><ref local="townCrier"/></property>
                <property name="targetMethod"><value>addListener</value></property>
                <property name="arguments">
                <list>
                  <ref bean="townResident2"/>
                </list>
                </property>
              </bean>         
           
           </beans>
          
          Listing 6. Example Run
          package springobserver;
          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.FileSystemXmlApplicationContext;
          
          public class ExampleRun {
          	public static void main(String[] args) {
          		// launch the spring frame work.
          		ApplicationContext ctx = new FileSystemXmlApplicationContext(
          				"/config/ObserverContext.xml");
          		// grab the Town Crier out of the spring 
          		// framework and send a message too all observers
          		TownCrier crier = (TownCrier) ctx.getBean("townCrier");
          		crier.setMessage("It is 1 O'Clock and all is well!");
          	}
          }
          
          Example 1. System Output
          I'm the Town Crier and I've got a message: It is 1 O'Clock and all is well!
          Greetings my name is: springobserver.TownResident@80fa6f
          I heard: It is 1 O'Clock and all is well!
          Greetings my name is: springobserver.TownResident2@1b9ce4b
          I heard: It is 1 O'Clock and all is well!
          

          posted @ 2005-11-22 14:17 Dion 閱讀(778) | 評論 (0)編輯 收藏

          僅列出標題
          共5頁: 上一頁 1 2 3 4 5 
          主站蜘蛛池模板: 通化县| 樟树市| 嘉祥县| 宁乡县| 邢台市| 祁连县| 婺源县| 永登县| 阳高县| 兰考县| 平远县| 潞西市| 澎湖县| 庆阳市| 南皮县| 张家口市| 苏尼特左旗| 东源县| 广东省| 桦南县| 尤溪县| 方山县| 遵义市| 盱眙县| 紫云| 台前县| 饶阳县| 井冈山市| 大同县| 益阳市| 吕梁市| 昌邑市| 上林县| 南投市| 宣恩县| 定安县| 彭山县| 仁寿县| 万州区| 深州市| 繁峙县|