初步认识DWR框架

来源:互联网 发布:科学 知乎 编辑:程序博客网 时间:2024/06/05 05:05

通过DWR框架,java开发者能够很方便的使用Ajax技术,使得java开发者在不熟悉使用Ajax进行异步数据交换的情况下能够顺利达到客户端跟服务端进行异步数据交换。

DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站。它可以允许在浏览器里的代码使用运行在WEB服务器上的JAVA函数,就像它就在浏览器里一样。

它包含两个主要的部分:允许JavaScript从WEB服务器上一个遵循了AJAX原则的Servlet中获取数据.另外一方面一个JavaScript库可以帮助网站开发人员轻松地利用获取的数据来动态改变网页的内容.
DWR采取了一个类似AJAX的新方法来动态生成基于JAVA类的JavaScript代码。这样WEB开发人员就可以在JavaScript里使用Java代码,就像它们是浏览器的本地代码(客户端代码)一样;但是Java代码运行在WEB服务器端而且可以自由访问WEB 服务器的资源。出于安全的理由,WEB开发者必须适当地配置哪些Java类可以安全的被外部使用。[1] 
这个从JAVA到JavaScript的远程功能方法给DWR的用户带来非常像传统的RPC机制,就像RMI或者SOAP一样,而且拥有运行在WEB上但是不需要浏览器插件的好处.
DWR不认为浏览器/WEB服务器协议是重要的,而更乐于保证编程界面的简单自然.对此最大的挑战就是把AJAX的异步特性和正常JAVA方法调用的同步特性相结合.在异步模式下,结果数据在开始调用之后的一段时间之后才可以被异步访问获取到.DWR允许WEB开发人员传递一个回调函数,来异步处理Java函数调用过程.

       下面的例子是一个入门上手的简单例子。例子的项目名为 test,使用myeclipse8.5,数据库为mysql5.0,dwr为2.0开发。项目所需的包名:mysql-connector-java-5.0.8-bin.jar连接mysql数据库用的驱动包),dwr.jar(dwr框架包),commons-logging-1.0.4.jar(dwr框架所需的日志包),使用dwr框架,其中dwr.ar,commons-logging-1.0.4.jar两个包缺一不可。文章首先把项目的代码全部贴出,代码的具体用处和说明在文章第二节会说明。

                                                                                           第一节

 

第一步:新建一个名为test的web项目工程。

第二步:编写连接数据库的Conn类。示例项目中所有的java类都是放在com.joyun.test包中。

[java] view plaincopy
  1. <span style="font-size:14px;">package com.joyun.test;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5. import java.sql.PreparedStatement;  
  6. import java.sql.ResultSet;  
  7.   
  8. public class Conn {  
  9.       
  10.     public Connection connDB() throws Exception{  
  11.         //1、注册驱动  
  12.         Class.forName("com.mysql.jdbc.Driver");  
  13.         String url = "jdbc:mysql://localhost:3306/joyunblog";  
  14.         //2、加载驱动  
  15.         Connection conn=DriverManager.getConnection(url, "root""admin");  
  16.         return conn;  
  17.           
  18.     }  
  19.       
  20. }  
  21. </span>  


 

第三步:编写一个User类。

[java] view plaincopy
  1. <span style="font-size:14px;">package com.joyun.test;  
  2.   
  3. public class User {  
  4.       
  5.     private String name = null;  
  6.     private String password = null;  
  7.       
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.     public String getPassword() {  
  12.         return password;  
  13.     }  
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17.     public void setPassword(String password) {  
  18.         this.password = password;  
  19.     }  
  20.       
  21.   
  22. }</span>  

 

第四步:编写UserDao类。

[java] view plaincopy
  1. <span style="font-size:14px;">package com.joyun.test;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.SQLException;  
  6.   
  7. public class UserDao {  
  8.       
  9.     public boolean save(User user){  
  10.         boolean b = false;  
  11.         String name = user.getName();  
  12.         String password = user.getPassword();  
  13.         Connection conn = null;  
  14.         try {  
  15.             try {  
  16.                 conn = new Conn().connDB();  
  17.             } catch (Exception e) {  
  18.                 // TODO Auto-generated catch block  
  19.                 e.printStackTrace();  
  20.             }     
  21.             String sql = "insert into myself(myname,mypassword,createtime,updatetime)" +  
  22.                 "values(+"+name+","+password+",now(),now())";     
  23.             PreparedStatement ps = conn.prepareStatement(sql);  
  24.             int i = ps.executeUpdate();  
  25.             if(i==1){  
  26.                 b = true;  
  27.             }  
  28.               
  29.         }catch (SQLException e) {  
  30.             // TODO Auto-generated catch block  
  31.             e.printStackTrace();  
  32.         }  
  33.         return b;  
  34.     }  
  35. }  
  36. </span>  


 

第五步:编写UserJs类。

[java] view plaincopy
  1. <span style="font-size:14px;">package com.joyun.test;  
  2.   
  3. public class UserJs {  
  4.     UserDao userDao = new UserDao();  
  5.       
  6.     public boolean save(User user){  
  7.         return userDao.save(user);  
  8.     }  
  9.   
  10. }</span>  

 

第六步:编写jsp页面。该页面为index.jsp页面,代码如下:

[html] view plaincopy
  1. <span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="gbk"%>  
  2. <%@ page contentType="text/html; charset=gb2312" %>   
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. request.setCharacterEncoding("gb2312");  
  7. %>  
  8.   
  9. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  10. <html>  
  11.   <head>  
  12.     <base href="<%=basePath%>">  
  13.       
  14.     <title>My JSP 'index.jsp' starting page</title>  
  15.     <meta http-equiv="pragma" content="no-cache">  
  16.     <meta http-equiv="cache-control" content="no-cache">  
  17.     <meta http-equiv="expires" content="0">      
  18.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  19.     <meta http-equiv="description" content="This is my page">  
  20.     <!-- 
  21.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  22.     -->  
  23.     <script src="<%=basePath%>dwr/engine.js"></script>  
  24.     <script src="<%=basePath%>dwr/util.js"></script>  
  25.     <script src="<%=basePath%>dwr/interface/UserJs.js"></script>  
  26.       
  27.     <script type="text/javascript">  
  28.     function OnSave(){  
  29.         var user = {};  
  30.         user.name = regForm.name.value;  
  31.         user.password = regForm.password.value;  
  32.         UserJs.save(user, saveFun);   
  33.         }  
  34.     function saveFun(data){  
  35.         if(data){  
  36.             alert("注册成功!");  
  37.             }  
  38.         else{  
  39.             alert("注册失败!");  
  40.             }  
  41.         }  
  42.     </script>  
  43.   </head>  
  44.   <body>   
  45.      <form name="regForm">              
  46.             口  令:<input type="password" name="password"><br>  
  47.             姓  名:<input type="text" name="name"><br>  
  48.             <input type="button" name="submitBtn" value="提交" onclick="OnSave()"><br>  
  49.       </form>  
  50.  </body>  
  51. </html>  
  52. </span>  


 

 

第七步:在WEB-INF文件下新建一个dwr.xml文件,该文件与web.xml同一目录。dwr.xml文件代码如下:

[html] view plaincopy
  1. <span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"   
  3. "http://www.getahead.ltd.uk/dwr/dwr20.dtd">  
  4. <dwr>  
  5.   <allow>  
  6.     <create creator="new" javascript="UserJs">  
  7.         <param name="class" value="com.joyun.test.UserJs"/>  
  8.     </create>  
  9.     <convert converter="bean" match="com.joyun.test.User"/>  
  10.   </allow>  
  11. </dwr>  
  12.   
  13. </span>  

 

 

第八步:编写web.xml。

[html] view plaincopy
  1. <span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  4.    
  5.     <servlet>  
  6.         <servlet-name>dwr-invoker</servlet-name>  
  7.         <display-name>DWR Servlet</display-name>  
  8.         <description>Direct Web Remoter Servlet</description>  
  9.         <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>  
  10.         <init-param>  
  11.           <param-name>debug</param-name>  
  12.           <param-value>true</param-value>  
  13.         </init-param>  
  14.         <init-param>  
  15.           <param-name>scriptCompressed</param-name>  
  16.           <param-value>false</param-value>  
  17.         </init-param>  
  18.         <load-on-startup>1</load-on-startup>  
  19.      </servlet>  
  20.         
  21.     <servlet-mapping>  
  22.         <servlet-name>dwr-invoker</servlet-name>  
  23.         <url-pattern>/dwr/*</url-pattern>  
  24.     </servlet-mapping>  
  25.       
  26.        
  27.     <welcome-file-list>  
  28.         <welcome-file>index.jsp</welcome-file>  
  29.     </welcome-file-list>  
  30.     <login-config>  
  31.         <auth-method>BASIC</auth-method>  
  32.     </login-config>  
  33.       
  34. </web-app>  
  35. </span>  


 

 

 

第九步:发布项目。

 

 

                                                                                                  第二节

 项目说明我们从后面的步骤往前面讲。

第一步:web.xml配置文件的说明。

[html] view plaincopy
  1. <span style="font-size:14px;"><servlet>  
  2.         <servlet-name>dwr-invoker</servlet-name>  
  3.         <display-name>DWR Servlet</display-name>  
  4.         <description>Direct Web Remoter Servlet</description>  
  5.         <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>  
  6.         <init-param>  
  7.           <param-name>debug</param-name>  
  8.           <param-value>true</param-value>  
  9.         </init-param>  
  10.         <init-param>  
  11.           <param-name>scriptCompressed</param-name>  
  12.           <param-value>false</param-value>  
  13.         </init-param>  
  14.         <load-on-startup>1</load-on-startup>  
  15.      </servlet>  
  16.         
  17.     <servlet-mapping>  
  18.         <servlet-name>dwr-invoker</servlet-name>  
  19.         <url-pattern>/dwr/*</url-pattern>  
  20.     </servlet-mapping></span>  


我们通过servelet对dwr的请求拦截。<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>,其实这个类我们也可以用org.directwebremoting.servlet.DwrServlet代替。如果我们设置了debug为true的话,我们通过http://ip:port/webapp/dwr/index.html访问调试信息,如本项目中,我们这样访问:http://localhost:8080/test/dwr/index.html。

第二步:dwr.xml配置文件的说明。

dwr.xml文件的结构如下:

[html] view plaincopy
  1. <!DOCTYPE dwr PUBLIC  
  2.     "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"  
  3.     "http://directwebremoting.org/schema/dwr30.dtd">  
  4.   
  5. <dwr>  
  6.   
  7.   <!-- init is only needed if you are extending DWR -->  
  8.   <init>  
  9.     <creator id="..." class="..."/>  
  10.     <converter id="..." class="..."/>  
  11.   </init>  
  12.   
  13.   <!-- without allow, DWR isn't allowed to do anything -->  
  14.   <allow>  
  15.     <filter class="..."/>  
  16.     <create creator="..." javascript="..."/>  
  17.     <convert converter="..." match="..."/>  
  18.   </allow>  
  19.   
  20.   <!-- you may need to tell DWR about method signatures -->  
  21.   <signatures>  
  22.     ...  
  23.   </signatures>  
  24.   
  25. </dwr>  


该文件中必须要有allow标签,否则dwr就不会接受从jsp页面传来的方法调用了。该文件的具体用法请参考dwr官网说明文档。

本项目中该文件的allow标签如下:

[html] view plaincopy
  1. <allow>  
  2. <create creator="new" javascript="UserJs">  
  3.         <param name="class" value="com.joyun.test.UserJs"/>  
  4.    </create>  
  5. <convert converter="bean" match="com.joyun.test.User"/>  
  6.  </allow>  

其中creator="new",说明用户每次访问该页面时都会创建一个新的实例。UserJs就是我们供前台页面调用的java类,该java类中有个save的方法。converter是类型转换,因为我们后台UserJS类的save方法参数是一个User对象。match就是要匹配转换的的User类的路径,即包名+类名。

第三步:index.jsp页面中,请注意js脚本。

[javascript] view plaincopy
  1. <span style="font-size:14px;"><script type="text/javascript">  
  2.     function OnSave(){  
  3.         var user = {};  
  4.         user.name = regForm.name.value;  
  5.         user.password = regForm.password.value;  
  6.         UserJs.save(user, saveFun);   
  7.         }  
  8.     function saveFun(data){  
  9.         if(data){  
  10.             alert("注册成功!");  
  11.             }  
  12.         else{  
  13.             alert("注册失败!");  
  14.             }  
  15.         }  
  16. </script></span>  

当用户在该页面点击<input type="button" name="submitBtn" value="提交" onclick="OnSave()">  提交会触发OnSave脚本方法,

在脚本OnSave方法中我们生命了一个user对象,该对象有name和password两个属性,这两个属性的值是用户在输入框输入的值。OnSave方法中调用后台UserJs类的save方法进行保存,这里的save方法命名是有两个参数,而后台UserJs类的save只有一个user对象作为参数啊。其实这里就是dwr框架的使用了。dwr框架通过方法回传的这一解决办法类实现异步数据的交换。即在脚本中调用UserJs.save(user, saveFun);方法时,首先是到拦截器重,即我们再web.xml中配置的拦截器,经过拦截器处理后,通过回传的这种形式返回服务端的处理结果,而data就是服务端UserJs类的save方法的返回值。ps:本人水平有限,在这里讲的不是很明白,大家多多包涵或者自己到百度查阅更详细的资料。其实简单来讲js脚本中跟后台java类的交互中间还会通过dwr拦截,dwr拦截器会对其进行处理让服务端跟客户端进行数据交互,这就是为什么java程序员可以在不很了解设置不了解Ajax的情况下使用dwr框架能够进行异步数据交换,因为这部分的工作已经被dwr框架取代了。
另外在index.jsp中:

<script src="<%=basePath%>dwr/engine.js"></script>
 <script src="<%=basePath%>dwr/util.js"></script>
 <script src="<%=basePath%>dwr/interface/UserJs.js"></script>

这三个脚本的引入,其中前两个脚本是必须要引入的,后面的脚本是对应我们的java类,其中UserJs.js是我们再dwr.xml配置文件<create creator="new" javascript="UserJs"> javascript中对应的值,

第四步:UserJs类

该类就是供脚本js调用的类。

 

 

 

 

==========================================================================================

 后记:在实际工作中,dwr框架通常都是跟ssh框架结合起来使用的!

 

更多dwr参考文档请访问:http://directwebremoting.org/dwr/documentation/index.html


0 0