11.1.2 DWR使用入门
有两种方式可以开始DWR的应用。一种是直接从其官方网站下载DWR的Web应用示范包,这是一个war的部署包,从中可以对DWR的应用效果及其部署方式有一个大概的了解。不过这种方式无法详细掌握如何将DWR与Web应用程序紧密集成。另外一种方式是根据DWR官方开发文档的讲解,通过一步步的部署和配置,将DWR集成到Web应用程序中。本节通过简单的示范和一个例子来讲述DWR的部署和集成。
DWR采用一个Java Servlet来处理请求并将响应结果发送给浏览器,这个Java Servlet需要加入到Java Web应用程序的部署描述文件web.xml。其次,它通过一个自定义的部署描述文件dwr.xml来控制Java对象与Javascript的转化。下面通过五步简单的配置,将DWR部署到2.4节创建的开发项目中。
第一步:安装jar开发包。
从DWR官方网站http://www.getahead.ltd.uk/dwr/下载DWR的开发包。这里采用DWR1.0,它是一个简单的名为dwr1.0.jar开发包。将这个开发包放到{APPLICATION_ WEB_HOME} \WEB-INF\lib目录下。如果使用DWR1.1,则下载的应该是DWR1.1的开发包。这个开发包中包含了DWR运行所需的全部Java类及相应的API。dwr1.0.jar也可以从随书光盘jar lib目录中找到。
第二步:修改web.xml,添加Servlet映射。
修改{APPLICATION_WEB_HOME}\WEB-INF目录下的web.xml,将下列代码添加到web.xml的适当位置。
例程11-1 为web.xml添加DWR映射
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<servlet>映射部分应该紧随web.xml中的其他<servlet>映射,<servlet-mapping>则紧随<servlet-mapping>部分。
这段部署描述告诉Web应用程序,全部以“/dwr/”起始的URL所指向的请求都交给uk.ldt.getahead.dwr.DWRServlet这个Java Servlet来处理。
第三步:创建dwr.xml
在{APPLICATION_WEB_HOME}\WEB-INF目录下创建dwr.xml部署描述文件,其代码例程11-2所示。
例程11-2 DWR部署描述文件dwr.xml
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<create creator="new" javascript="JDate">
<param name="class" value="java.util.Date"/>
</create>
</allow>
</dwr>
这个XML文档中用到了其对应的DTD文档,顶部的文档声明指明当前用到的是DWR1.0版本。如果使用DWR1.1,则应该相应地修改这个XML文档的文档声明。
这个部署描述文件定义什么样的Java 类可以被DWR应用创建并通过Javascript远程调用。在上面的部署描述中,定义了可以被DWR创建的Java类java.util.Date,并给这个类赋予一个Javascript名称JDate。通过修改dwr.xml,也可以将自定义的Java类暴露给Javascript远程调用。
需要注意的是,dwr部署描述为远程Java类拟定的Javascript名称还是有些限制的。
— 避免使用Javascript关键字或者保留字,因为这些用Javascript关键字或者保留字命名的方法会自动执行。大部分的Javascript关键字或者保留字也是Java的关键字或者保留字,比如,“try()”不是一个合法的命名。不过还是有一部分的Javascript关键字或者保留字在Java中不被限制,比如“delete()”。
— 避免使用方法重载。有时候,在调用这些重载的方法会引起麻烦,因为Javascript没有像Java那样的包命名机制来支持方法重载。
第四步:测试URL,查看部署效果。
在浏览器地址栏中输入http://localhost:8080/ajaxlab/dwr,其页面效果如图11-2所示。通常,这个页面会显式在dwr.xml部署描述文件中定义的全部Java类,并且显式可以查看所有其可供远程调用的方法的列表的链接。这个页面由DWR动态创建。在本例中,页面上有一个JDate的链接,列出暴露给DWR的JDate类可供Javascript远程调用的方法。
图11-2 DWR部署效果
单击“JDate”链接,查看Javascript能够调用的java.util.JDate类的方法,其效果如图11-3所示。单击每个方法后面的“Execute”按钮,尝试执行这些方法。
图11-3 能够被Javascript远程调用的方法
第五步:使用Javascript远程调用Java类的方法。
java.util.Date类的相关方法已经暴露出来供Javascript远程调用。将以下的Javascript引用代码添加到JSP或者HTML文件中,就可以在JSP或者HTML文件中直接调用第四步配置所暴露的java.util.Date类的方法了。
<script language="javascript" src="/ajaxlab/dwr/interface/JDate.js"> </script>
<script language="javascript" src='/ajaxlab/dwr/engine.js'></script>
<script language="javascript" src='/ajaxlab/dwr/util.js'></script>
例程11-3展示了这个过程,调用java.util.Date类的toString()方法将当前时间打印出来。这个例子包含一个普通按钮控件和两个Javascript函数,其中一个函数doTest通过JDate.toString()调用,取得java.util.Date所表示的当前时间。第二个函数responseDate将第一个函数所取得的当前时间以弹出窗口的形式显式出来。第二个函数的名称作为第一个函数的参数,这与第5章所说的回调函数类似。具体代码如例程11-3所示,其运行效果如图11-4所示。
例程11-3 sample12_1.jsp
<%@ page contentType="text/html; charset=gb2312" errorPage="" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Ch11--DWR使用入门</title>
<script language="javascript" src="/ajaxlab/dwr/interface/JDate.js"></s cript>
<script language="javascript" src='/ajaxlab/dwr/engine.js'></script>
<script language="javascript" src='/ajaxlab/dwr/util.js'></script>
<script language="javascript">
function doTest() {
JDate.toString(load);
}
function load(data) {
window.alert("Current Time:"+data);
}
</script>
</head>
<body>
<input type="button" name="count" value="cont" onClick="doTest()">
</body>
</html>
图11-4 调用JDate的Javascript方法显示当前时间
通过简单的配置,Javascript可以自由地远程调用Java对象的方法。接下来看看DWR是怎么实现上述设计的。DWR使用dwr.xml部署描述文档来定义Javascript对象和Java类之间的映射转化。首先了解一下dwr.xml这个DWR定义的部署描述文件的结构。从dwr.xml对应的DTD(http://www.getahead.ltd.uk/dwr/dwr10.dtd,版本1.0)文件中很容易知道dwr.xml的具体结构。从DWR的官方网站可以找到关于这个DTD的说明文档(http://get ahe ad.ltd.uk/dwr-demo/dtddoc/)。
所有部署描述文件的顶级根元素为dwr,其按照顺序可以包含以下三个子元素之一。
— init:此元素定义那些在应用程序启动时作为DWR运行库所需的类自动加载并初始化的类。
— allow:此元素定义那些允许客户端Javascript远程调用的Java类。
— signatures:此元素签名必要的方法,当使用集合的时候,为转换器指定Java反射机制外的类别信息。
表11-1显示了dwr.xml的各个组成元素及其父元素、属性、子元素、用途等信息。
表11-1 dwr.xml组成元素及其属性和用途
元素名称 | 属性名称 | 父 元 素 | 用 途 |
dwr |
|
| dwr.xml文档的根元素 |
init |
| dwr | 定义那些在应用程序启动时作为DWR运行库所需的类自动加载并初始化的类 |
creator |
| init | 定义供Javascript调用的新建对象的方法,即对象的构造方法 |
| id | creator | 用来惟一标识creator所创建的对象。必需属性 |
| class | creator | 应用creator元素定义的Java对象的完整名称。必需属性 |
converter |
| init | 定义Javascript对象和Java对象之间新的转换方法。有些类有默认的转换机制,但有些类需要自定义转换机制 |
| id | converter | 用来惟一标识converter所创建的对象。必需属性 |
| class | converter | 应用converter元素定义的Java对象的完整名称。必需属性 |
allow |
| dwr | 定义那些允许客户端Javascript远程调用的Java类 |
create |
| allow | 定义允许创建的Java类,并为其指定一个Javascript名称,并定义DWR应当如何获得要进行远程的类的实例 |
| creator | create | create元素所使用的构造方法名称。必需属性 |
续表
元素名称 | 属性名称 | 父 元 素 | 用 途 |
| javascript | create | Java类暴露给浏览器调用的Javascript名称。必需属性 |
| scope | create | create元素所创建的类的可用范围,默认为page。可选属性 |
param |
| create | 指定create元素所需要的参数,比如其允许创建的Java类的名称 |
|