posts - 66,  comments - 40,  trackbacks - 0
          概述

          這篇文章闡述了使用開源項(xiàng)目DWR(直接Web遠(yuǎn)程控制)和AJAX(異步JavaScript和XML)的概念來(lái)提高Web應(yīng)用的可用性。作者一步步來(lái)展示DWR如何使得AJAX的應(yīng)用既簡(jiǎn)單又快捷。(1600字;2005年6月20日)

          AJAX,或者說(shuō)是異步JavaScript和XML,描述了一種使用混合了HTML(或XHTML)和層疊樣式表作為表達(dá)信息,來(lái)創(chuàng)建交互式的Web應(yīng)用的開發(fā)技術(shù);文檔對(duì)象模型(DOM),JavaScript,動(dòng)態(tài)地顯示和與表達(dá)信息進(jìn)行交互;并且,XMLHttpRequest對(duì)象與Web服務(wù)器異步地交換和處理數(shù)據(jù)。

          因特網(wǎng)上許多例子展示了在一個(gè)HTML文件內(nèi)部使用XMLHttpRequest與服務(wù)器端進(jìn)行交互的必要的步驟。當(dāng)手工地編寫和維護(hù)XMLHttpRequest代碼時(shí),開發(fā)者必須處理許多潛在的問(wèn)題,特別是類似于跨瀏覽器的DOM實(shí)現(xiàn)的兼容性這樣的問(wèn)題。這將會(huì)導(dǎo)致在編碼和調(diào)試Javascript代碼上面花費(fèi)數(shù)不清的時(shí)間,這顯然對(duì)開發(fā)者來(lái)說(shuō)很不友好。

          DWR(直接Web遠(yuǎn)程控制)項(xiàng)目是在Apache許可下的一個(gè)開源的解決方案,它供給那些想要以一種簡(jiǎn)單的方式使用AJAX和XMLHttpRequest的開發(fā)者。它具有一套Javascript功能集,它們把從HTML頁(yè)面調(diào)用應(yīng)用服務(wù)器上的Java對(duì)象的方法簡(jiǎn)化了。它操控不同類型的參數(shù),并同時(shí)保持了HTML代碼的可讀性。

          DWR不是對(duì)一個(gè)設(shè)計(jì)的插入,也不強(qiáng)迫對(duì)象使用任何種類的繼承結(jié)構(gòu)。它和servlet框架內(nèi)的應(yīng)用配合的很好。對(duì)缺少DHTML編程經(jīng)驗(yàn)的開發(fā)者來(lái)說(shuō),DWR也提供了一個(gè)JavaScript庫(kù)包含了經(jīng)常使用的DHTML任務(wù),如組裝表,用item填充select下拉框,改變HTML元素的內(nèi)容,如<div>和<span>
          DWR網(wǎng)站是詳盡的并且有大量的文檔,這也是這篇文章的基礎(chǔ)。一些例子用來(lái)展示DWR如何使用和用它的庫(kù)可以完成什么樣的工作。

          這篇文章讓讀者看到了一個(gè)使用了DWR的Web應(yīng)用是如何一步步建立的。我會(huì)展示創(chuàng)建這個(gè)簡(jiǎn)單的示例應(yīng)用的必要的細(xì)節(jié),這個(gè)應(yīng)用是可下載的并且可以在你的環(huán)境中布署來(lái)看看DWR如何工作。
          注意:找到有關(guān)AJAX的信息并不困難;網(wǎng)頁(yè)上有幾篇文章和博客的條目涵蓋了這個(gè)主題,每一個(gè)都試圖指出和評(píng)論這個(gè)概念的不同的方面。在資源部分,你會(huì)找到一些有趣的指向示例和文章的鏈接,來(lái)學(xué)習(xí)AJAX的更多的內(nèi)容。

          示例應(yīng)用
          這篇文章使用的示例應(yīng)用模擬了多倫多的一個(gè)公寓出租搜索引擎。用戶可以在搜索前選擇一組搜索標(biāo)準(zhǔn)。為了提高交互性,AJAX中以下兩種情況下使用:
          ·應(yīng)用通告用戶配合他的選擇會(huì)返回多少搜索結(jié)果。這個(gè)數(shù)字是實(shí)時(shí)更新的-使用AJAX-當(dāng)用戶選擇的臥室和浴室的數(shù)量,或者價(jià)格范圍變化時(shí)。當(dāng)符合標(biāo)準(zhǔn)的搜索結(jié)果沒(méi)有或太多時(shí),用戶就沒(méi)有必要點(diǎn)擊搜索按紐。
          ·數(shù)據(jù)庫(kù)查詢并取回結(jié)果是由AJAX完成的。當(dāng)用戶按下顯示結(jié)果按鈕時(shí),數(shù)據(jù)庫(kù)執(zhí)行搜索。這樣,應(yīng)用看起來(lái)更具響應(yīng)了,而整個(gè)頁(yè)面不需要重載來(lái)顯示結(jié)果。

          數(shù)據(jù)庫(kù)
          我們使用的數(shù)據(jù)庫(kù)是HSQL,它是一種占用資源很小的Java SQL數(shù)據(jù)庫(kù)引擎,可以不需要安裝和配置的與Web應(yīng)用捆綁在一起。一個(gè)SQL文件被用來(lái)在Web應(yīng)用的上下文啟動(dòng)時(shí)創(chuàng)建一個(gè)內(nèi)存中的表并添加一些記錄。

          Java類
          應(yīng)用包含了兩個(gè)主要的類叫Apartment和ApartmentDAO。Apartment.java類是一個(gè)有著屬性和getter/setter方法的簡(jiǎn)單的Java類。ApartmentDAO.java是數(shù)據(jù)訪問(wèn)類,用來(lái)查詢數(shù)據(jù)庫(kù)并基于用戶的搜索標(biāo)準(zhǔn)來(lái)返回信息。ApartmentDAO類的實(shí)現(xiàn)的直接了當(dāng)?shù)?它直接使用了Java數(shù)據(jù)庫(kù)聯(lián)接調(diào)用來(lái)得到公寓的總數(shù)和符合用戶請(qǐng)求的可用公寓的列表。

          DWR配置和使用
          設(shè)置DWR的使用是簡(jiǎn)單的:將DWR的jar文件拷入Web應(yīng)用的WEB-INF/lib目錄中,在web.xml中增加一個(gè)servlet聲明,并創(chuàng)建DWR的配置文件。DWR的分發(fā)中需要使用一個(gè)單獨(dú)的jar文件。你必須將DWR servlet加到應(yīng)用的WEB-INF/web.xml中布署描述段中去。
          ????<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>dwr-invoker</servlet-name>
          ????????<url-pattern>/dwr/*</url-pattern>
          ????</servlet-mapping>


          一個(gè)可選的步驟是設(shè)置DWR為調(diào)試模式—象上面的例子那樣—在servlet描述段中將debug參數(shù)設(shè)為true。當(dāng)DWR在調(diào)試模式時(shí),你可以從HTMl網(wǎng)頁(yè)中看到所有的可訪問(wèn)的Java對(duì)象。包含了可用對(duì)象列表的網(wǎng)頁(yè)會(huì)出現(xiàn)在/WEBAPP/dwr這個(gè)url上,它顯示了對(duì)象的公共方法。所列方法可以從頁(yè)面中調(diào)用,允許你,第一次,運(yùn)行服務(wù)器上的對(duì)象的方法。下圖顯示了調(diào)試頁(yè)的樣子:

          image
          調(diào)試頁(yè)

          現(xiàn)在你必須讓DWR知道通過(guò)XMLHttpRequest對(duì)象,什么對(duì)象將會(huì)接收請(qǐng)求。這個(gè)任務(wù)由叫做dwr.xml的配置文件來(lái)完成。在配置文件中,定義了DWR允許你從網(wǎng)頁(yè)中調(diào)用的對(duì)象。從設(shè)計(jì)上講,DWR允許訪問(wèn)所有公布類的公共方法,但在我們的例子中,我們只允許訪問(wèn)幾個(gè)方法。下面是我們示例的配置文件:
          <dwr>
          ????<allow>
          ????????<convert converter="bean" match="dwr.sample.Apartment"/>
          ????????<create creator="new" javascript="ApartmentDAO" class="dwr.sample.ApartmentDAO">
          ????????????<include method="findApartments"/>
          ????????????<include method="countApartments"/>
          ????????</create>
          ????</allow>
          </dwr>


          上面的文件實(shí)現(xiàn)了我們例子中的兩個(gè)目標(biāo)。首先,<convert>標(biāo)記告訴DWR將dwr.sample.Apartment對(duì)象的類型轉(zhuǎn)換為聯(lián)合數(shù)組,因?yàn)椋鲇诎踩脑颍珼WR默認(rèn)的不會(huì)轉(zhuǎn)換普通bean。第二,<create>標(biāo)記讓DWR暴露出dwr.sample.ApartmentDAO類給JavaScript調(diào)用;我們?cè)陧?yè)面中使用JavaScript文件被javascript屬性定義。我們必須注意<include>標(biāo)記,它指明了dwr.sample.ApartmentDAO類的哪些方法可用。

          HTML/JSP代碼
          配置完成后,你就可以啟動(dòng)你的Web應(yīng)用了,這時(shí)DWR會(huì)為從你的HTML或Java服務(wù)器端頁(yè)面(JSP)上調(diào)用所需方法作好準(zhǔn)備,并不需要你創(chuàng)建JavaScript文件。在search.jsp文件中, 我們必須增加由DWR提供的JavaScript接口,還有DWR引擎,加入以下三行到我們的代碼中:

          ??<script src='dwr/interface/ApartmentDAO.js'></script>
          ??<script src='dwr/engine.js'></script>
          ??<script src='dwr/util.js'></script>


          我們注意到當(dāng)用戶改變搜索標(biāo)準(zhǔn)時(shí),這是AJAX在示例程序中的首次應(yīng)用;正如他所看到的,當(dāng)標(biāo)準(zhǔn)改變時(shí),可用的公寓數(shù)量被更新了。我創(chuàng)建了兩個(gè)JavaScript函數(shù):當(dāng)某一個(gè)選擇下拉框中的值變化時(shí)被調(diào)用。ApartmentDAO.countApartments()函數(shù)是最重要的部分。最有趣的是第一個(gè)參數(shù), loadTotal()函數(shù),它指明了當(dāng)接收到服務(wù)端的返回時(shí)DWR將會(huì)調(diào)用的JavaScript方法。loadTotal于是被調(diào)用來(lái)在HTML頁(yè)面的<div>中顯示結(jié)果。下面是在這個(gè)交互場(chǎng)景中所使用到的JavaScript函數(shù):

          function updateTotal() {
          ????$("resultTable").style.display = 'none';
          ????var bedrooms = document.getElementById("bedrooms").value;
          ????var bathrooms = document.getElementById("bathrooms").value;
          ????var price = document.getElementById("price").value;
          ????ApartmentDAO.countApartments(loadTotal, bedrooms, bathrooms, price);
          }

          function loadTotal(data) {
          ????document.getElementById("totalRecords").innerHTML = data;
          }


          很明顯,用戶想看到符合他的搜索條件的公寓列表。那么,當(dāng)用戶對(duì)他的搜索標(biāo)準(zhǔn)感到滿意,并且總數(shù)也是有效的話,他會(huì)按下顯示結(jié)果的按紐,這將會(huì)調(diào)用updateResults() JavaScript方法:

          function updateResults() {
          ????
          ????DWRUtil.removeAllRows("apartmentsbody");
          ????var bedrooms = document.getElementById("bedrooms").value;
          ????var bathrooms = document.getElementById("bathrooms").value;
          ????var price = document.getElementById("price").value;
          ????ApartmentDAO.findApartments(fillTable, bedrooms, bathrooms, price);
          ????$("resultTable").style.display = '';
          }

          function fillTable(apartment) {
          ????DWRUtil.addRows("apartmentsbody", apartment, [ getId, getAddress, getBedrooms, getBathrooms, getPrice ]);
          }


          updateResults()方法清空了存放搜索返回結(jié)果的表域,從用戶界面上獲取所需參數(shù),并且將這些參數(shù)傳給DWR創(chuàng)建的ApartmentDAO對(duì)象。然后數(shù)據(jù)庫(kù)查詢將被執(zhí)行,fillTable()將會(huì)被調(diào)用,它解析了DWR返回的對(duì)象(apartment),然后將其顯示到頁(yè)面中(apartmentsbody)。

          安全因素
          為了保持示例的簡(jiǎn)要,ApartmentDAO類盡可能的保持簡(jiǎn)單,但這樣的一個(gè)類通常有一組設(shè)置方法來(lái)操作數(shù)據(jù),如insert(), update()和delete()。DWR暴露了所有公共方法給所有的HTML頁(yè)面調(diào)用。出于安全的原因,像這樣暴露你的數(shù)據(jù)訪問(wèn)層是不明智的。開發(fā)者可以創(chuàng)建一個(gè)門面來(lái)集中所有JavaScript函數(shù)與底層業(yè)務(wù)組件之間的通信,這樣就限制了過(guò)多暴露的功能。

          結(jié)論
          這篇文章僅僅讓你在你的項(xiàng)目中使用由DWR支持的AJAX開了個(gè)頭。DWR讓你集中注意力在如何提高你的應(yīng)用的交互模型上面,消除了編寫和調(diào)試JavaScript代碼的負(fù)擔(dān)。使用AJAX最有趣的挑戰(zhàn)是定義在哪里和如何提高可用性。DWR負(fù)責(zé)了操作Web頁(yè)面與你的Java對(duì)象之間的通信,這樣就幫助你完全集中注意力在如何讓你的應(yīng)用的用戶界面更加友好,
          我想感謝Mircea Oancea和Marcos Pereira,他們閱讀了這篇文章并給予了非常有價(jià)值的返匱。
          posted on 2006-09-08 13:37 happytian 閱讀(98) 評(píng)論(0)  編輯  收藏

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


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

          Welcome here, my friend!

          常用鏈接

          留言簿(12)

          隨筆檔案(66)

          文章分類

          文章檔案(63)

          web

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 89369
          • 排名 - 647

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 清原| 银川市| 广德县| 洪江市| 于田县| 西充县| 小金县| 芒康县| 九龙县| 遂宁市| 视频| 河北省| 南皮县| 同江市| 武强县| 雷山县| 筠连县| 巢湖市| 宝坻区| 田东县| 崇阳县| 和龙市| 冕宁县| 达尔| 绍兴市| 邛崃市| 瑞丽市| 元朗区| 桓台县| 毕节市| 建平县| 胶南市| 郸城县| 富顺县| 马龙县| 陇南市| 万源市| 阆中市| 安义县| 贵溪市| 鸡泽县|