DWR的簡單應用


1.前言            

什麼是DWR?DWR是一個Java EE領域的Ajax框架,通過DWR的幫助,可以讓開發者更簡單地開發出Ajax應用。通過DR的幫助,開發者可以在瀏覽器的JavaScript代碼中調用遠程的Java方法,就像這些Java方法就是在客戶端定義一樣。

DWR框架允許客戶端JavaScript代碼直接調用遠程的Java方法,這種調用非常類似於WebService技術的RPC(RemoteProcedure Call,遠程過程調用)調用,因此,DWR也被稱爲RPC風格的Ajax框架。

DWR框架主要包括如下兩個部分。

1)        客戶端有JavaScipt,這部分代碼使客戶端JavaScript可以直接調用遠程服務器的Java方法。除此之外,DWR還提供了一些方便的工具函數來簡化DOM操作。

2)        服務器上運行的Servlet負責處理用戶請求,並將用戶請求委託到實際Java對象進行處理,並負責把處理結果返回客戶端。

基本原理是:當開發者直接調用遠程Java方法時,DWR會負責將這種調用轉換成對應的Ajax請求,並使用XMLHttpRequest將請求發送到遠程服務端。當服務器處理完成後,DWR負責數據的傳遞和轉換。


2.下載DWR文件

1)        登錄http://directwebremoting.org/dwr/downloads站點,下載DWR文件。


1)        將上面解壓路徑中的WEB-INF\lib目錄下的dwr.jar文件監製到Web應用的WEB-INF\lib下。

3.配置web.xml

成功安裝DWR需要先修改web.xml文件,修改web.xml文件能保證特定請求被轉發DWR的核心Servlet處理,而dwr.xml文件則負責定義Java類和JavaScript對象之間的對應關係。

[html] view plain copy
  1. <?xml version="1.0" encoding="GBK"?>  
  2. <web-app xmlns="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">  
  6.     <!-- 配置DWR的核心Servlet -->  
  7.     <servlet>  
  8.         <!-- 指定DWR核心Servlet的名字 -->  
  9.         <servlet-name>dwr-invoker</servlet-name>  
  10.         <!-- 指定DWR核心Servlet的實現類 -->  
  11.         <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>  
  12.         <!--  指定DWR核心Servlet處於調試狀態 -->  
  13.         <init-param>  
  14.             <param-name>debug</param-name>  
  15.             <param-value>true</param-value>  
  16.         </init-param>  
  17.     </servlet>  
  18.     <!-- 指定核心Servlet的URL映射 -->  
  19.     <servlet-mapping>  
  20.         <servlet-name>dwr-invoker</servlet-name>  
  21.         <!-- 指定核心Servlet映射的URL -->  
  22.         <url-pattern>/leedwr/*</url-pattern>  
  23.     </servlet-mapping>  
  24. </web-app>  

4.添加dwr.xml文件

1)        除此之外,還必須增加一個dwr.xml,該文件負責定義Java類和JavaScript對象之間對應關係。

[html] view plain copy
  1. <?xml version="1.0" encoding="GBK"?>  
  2. <!-- 指定DWR配置文件的DTD等信息 -->  
  3. <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"  
  4.     "http://getahead.org/dwr/dwr30.dtd">  
  5. <!-- DWR配置文件的根元素是dwr -->  
  6. <dwr>  
  7.     <allow>  
  8.         <!-- 使用new關鍵資創建一個Java實例  
  9.             指定創建的JavaScript對象名爲hello-->  
  10.         <create creator="new" javascript="hello">  
  11.             <!-- 使用class屬性指定創建該Java實例的實現類 -->  
  12.             <param name="class" value="com.owen.dwr.HelloDwr"/>  
  13.         </create>  
  14.         <!-- 對com.owen.dwr.domain.Person類使用Bean轉換器 -->  
  15.         <convert converter="bean" match="com.owen.dwr.domain.Person"/>  
  16.         <!-- 對com.owen.dwr.domain.Cat使用Object轉換器 -->  
  17.         <convert converter="object" match="com.owen.dwr.domain.Cat">  
  18.             <!-- 指定force="true"強制使用反射訪問私有屬性 -->  
  19.             <param name="force" value="true"/>  
  20.         </convert>  
  21.     </allow>  
  22.     <signatures>  
  23.         <![CDATA[ 
  24.         import java.util.List; 
  25.         import com.owen.dwr.HelloDwr; 
  26.         import com.owen.dwr.domain.Person; 
  27.         HelloDwr.sendListNoGeneric(List<Person>); 
  28.         ]]>  
  29.     </signatures>  
  30. </dwr>  

2)        dwr.xml文件說明

a)        在上面的配置文件,最重要的元素就是<allow…/>元素,如果一個dwr.xml文件沒有定義<allow…/>元素,或者<allow…/>元素爲空,則DWR將什麼都幹不了。<allow…/>元素裏常用的元素是<create…/>和<conert…/>,其中<create…/>用於定義如何將一個Java類轉換成一個JavaScript對象,而<convert…/>定義如何完成Java對象和JavaScript對象之間的轉換。

b)        DWR使用反射來確定Java實例和JavaScript對象之間的轉換。在時候,參數類型信息並不十分明確,或者參數是一個集合對象,而且沒有使用泛型來限制集合元素的類型,這就需要在dwr.xml文件的<signatures…/>元素中明確指定這些類型。

5.創建對應的類

在dwr.xml的文件中,我們添加了幾個類,所以這個時候,我們需要提供這些類。

1)        Cat.java

[java] view plain copy
  1.  /** 
  2.  *實體Cat 
  3.  * @author OwenWilliam 2016-5-8 
  4.  * @version 1.0 
  5.  */  
  6. public class Cat  
  7. {  
  8.     //Cat類的私有屬性  
  9.     private String name;  
  10.     //構造器  
  11.     public Cat(String name)  
  12.     {  
  13.         this.name = name;  
  14.     }  
  15. }  

2)        Person.java

[java] view plain copy
  1. package com.owen.dwr.domain;  
  2.   
  3. /** 
  4.  *實體Person 
  5.  * @author OwenWilliam 2016-5-8 
  6.  * @version 1.0 
  7.  */  
  8. public class Person  
  9. {  
  10.     // 私有Field  
  11.     private String name;  
  12.     // 無參數的構造器  
  13.     public Person() {}  
  14.     // 初始化全部成員變量的構造器  
  15.     public Person(String name)  
  16.     {  
  17.         this.name = name;  
  18.     }  
  19.   
  20.     // name的setter和getter方法  
  21.     public void setName(String name)  
  22.     {  
  23.         this.name = name;  
  24.     }  
  25.     public String getName()  
  26.     {  
  27.         return this.name;  
  28.     }  
  29. }  

3)        HelloDwr.java

[java] view plain copy
  1.  package com.owen.dwr;  
  2.   
  3. import java.util.*;  
  4.   
  5. import com.owen.dwr.domain.*;  
  6.   
  7. /** 
  8.   
  9.  * @author OwenWilliam 2016-5-8 
  10.  * @version 1.0 
  11.  */  
  12. public class HelloDwr  
  13. {  
  14.     // 第一個簡單的hello方法  
  15.     public String hello(String name)  
  16.     {  
  17.         return name + ",您好!您已經開始了DWR的學習之旅,祝您學得開心...";  
  18.     }  
  19.     // 使用一個JavaBean作爲參數的方法  
  20.     public String sendObj(Person p )  
  21.     {  
  22.         return p.getName() + ",您好!您已經學會了使用JavaBean參數...";  
  23.     }  
  24.     // 返回JavaBean實例的方法  
  25.     public Person getBean (String name)  
  26.     {  
  27.         return new Person(name);  
  28.     }  
  29.     // 返回一個普通的Java對象,Cat對象爲其屬性提供setter和getter方法  
  30.     public Cat getObject(String name)  
  31.     {  
  32.         return new Cat("服務器端" + name);  
  33.     }  
  34.     // 返回一個集合對象  
  35.     public List<Person> getPersonList()  
  36.     {  
  37.         List<Person> result = new ArrayList<Person>();  
  38.         result.add(new Person("集合aaaa"));  
  39.         result.add(new Person("集合bbbb"));  
  40.         result.add(new Person("集合cccc"));  
  41.         return result;  
  42.     }  
  43.     // 返回一個數組對象  
  44.     public Person[] getPersonArray()  
  45.     {  
  46.         Person[] result = new Person[3];  
  47.         result[0] = new Person("數組aaaa");  
  48.         result[1] = new Person("數組bbbb");  
  49.         result[2] = new Person("數組cccc");  
  50.         return result;  
  51.     }  
  52.     // 返回一個Map對象  
  53.     public Map<String, Person> getPersonMap()  
  54.     {  
  55.         // 創建一個Map對象  
  56.         Map<String, Person> result = new HashMap<String, Person>();  
  57.         // 填充Map對象的內容  
  58.         result.put("first" , new Person("Map aaaa"));  
  59.         result.put("second" , new Person("Map bbb"));  
  60.         result.put("third" , new Person("Map cccc"));  
  61.         // 返回Map  
  62.         return result;  
  63.     }  
  64.     // 遠程方法的參數是集合  
  65.     public String sendList(List<Person> pl)  
  66.     {  
  67.         String result = "";  
  68.         for (Person p : pl)  
  69.         {  
  70.             result += p.getName() + "<br />";  
  71.         }  
  72.         return result;  
  73.     }  
  74.     // 遠程方法的參數是不帶泛型的集合  
  75.     public String sendListNoGeneric(List pl)  
  76.     {  
  77.         String result = "";  
  78.         for (Object p : pl)  
  79.         {  
  80.             result += ((Person)p).getName() + "<br />";  
  81.         }  
  82.         return result;  
  83.     }  
  84.   
  85.     // 遠程方法的參數是集合  
  86.     public String sendMap(Map<String , Person> pmap)  
  87.     {  
  88.         String result = "";  
  89.         for (String key : pmap.keySet())  
  90.         {  
  91.             result += "鍵" + key + " 其值爲:" +  
  92.                 pmap.get(key).getName() + "<br />";  
  93.         }  
  94.         return result;  
  95.     }  
  96. }  

6.創建JS文件

創建個js文件名字叫hellodwr.js,這個文件可以直接調用java類中的方法。像hello.hello(name, cb)調用就是直接調用。

[javascript] view plain copy
  1. // -------------發送簡單字符串參數,返回普通字符串--------------  
  2. function sendMessage()  
  3. {  
  4.     // 獲取頁面中name元素的值  
  5.     var name = document.getElementById("name").value;  
  6.     // 調用遠程方法,cb是回調函數  
  7.     hello.hello(name , cb)  
  8. }  
  9. function cb(data)  
  10. {  
  11.     document.getElementById("show").innerHTML = data;  
  12. }  
  13. // -----------發送一個JavaBean對象作爲參數,返回普通字符串------------  
  14. function sendObject()  
  15. {  
  16.     var nameValue = document.getElementById("name").value;  
  17.     // 調用遠程方法,使用JavaScript對象作爲參數  
  18.     hello.sendObj({name:nameValue} , cb);  
  19. }  
  20.   
  21. // ----------------調用返回JavaBean方法-----------------  
  22. function getBean()  
  23. {  
  24.     var name = document.getElementById("name").value;  
  25.     // 調用遠程方法,beanCb是回調函數  
  26.     hello.getBean(name , beanCb)  
  27. }  
  28. function beanCb(data)  
  29. {  
  30.     // 服務器方法返回JavaBean對象,客戶端的data是JavaScript對象  
  31.     document.getElementById("show").innerHTML =   
  32.         data.name + ",您好,您已經學會了使用JavaBean返回值";  
  33. }  
  34. // ----------------調用返回getObject方法---------------  
  35. function getObject()  
  36. {  
  37.     var name = document.getElementById("name").value;  
  38.     // 調用遠程方法,objCb是回調函數  
  39.     hello.getObject(name , objCb)  
  40. }  
  41. function objCb(data)  
  42. {  
  43.     // 服務器方法返回非JavaBean式的對象,客戶端的data是JavaScript對象  
  44.     document.getElementById("show").innerHTML =   
  45.         data.name + ",是從服務器返回的貓的名字";  
  46. }  
  47. // ---------------調用返回集合的方法--------------  
  48. function getBeanList()  
  49. {  
  50.     // 調用遠程方法,listCb返回回調函數  
  51.     hello.getPersonList(listCb);  
  52. }  
  53. // 遠程Java方法返回List對象,集合元素是JavaBean式的對象  
  54. // 此處的data是JavaScript對象數組  
  55. function listCb(data)  
  56. {  
  57.     var result='';  
  58.     // 遍歷每個數組元素  
  59.     for (var i = 0 ; i < data.length ; i ++)  
  60.     {  
  61.         result += data[i].name + "<br />";  
  62.     }  
  63.     document.getElementById("show").innerHTML = result;  
  64. }  
  65. // ---------------調用返回數組的方法--------------  
  66. function getBeanArray()  
  67. {  
  68.     hello.getPersonArray(arrayCb);  
  69. }  
  70. function arrayCb(data)  
  71. {  
  72.     var result = "";  
  73.     // 下面的data是遠程Java方法的返回值,  
  74.     // data是個數組,遍歷數組。  
  75.     for (var i = 0 ; i < data.length ; i ++)  
  76.     {  
  77.         //依次訪問數組元素,數組元素是JSON格式的對象,訪問其name屬性  
  78.         result += data[i].name + "<br />";  
  79.     }  
  80.     document.getElementById("show").innerHTML = result;  
  81. }  
  82. // ---------------調用返回Map對象的方法-------------  
  83. function getBeanMap()  
  84. {  
  85.     hello.getPersonMap(mapCb);  
  86. }  
  87. // 遠程Java方法返回Map對象,集合元素是JavaBean式的對象  
  88. // 此處的data是JavaScript對象,且每個屬性值都是JavaScript對象  
  89. function mapCb(data)  
  90. {  
  91.     var result='';  
  92.     for (var key in data)  
  93.     {  
  94.         result += "鍵爲" + key + ",其值爲:" + data[key].name + "<br />";  
  95.     }  
  96.     document.getElementById("show").innerHTML = result;  
  97. }  
  98.   
  99. // ---------------調用發送集合的方法-------------------  
  100. function sendBeanList()  
  101. {  
  102.     // 創建JavaScript數組  
  103.     var args = [  
  104.         {name:"客戶端aaa"},  
  105.         {name:"客戶端bbb"},  
  106.         {name:"客戶端ccc"}  
  107.     ];  
  108.     // Java方法需要List參數,以JavaScript數組作爲參數調用遠程方法  
  109.     hello.sendList(args , sendListCb);  
  110. }  
  111. function sendListCb(data)  
  112. {  
  113.     document.getElementById("show").innerHTML = data;  
  114. }  
  115. // ---------------調用發送無泛型限制的集合--------------------  
  116. function sendBeanListNoGeneric()  
  117. {  
  118.     // 創建JavaScript數組  
  119.     var args = [  
  120.         {name:"客戶端aaa"},  
  121.         {name:"客戶端bbb"},  
  122.         {name:"客戶端ccc"}  
  123.     ];  
  124.     // Java方法需要List參數,以JavaScript數組作爲參數調用遠程方法  
  125.     hello.sendListNoGeneric(args , sendListCb);  
  126. }  
  127. // ---------------調用發送Map的方法-------------------------  
  128. function sendBeanMap()  
  129. {  
  130.     // 創建JavaScript對象  
  131.     var args = {  
  132.         first:{name:"客戶端aaa"},  
  133.         second:{name:"客戶端bbb"},  
  134.         third:{name:"客戶端ccc"}  
  135.     };  
  136.     // Java方法需要Map參數,以JavaScript對象作爲參數調用遠程方法  
  137.     hello.sendMap(args , sendMapCb);  
  138. }  
  139. function sendMapCb(data)  
  140. {  
  141.     document.getElementById("show").innerHTML = data;  
  142. }  

7.創建前端html的文件

html的文件就是要調用hellodwr.js中的方法。

[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta name="author" content="OwenWilliam" />  
  5.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  6.     <title> DWR入門 </title>  
  7.     <!-- 導入DWR引擎的核心JavaScript代碼庫 -->  
  8.     <script type='text/javascript' src='leedwr/engine.js'></script>  
  9.     <!-- 導入開發者爲本應用編寫的JavaScript代碼庫 -->  
  10.     <script type='text/javascript' src='hellodwr.js'></script>  
  11.     <!-- 導入DWR爲hello對象動態生成的JavaScript代碼庫 -->  
  12.     <script type='text/javascript' src='leedwr/interface/hello.js'>  
  13.     </script>  
  14. </head>  
  15. <body>  
  16. <h3>DWR入門</h3>  
  17. 請輸入您的名字<input id="name" name="name" type="text"/><br />  
  18. <input type="button" value="發送簡單請求" onclick="sendMessage();"/>  
  19. <input type="button" value="發送對象參數" onclick="sendObject();"/>  
  20. <input type="button" value="返回JavaBean" onclick="getBean();"/><br />  
  21. <input type="button" value="返回Object" onclick="getObject();"/>  
  22. <input type="button" value="返回Bean集合" onclick="getBeanList();"/>  
  23. <input type="button" value="返回Bean數組" onclick="getBeanArray();"/><br />  
  24. <input type="button" value="返回Bean Map" onclick="getBeanMap();"/>  
  25. <input type="button" value="發送Bean集合" onclick="sendBeanList();"/>  
  26. <input type="button" value="發送不帶泛型限制的Bean集合"  
  27.     onclick="sendBeanListNoGeneric();"/><br />  
  28. <input type="button" value="發送Bean Map" onclick="sendBeanMap();"/>  
  29. <hr />  
  30. 下面是服務器的迴應:<br />  
  31. <div id"show"></div>  
  32. </body>  
  33. </html>  

8.項目創建圖


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章