1.DWR是一個Java開源庫,幫助你實現Ajax網站,它可以讓你在瀏覽器中的Javascript代碼調用Web服務器上的Java,就像在Java代碼就在瀏覽器中一樣。
2.DWR主要包括兩部分:
在服務器上運行的Servlet來處理請求並把結果返回瀏覽器。
運行在瀏覽器上的Javascript,可以發送請求,並動態改變頁面。DWR會根據你的Java類動態的生成Javascript代碼。這些代碼的魔力是讓你感覺整個Ajax調用都是在瀏覽器上發生的,但事實上是服務器執行了這些代碼,DWR負責數據的傳遞和轉換。
2.1這種Java和Javascript之間的遠程調用會讓DWR用戶感覺像是曾經習慣使用的RMI或SOAP的RPC機制。而且這一過程還不需要額外的瀏覽器插件。
2.2Java是同步的,而Ajax是異步的。所以當你調用一個遠程方法時,你要給DWR一個回調函數,當數據從網絡上回來時,DWR會調用這個函數。
3.DWR動態爲服務端AjaxService類(Java)生成了一個相應的客戶端AjaxService類(Javascript)。這個類被 eventHandler調用。DWR就會去處理整個遠程調用的細節,包括在Javascript和Java之間轉換參數和返回值。然後在這裏例子中,它會執行你提供的回調函數(populateList),這個函數再利用DWR提供的工具函數來更改頁面內容。
4.開發流程
如何開始用DWR
4.1. 安裝DWR的Jar包
下載dwr.jar和commons-logging.jar文件。把它放到你的webapp的WEB-INF/lib目錄下。那裏可能已經有很多其他的jar文件了。
4.2. 編輯配置文件
需要把下面的代碼加到WEB-INF/web.xml文件中。
<!-- 配置DWR的請求處理類 -->
<servlet>
<servlet-name>dwr_invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr_invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
在WEB-INF目錄下的web.xml旁邊創建一個dwr.xml文件。可以從最簡單的配置開始:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEdwrPUBLIC"-//GetAheadLimited//DTD Direct Web Remoting 3.0//EN""http://getahead.org/dwr/dwr30.dtd">
<dwr>
<allow><!--allow定義了DWR能夠創建和轉換的類 -->
<createcreator="new"javascript="DwrDate"><!--create爲創建器 -->
<paramname="class"value="java.util.Date"></param>
</create>
<createcreator="new"javascript="DwrService">
<paramname="class"value="cn.jbit.dwr.service.DwrService"></param>
<!-- 設定暴露給客戶端的方法-->
<includemethod="getDwrBean"></include>
</create>
<!-- 設定Bean 轉換器-->
<convertconverter="bean"match="cn.jbit.dwr.service.DwrBean"></convert>
</allow>
</dwr>
DWR配置文件定義了那些DWR會創建提供遠程調用的Javascript類。在上面的例子中我們定義了兩個類來提供遠程調用,併爲其提供的Javascript類的名字。
在上面我們使用了new創建器,它會調用沒有參數的構造函數來創建實例,但是所有JavaBean必須有這一構造函數。還要注意DWR有一些限制:
不要出現Javascript保留關鍵字;和保留關鍵字同名的函數指定被排除。
Javascript方法重載是不支持的,所以儘量不要再Java中使用。
4.2.1解釋
<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAheadLimited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd">
<dwr>
<init><!--用來聲明創造bean的類和轉換bean的類。-->
<creator id="..."class="..." />
<converter id="..." class="..."/>
</init>
<!--allow定義了DWR能夠創建和轉換的類 -->
<allow>
<!--創建器-->
<create creator=".<!--值有new和none new是新創建一個類:none適用於調用靜態對象或存在的對象-->." javascript=".<!--在客戶端創建的javascript對象命名-->." scope=".<!--作用域默認page-->."> <param name=".<!--參數-->."value="..."/>
<include method=".<!--定義允許訪問的方法列表,其他默認不允許訪問-->."/>
<exclude method=".<!--定義不允許訪問的方法列表,其他默認允許訪問-->."/>
</create>
<convert converter=".<!--類型轉換器-->." match="..."/>
</allow>
<signatures> ... </signatures><!--使用反射來找出在轉換時應該用那種類型。-->
</dwr>
--如果需要進行JavaBean對象和JavaScript對象之間的轉換,需要在dwr.xml中顯式設置
<convert converter="bean"match="www.dwrdemo.DwrBean">
<param name=".<!--參數-->."value="..."/>
</convert>
5. 訪問下面的URL
http://localhost:8080/[YOUR-WEBAPP]/dwr/
你可以看見一個頁面,裏面有第二步中的類。接着往裏點,你會看到所有可以調用的方法列表。這個頁面是動態生成用來測試的例子。
另一種方式是看剛纔的頁面中提供的代碼:
到 http://localhost:8080/\[YOUR-WEBAPP\]/dwr/ 頁面,點擊你的類。查看源碼,找到執行方法的那幾行,把那些文字粘貼到你的HTML或JSP中。
要包括下面這些能產生神奇效果的Javascript文件的鏈接。
<script src='/[YOUR-WEBAPP]/dwr/interface/[YOUR-SCRIPT].js'></script> <scriptsrc='/[YOUR-WEBAPP]/dwr/engine.js'></script>
例:<!-- 導入DWR 爲Java 對象動態生成的JavaScript 文件-->
<scripttype="text/javascript" src="dwr/interface/DwrDate.js"></script>
<scripttype="text/javascript" src="dwr/interface/DwrService.js"></script>
<!--導入DWR 的JavaScript 文件-->
<scripttype="text/javascript" src="dwr/engine.js"></script>
<scripttype="text/javascript" src="dwr/util.js"></script>
5.1解釋
engine.js對DWR非常重要,它是DWR客戶端的核心,用來把動態生成的JavaScript對象轉換爲服務器上的Java對象
該函數庫可用於設置一些DWR的全局屬性
dwr.engine.setTimeout(time),以毫秒爲單位設置請求超時的時間
dwr.engine.setHttpMethod(method),該方法只能設置兩個值POST和GET
dwr.engine.setOrdered(boolean),Ajax通常都是異步調用,但服務器響應的順序與調用順序往往不同,使用dwr.engine.setOrfered(true)語句,DWR將保證請求的順序與服務器響應的順序一致
util.js文件中包含了一些工具函數,通過這些函數的幫助,將簡化JavaScript操作
util.js提供一些基本的頁面操作函數,通過這些函數可以方便的操作HTML元素
util.js文件與DWR框架關係不是特別大,可以在任何不同的網頁中使用(即便該工程沒有DWR支持)
$( )函數根據指定ID查找頁面中的HTML元素
簡單的講
$(ID) = document.getElementById(ID)
使用 $() 使代碼更簡潔、更清晰
6.多個dwr.xml文件
可以有多個dwr.xml文件(詳細信息見web.xml文檔)。每個文件中的定義會被加在一起。DWR用這個功能來加載基礎配置文件。我們可以看看標準被配置文件來了解dwr.xml的內容。
7.使用DWR的一些技巧
這裏有些東西可以幫你使用DWR。如果你也有什麼使用技巧,也添加進來吧。
創建一個"Google Suggest"組件
我不建議你做自己的suggest組件。讓一些基礎的東西工作起來是很容易的,但是讓鍵盤導航正常的工作卻不那麼容易。有一些庫裏面已經包含的suggest組件:
Script.aculo.us 裏有一個 Autocompleter.Local 函數,可以和DWR整合起來。讓Local版的組件和DWR的遠程調用結合起來要比直接讓Remote版的組件工作起來更容易一些,因爲Remote版的組件一般對服務器上的工作又特殊要求。你會可以在DWR的用戶郵件列表中找到相關的信息,也可以看Rubens的blog
另外,Rimu Hosting的Peter實現了一個自己的Suggest組件,也是可以和DWR一起用的,查看這裏
增強文件上傳
Pierre Losson寫了一個如何把DWR和Commons-Fileupload組件結合起來的文章。很不錯,並且源碼和演示都有。
改進加載信息
DWR 1.0 中的useLoadingMessage()函數有點問題,你可以自己定義這一信息,但是要小心調用。你也可以把這個函數中的問題修正一下。更多信息可以參看useLoadingMessage()的文檔。
使用Server控制檯
DWR可以報告出詳細的錯誤信息,這些信息可以幫你找出你的程序錯在哪裏。如果你的程序出現什麼異常,你應該仔細查看你的web容器開始或運行過程中出現的錯誤信息。一般錯誤信息會在WARNING或ERROR級別,但是INFO級別的信息也很有用。
如果你的log信息中又什麼錯誤,但是你想知道的更詳細的信息,可以查看INFO級別的信息,因爲有時錯誤信息和後臺信息會被一起輸出到log裏。
使用debug/test頁面
debug/test頁面對於查找錯誤也很有用。查看
http://localhost:8080/[YOUR-WEBAPP ]/
開始指南中有基本使用方法。但是一定要記住在發現錯誤時可以在這些頁面找到有用的信息。
訪問HttpServletRequest
向回調函數傳遞參數
通常我們需要把額外的信息傳遞給callback函數,但是所有的callback函數只有一個參數(遠程方法的返回碼)