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.项目创建图

9.执行结果

猜你喜欢

转载自blog.csdn.net/rjkkaikai/article/details/80447923
dwr