一、DWR简介

  dwr是一个Ajax框架,官方网站:http://directwebremoting.org/dwr/,最新版本3.0.1,要求jdk1.6及以上。

  如下图所示,可以通过DWR来调用Java方法,并通过DWR封装的工具类来对页面元素进行简单处理:

  上面的展示是对Ajax的封装,简化了用户的操作,当然最常用的还是逆向Ajax(需要DWR2.0及以上版本),就是俗称的服务器端推送:

  逆向Ajax相对比较难一点,下面先展示js调用Java方法的例子。

二、DWR示例-js调用Java方法

2.1 创建Web项目

  创建Web项目,并将dwr-3.0.1-RELEASE.jarcommons-logging-1.2.jar放入WEB-INF/lib下,dwr-3.0.1-RELEASE.jar是DWR必须要的jar包,最新版本为3.0.1-RELEASE,它依赖commons-logging-1.2.jar日志包。最终项目结构如下:

  若使用Maven,则Maven坐标如下:

  1. <dependency>
  2. <groupId>org.directwebremoting</groupId>
  3. <artifactId>dwr</artifactId>
  4. <version>3.0.1-RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>commons-logging</groupId>
  8. <artifactId>commons-logging</artifactId>
  9. <version>1.2</version>
  10. </dependency>

  Maven创建Web项目查看(待续)。本项目使用jdk1.7,tomcat7搭建。

2.2 修改web.xml

  DWR的js调用Java代码,本质上还是通过Ajax来访问,因此需要在web.xml中配置DWR接收js请求的servlet,配置如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  3. id="WebApp_ID" version="3.1">
  4. <display-name>testweb</display-name>
  5. <servlet>
  6. <servlet-name>dwr-invoker</servlet-name>
  7. <!-- 接收js的Ajax请求的servlet -->
  8. <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  9. </servlet>
  10.  
  11. <servlet-mapping>
  12. <servlet-name>dwr-invoker</servlet-name>
  13. <!-- 拦截指定的URL -->
  14. <url-pattern>/dwr/*</url-pattern>
  15. </servlet-mapping>
  16. <welcome-file-list>
  17. <welcome-file>index.html</welcome-file>
  18. <welcome-file>index.jsp</welcome-file>
  19. </welcome-file-list>
  20. </web-app>

  若使用的不是jdk1.7及Tomcat7注意修改web.xml的头信息,为低版本。

2.3 创建被调用的Java类

  创建一个普通的Java类即可,如下:

  1. package yiwangzhibujian;
  2.  
  3. import java.util.Date;
  4.  
  5. /**
  6. * @author yiwangzhibujian
  7. */
  8. @SuppressWarnings("deprecation")
  9. public class HelloWorld{
  10.  
  11. /**
  12. * 无参无返回值
  13. */
  14. public void helloNN(){
  15. System.out.println(new Date().toLocaleString() + " js访问helloNN方法");
  16. }
  17.  
  18. /**
  19. * 有参无返回值
  20. */
  21. public void helloYN(String name){
  22. System.out.println(new Date().toLocaleString() + " js访问helloYN方法,name=" + name);
  23. }
  24.  
  25. /**
  26. * 无参有返回值
  27. */
  28. public String helloNY(){
  29. System.out.println(new Date().toLocaleString() + " js访问helloNY方法");
  30. return "Hello World!";
  31. }
  32.  
  33. /**
  34. * 有参有返回值
  35. */
  36. public String helloYY(String name){
  37. System.out.println(new Date().toLocaleString() + " js访问helloYY方法,name=" + name);
  38. return "Hello " + name;
  39. }
  40. }

  通过DWR调用Java方法使用普通的Java类即可,不需要访问servlet。

2.4 创建DWR配置文件

  在WEB-INF根路径下创建DWR的配置文件,dwr.xml

  1. <!DOCTYPE dwr PUBLIC
  2. "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
  3. "http://getahead.org/dwr/dwr30.dtd">
  4.  
  5. <dwr>
  6. <allow>
  7. <create creator="new" javascript="HelloWorld">
  8. <param name="class" value="yiwangzhibujian.HelloWorld" />
  9. </create>
  10. </allow>
  11. </dwr>

  create=“new”,即通过默认的构造方法使用new来创建对象,javascript="HelloWorld",HelloWorld表示调用类的名称,即在js中Java对象的名字,<param>即用来配置DWR访问的类。简单来说,value就是js要调用的类,javascript属性即是为这个类起一个简单的别名。

2.5 创建JSP页面

  本示例简单的在index.jsp中编写:

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%
  3. String path=request.getContextPath();
  4. String basePath=request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
  5. %>
  6.  
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  8. <html>
  9. <head>
  10. <base href="<%=basePath%>">
  11.  
  12. <title>My JSP 'index.jsp' starting page</title>
  13. <meta http-equiv="pragma" content="no-cache">
  14. <meta http-equiv="cache-control" content="no-cache">
  15. <meta http-equiv="expires" content="0">
  16. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  17. <meta http-equiv="description" content="This is my page">
  18. <script type='text/javascript' src='dwr/engine.js'></script>
  19. <script type='text/javascript' src='dwr/util.js'></script>
  20. <script type='text/javascript' src='dwr/interface/HelloWorld.js'></script>
  21. <style type="text/css">
  22. td{
  23. border: solid 1px;
  24. }
  25. </style>
  26. </head>
  27.  
  28. <body>
  29. <table>
  30. <tr>
  31. <td>无参无返回值</td>
  32. <td colspan="3"><input type="button" value="helloNN" onclick="helloNN();"></td>
  33. </tr>
  34. <tr>
  35. <td>有参无返回值</td>
  36. <td colspan="2"><input type="text" id="helloYNName"></td>
  37. <td><input type="button" value="helloYN" onclick="helloYN();"></td>
  38. </tr>
  39. <tr>
  40. <td>无参有返回值</td>
  41. <td><input type="button" value="helloNY" onclick="helloNY();"></td>
  42. <td colspan="2"><input type="text" id="helloNYValue"></td>
  43. </tr>
  44. <tr>
  45. <td>有参有返回值</td>
  46. <td><input type="text" id="helloYYName"></td>
  47. <td><input type="button" value="helloYY" onclick="helloYY();"></td>
  48. <td><input type="text" id="helloYYValue"></td>
  49. </tr>
  50. </table>
  51. </body>
  52. <script type="text/javascript">
  53. //无参无返回值
  54. function helloNN(){
  55. HelloWorld.helloNN();
  56. }
  57. //有参无返回值
  58. function helloYN(){
  59. var name = dwr.util.getValue("helloYNName");
  60. HelloWorld.helloYN(name);
  61. }
  62. //无参有返回值
  63. function helloNY(){
  64. HelloWorld.helloNY(function(data) {
  65. dwr.util.setValue("helloNYValue", data);
  66. });
  67. }
  68. //有参有返回值
  69. function helloYY(){
  70. var name = dwr.util.getValue("helloYYName");
  71. HelloWorld.helloYY(name, function(data) {
  72. dwr.util.setValue("helloYYValue", data);
  73. });
  74. }
  75. </script>
  76. </html>

  必须引入的两个js,第二个js不是真实存在的js文件,而是项目启动访问后动态生成的js,这个js的名称HelloWorld,需与dwr.xml配置文件中javascript属性值一样,以下两个文件的顺序不能变:

  1. <script type='text/javascript' src='dwr/engine.js'></script>
  2. <script type='text/javascript' src='dwr/interface/HelloWorld.js'></script>

  使用DWR还可以使用它的一个工具js:

  1. <script type='text/javascript' src='dwr/util.js'></script>

  引入此js后,可以使用它的一些简单的方法,比如获取元素的值,设置元素的值等,也可以使用普通js或者jquery来获取:

  1. //获取指定id元素的值
  2. var name = dwr.util.getValue("helloYYName");
  3. //设置指定id元素的值为data
  4. dwr.util.setValue("helloYYValue", data);

  若不是用DWR的util工具,可以不需要引入util.js工具js。

+提示    

  engine.js在jar包中,具体位置为:org.directwebremoting包内

  util.js也在jar包中,具体路径为:org.directwebremoting.ui.servlet包内

2.6 启动项目访问测试

  最终项目目录结构如下:

  启动项目后访问:http://localhost:8080/dwr/,将有如下页面:

  按顺序测试并输入指定的值,最终结果如下:

  控制台输出内容如下:

  经测试无误。

三、原理简单分析

3.1.访问页面时

  当访问带有DWR页面的时候,引入js的请求会被,匹配到web.xml中的DWR的servlet(org.directwebremoting.servlet.DwrServlet):

  1. <servlet>
  2. <servlet-name>dwr-invoker</servlet-name>
  3. <!-- 接收js的Ajax请求的servlet -->
  4. <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  5. </servlet>
  6.  
  7. <servlet-mapping>
  8. <servlet-name>dwr-invoker</servlet-name>
  9. <!-- 拦截指定的URL -->
  10. <url-pattern>/dwr/*</url-pattern>
  11. </servlet-mapping>

  servlet会动态创建engine.js文件,并根据dwr/interface/HelloWorld.js,这种特定路径的文件名HelloWorld,去DWR配置文件dwr.xml中去查找相关配置:

  1. <create creator="new" javascript="HelloWorld">
  2. <param name="class" value="yiwangzhibujian.HelloWorld" />
  3. </create>

  查找到配置的对象后,并根据对象的所有方法动态创建HelloWorld对象,也会将所有方法生成相应的js方法,生成的HelloWorld.js如下:

  1. if (typeof dwr == 'undefined' || dwr.engine == undefined) throw new Error('You must include DWR engine
  2. before including this file');
  3.  
  4. (function() {
  5. if (dwr.engine._getObject("HelloWorld") == undefined) {
  6. var p;
  7.  
  8. p = {};
  9.  
  10. p.helloNN = function(callback) {
  11. return dwr.engine._execute(p._path, 'HelloWorld', 'helloNN', arguments);
  12. };
  13.  
  14. p.helloNY = function(callback) {
  15. return dwr.engine._execute(p._path, 'HelloWorld', 'helloNY', arguments);
  16. };
  17.  
  18. p.helloYN = function(p0, callback) {
  19. return dwr.engine._execute(p._path, 'HelloWorld', 'helloYN', arguments);
  20. };
  21.  
  22. p.helloYY = function(p0, callback) {
  23. return dwr.engine._execute(p._path, 'HelloWorld', 'helloYY', arguments);
  24. };
  25.  
  26. dwr.engine._setObject("HelloWorld", p);
  27. }
  28. })();

  可以看到动态生成的对象包含java对象的所有方法,调用js方法会通过底层的Ajax调用相应的Java方法。

3.2 使用原因

  • DWR是开源免费的
  • 封装Ajax实现,可以很方便的调用
  • 除此以外还有反向Ajax,即服务器推送功能,后续介绍

  这一篇简单的介绍了DWR,并展示了一个js调用Java的例子,可以看出DWR对Ajax封装的非常好,调用起来很方便。下面一篇将会介绍逆向Ajax的用法。

【DWR系列01】-DWR简介及入门例子的更多相关文章

  1. Redux系列01:从一个简单例子了解action、store、reducer

    其实,redux的核心概念就是store.action.reducer,从调用关系来看如下所示 store.dispatch(action) --> reducer(state, action) ...

  2. SpagoBI系列----------[01]SpagoBI简介及安装步骤

    商务智能套件SpagoBI提供一个基于J2EE的框架用于管理BI对象如报表.OLAP分析.仪表盘.记分卡以及数据挖掘模型等的开源BI产品.它提供的BI管理器能 够控制.校验.验证与分发这些BI对象. ...

  3. 【DWR系列03】- DWR主要类详解

    img { border: 1px solid black } 一.简介 首先应该了解这个jar包主要的类,了解了类,就了解了DWR.DWR的在线javadoc:http://directwebrem ...

  4. 【DWR系列02】-DWR逆向Ajax即服务器推送

    .literal { background-color: #f2f2f2; border: 1px solid #cccccc; padding: 1px 3px 0; white-space: no ...

  5. C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介

    目录 为什么要刷LeetCode 刷LeetCode有哪些好处? LeetCode vs 传统的 OJ LeetCode刷题时的心态建设 C#如何刷遍LeetCode 选项1: VS本地Debug + ...

  6. Quartz入门例子简介 从入门到菜鸟(一)

    转: Quartz入门例子简介 从入门到菜鸟(一) 2016年11月19日 22:58:24 爱种鱼的猫 阅读数:4039   刚接触quartz这个词并不是在学习过程中...而是WOW里面的界面插件 ...

  7. [.NET MVC4 入门系列01]Helloworld MVC 4 第一个MVC4程序

    [.NET MVC4 入门系列01]Helloworld MVC 4 第一个MVC4程序   一.练习项目: http://www.asp.net/mvc/tutorials/mvc-4/gettin ...

  8. php从入门到放弃系列-01.php环境的搭建

    php从入门到放弃系列-01.php环境的搭建 一.为什么要学习php 1.php语言适用于中小型网站的快速开发: 2.并且有非常成熟的开源框架,例如yii,thinkphp等: 3.几乎全部的CMS ...

  9. 005 01 Android 零基础入门 01 Java基础语法 01 Java初识 05 Eclipse简介

    005 01 Android 零基础入门 01 Java基础语法 01 Java初识 05 Eclipse简介 Eclipse是一款集成开发工具--IDE. 集成开发环境(IDE,Integrated ...

随机推荐

  1. JVM:查看java内存情况命令

    jmap (linux下特有,也是很常用的一个命令) 观察运行中的jvm物理内存的占用情况. 参数如下: -heap :打印jvm heap的情况 -histo: 打印jvm heap的直方图.其输出 ...

  2. UnicodeEncodeError: 'ascii' codec can't encode characters in position 820-823: ordinal not in range(128)

    真是奇怪了,在itermi里 print(data) 就能直接运行,而在sublime里,就非得写成这样 print(data.encode('utf-8'))

  3. Unity StrangeIoC框架

    Unity StrangeIoC框架  http://blog.csdn.net/y1196645376/article/details/52746251    

  4. 【转】MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  5. Visual Studio 版本转换工具WPF版开源了

    想法的由来 入职一家新公司,领导给了个任务,要编写一个视频监控软件,等我编写调试好,领导满意了以后,这个软件要加入到公司的一个软件系统中去(这个添加工作不用我来做,嘻嘻,看着自己的软件被别人使用,心情 ...

  6. Bookshop(一)数据库连接

    连接池配置文件db.properties配置 1.新建一个普通文件->改名为db.properties(后缀)手动添加属性 一般为数据库驱动类.数据库连接地址.用户名.用户密码 driver=c ...

  7. 项目vue2.0仿外卖APP(四)

    组件拆分 先把项目搭建时生成的代码给清了吧 现在static目录下引入reset.css 接着在index.html引入,并且设置<meta> 有时候呢,为了让代码符合我们平时的编码习惯, ...

  8. 2>&1

    经常关注linux脚本的人,一定看到过 2>&1 这样的用法,最初一定不明白其中的含义以及为什么是这样的一种组合.昨天偶然间再次看到了这个 2>&1 的写法,遂下决心搞明白 ...

  9. java 单例模式

    懒汉式 public class Singleton{ //@单例类只能有一个实例 //@单例类必须自行创建这个实例 //@单例类必须给所有对象提供这一个实例//必须向整个系统提供这个这个实例 pri ...

  10. python table转空格

    有需求: 预留,先上代码: import os def Table_Space(file_name,lis_out,tab_num = 4): file_str = open(file_name,&q ...