- 浏览: 173793 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (157)
- j2se (6)
- 网络安全 (11)
- java (28)
- spring (0)
- Struts2 (2)
- hibernate (1)
- Dwr (0)
- ajax (3)
- flash (0)
- 文学&&小说 (1)
- 火车头 (1)
- 小软件 (13)
- 数据挖掘 (1)
- 搜索 (4)
- Java开源项目 (9)
- javaweb 服务器 (0)
- 经典教程 (12)
- php (1)
- web roller (4)
- Lucene (1)
- 普索网 (1)
- Javascript (2)
- 普索网【Vim】 (0)
- Ftp (0)
- log4j (1)
- j2se【pusuo】 (1)
- fdsfdsfsadfasfsa (0)
- b (0)
- c (0)
- f (0)
- cc (0)
- ddd (1)
最新评论
DWR中文文档.rar
DWR中文文档v0.9
DWR 2.0
方佳玮 编著
部分原创/部分整理/部分翻译
版权声明
本书目前仅发行网络版,完全免费,转载请注明作者信息。任何出版社或个人未经作者
允许不得出版印刷。
另外如果发现本人的部分内容有所抄袭,请不要来找我理论,我本来做的就是公益事情。
版权所有,侵仅必究。
参考网站及资料
DWR官方网站
http://getahead.ltd.uk/dwr/
JavaScud Wiki
http://wiki.javascud.org/display/dwrcn/Home
IBM中国
http://www.ibm.com/developerworks/cn/
前言
Ajax向我们袭来的时候,很多写代码的程序员看到了Ajax的发展前景,但并不是每一
个程序员都能将页面与代码完美整合在一起,DOM、CSS、javascript让人眼花缭乱,不知
从何下手。
本书的读者必须有一定的Jsp,JavaScript,应用服务器(比如Tomcat)的基础和使用经
验,否则请在看此教程前先去了解一下。当然附录里有一些JavaScript的教程。
本书可以当作一本DWR完整的教程,也可以当作一本详细介绍DWR的“词典”,我
的目的只是通过本书,希望您能够了解一些DWR的基本知识、常用的用户界面组件、远程
方法调用等。并能够搭建DWR开发环境,实现DWR的快速开发。
非常感谢JavaScud Wiki网站,省去了我很多翻译时间,同时感谢网站的几位翻译人员。
由于本人也刚刚接触DWR,书中难免会有一些错误和表达不是太好的地方,请读者谅
解并提出您的宝贵意见。我很希望得到读者对本书的评价和建议。您可以把你在学习本书的
过程中所遇到的问题和建议发送到我的邮箱 jorwen.fang@gmail.com ,以便我对本书下一个
版本的更新,我会在第一时间给您回复。
感谢您阅读本书!希望这本书对你来说是一本有用的书。我是上海华东理工大学03届
计算机(金山)专业的方佳玮。
方佳玮
2007-01-22
目录
第1章. DWR入门 ................................................................................................................................ 8
1.1 简介 ................................................................................................................................. 8
1.2 第一个DWR程序:Hello World ....................................................................................... 9
1.2.1 将DWR放入你的工程 ............................................................................................. 9
1.2.2 编辑配置文件 ........................................................................................................... 9
1.2.3 编写service ........................................................................................................... 10
1.2.4 测试DWR .............................................................................................................. 10
1.2.5 编写一个jsp ........................................................................................................... 11
1.3 本章总结......................................................................................................................... 12
第2章. web.xml配置 .......................................................................................................................... 13
2.1 主要配置......................................................................................................................... 13
2.2 常用<init-param>参数列表 ............................................................................................. 14
2.2.1 安全参数 ................................................................................................................ 14
2.2.2 Ajax服务器加载时保护参数 ................................................................................... 14
2.2.3 其他参数 ................................................................................................................ 15
2.3 日志配置......................................................................................................................... 16
2.4 多个dwr.xml配置和J2EE角色定义 .............................................................................. 16
2.5 插件配置......................................................................................................................... 18
2.6 测试模式配置 ................................................................................................................. 19
第3章. dwr.xml配置 ........................................................................................................................... 20
3.1 纵览 ............................................................................................................................... 20
3.2 <init>标签 ....................................................................................................................... 20
3.3 <allow>标签 ................................................................................................................... 21
3.3.1 Creator ................................................................................................................... 21
3.3.2 Converter ............................................................................................................... 25
3.4 <signatures>标签 ........................................................................................................... 30
第4章. 整合 ....................................................................................................................................... 32
4.1 DWR与Servlet .............................................................................................................. 32
4.1.1 使用webContext的方法: .................................................................................... 32
4.1.2 方法选择 ................................................................................................................ 32
4.2 DWR与Spring ............................................................................................................... 34
4.2.1 让DWR和Spring一起工作的检查列表 ................................................................. 34
4.2.2 Spring Creator ....................................................................................................... 34
4.2.3 找到Spring配置文件 ............................................................................................. 34
4.2.4 使用Spring配置DWR ........................................................................................... 35
4.3 DWR与JSF ................................................................................................................... 36
4.3.1 JSF Creator ........................................................................................................... 36
4.3.2 Servlet Filter .......................................................................................................... 36
4.4 DWR与Struts ................................................................................................................ 37
4.4.1 Struts creator ......................................................................................................... 37
4.4.2 开始顺序 ................................................................................................................ 37
4.5 DWR与Weblogic或PageFlow ..................................................................................... 38
4.6 DWR与Hibernate ......................................................................................................... 39
4.6.1 让DWR和Hibernate一起工作的检查列表 ............................................................ 39
4.6.2 HibernateBeanConverter ....................................................................................... 39
4.6.3 Session管理 .......................................................................................................... 39
4.7 DWR与WebWork ......................................................................................................... 40
4.7.1 配置dwr.xml .......................................................................................................... 40
4.7.2 在JSP中导入脚本 ................................................................................................. 40
4.7.3 高级 ....................................................................................................................... 41
4.8 DWR与Acegi ................................................................................................................ 42
4.8.1 问题提出 ................................................................................................................ 42
4.8.2 解决方案 ................................................................................................................ 42
第5章. DWR中的JavaScript简介 ..................................................................................................... 44
5.1 简单的回调函数 .............................................................................................................. 44
5.2 调用元数据对象 .............................................................................................................. 45
5.3 查找回调函数 ................................................................................................................. 45
5.4 创造一个与Java对象匹配的Javascript对象 ................................................................. 46
第6章. engine.js 功能 ........................................................................................................................ 47
6.1 使用选项......................................................................................................................... 47
6.2 选项索引......................................................................................................................... 48
6.2.1 处理器(Handler) .................................................................................................... 48
6.2.2 调用处理器(Call Handler) .................................................................................... 48
6.2.3 Hooks (一个batch中可以注册多个hook) ............................................................. 49
6.2.4 全局选项(在单次调用或者批量调用中不可用) ....................................................... 49
6.2.5 废弃的选项 ............................................................................................................. 49
6.2.6 未来版本的选项 ..................................................................................................... 49
6.3 选项说明......................................................................................................................... 50
6.3.1 批量调用 ................................................................................................................ 50
6.3.2 顺序调用 ................................................................................................................ 50
6.3.3 错误警告和超时 ..................................................................................................... 50
6.3.4 远程调 Hooks ........................................................................................................ 51
6.3.5 远程调用选项 ......................................................................................................... 51
第7章. util.js 功能 .............................................................................................................................. 54
7.1 $() ................................................................................................................................. 54
7.2 addOptions and removeAllOptions ................................................................................ 54
7.3 addRows and removeAllRows ....................................................................................... 55
7.4 getText ........................................................................................................................... 56
7.5 getValue ......................................................................................................................... 56
7.6 getValues ....................................................................................................................... 57
7.7 onReturn ........................................................................................................................ 57
7.8 selectRange ................................................................................................................... 57
7.9 setValue ......................................................................................................................... 58
7.10 setValues ....................................................................................................................... 58
7.11 toDescriptiveString ......................................................................................................... 58
7.12 useLoadingMessage ...................................................................................................... 58
7.13 Submission box .............................................................................................................. 61
第8章. DWR进阶 ............................................................................................................................... 63
8.1 DWR Annotations ........................................................................................................ 63
8.1.1 初始配置 ................................................................................................................ 63
8.1.2 远程访问类 ............................................................................................................. 63
8.1.3 对象转换 ................................................................................................................ 64
8.2 错误和异常处理 .............................................................................................................. 64
8.2.1 错误处理 ................................................................................................................ 64
8.2.2 异常 ....................................................................................................................... 65
8.2.3 找出更多的信息 ..................................................................................................... 65
8.3 传递额外的数据到callback函数 .................................................................................... 66
8.4 从其他的URL读取数据 ................................................................................................. 67
8.5 安全 ............................................................................................................................... 68
第9章. 范例精讲 ................................................................................................................................ 71
9.1 购物车 ............................................................................................................................ 71
9.1.1 介绍 ....................................................................................................................... 71
9.1.2 实现目录 ................................................................................................................ 72
9.1.3 测试部署 ................................................................................................................ 74
9.1.4 调用远程对象 ......................................................................................................... 75
9.1.5 实现购物车 ............................................................................................................. 77
9.1.6 调用远程的 Cart 方法 ........................................................................................... 79
9.1.7 演示结果 ................................................................................................................ 81
9.1.8 总结 ....................................................................................................................... 81
第10章. 附录 ............................................................................................................................... 83
10.1 常见问题......................................................................................................................... 83
10.1.1 TransformerFactoryConfigurationError .................................................................. 83
10.1.2 XML解析错误 ........................................................................................................ 83
10.1.3 使用weblogic的类路径问题 .................................................................................. 83
10.1.4 没有cookies的情况下用DWR .................................................................... 84
10.2 JavaScript高级应用 ....................................................................................................... 85
10.2.1 用变量操纵函数 ..................................................................................................... 85
10.2.2 高阶函数 ................................................................................................................ 86
10.2.3 动态类型 ................................................................................................................ 87
10.2.4 灵活的对象模型 ..................................................................................................... 89
10.2.5 本节总结 ................................................................................................................ 91
第1章. DWR入门
1.1 简介
DWR是一个可以允许你去创建AJAX WEB站点的JAVA开源库。它可以让你在浏览器中的Javascript代
码调用Web服务器上的Java代码,就像在Java代码就在浏览器中一样。
DWR包含2个主要部分:
. 一个运行在服务器端的Java Servlet,它处理请求并且向浏览器发回响应。
. 运行在浏览器端的JavaScript,它发送请求而且还能动态更新网页。
DWR工作原理是通过动态把Java类生成为Javascript。它的代码就像Ajax魔法一样,你感觉调用就像发
生在浏览器端,但是实际上代码调用发生在服务器端,DWR负责数据的传递和转换。这种从Java到
JavaScript的远程调用功能的方式使DWR用起来有种非常像RMI或者SOAP的常规RPC机制,而且DWR
的优点在于不需要任何的网页浏览器插件就能运行在网页上。
Java从根本上讲是同步机制,然而AJAX却是异步的。所以你调用远程方法时,当数据已经从网络上返回
的时候,你要提供有反调 (callback) 功能的DWR。
这个图片显示了DWR如何选择一个下拉列表的内容作为JavaScript 的onclick事件的结果。
DWR动态在JavaScript里生成一个AjaxService类,去匹配服务气端的代码。由eventHandler去调用它,
然后DWR处理所有的远程细节,包括倒置 (converting) 所有的参数以及返回Javascript和Java之的
值。在示例中,先在eventHandler方法里调用AjaxService的getOptions() 方法,然后通过反调 (callback)
方法populateList(data) 得到返回的数据,其中data就是String[]{"1", "2", "3"},最后再使用DWR utility 把
data加入到下拉列表。
好了,DWR介绍完了,现在大家肯定很想知道如何做出第一个DWR吧!然后我们在下一章节以一个
HelloWorld示例带领大家入门。
1.2 第一个DWR程序:Hello World
有2中方法可以帮助你入门DWR,一个方法是去下载WAR文件并且去完整看一下代码,但是这样并不能
帮助你发现DWR是如何简单地集成到你当前地WEB应用,所以以下几个简单地步骤推荐看一下:
1.2.1 将DWR放入你的工程
1) 从官方网站下载dwr.jar包。然后将它放在你webapp的WEB-INF/lib目录下。
2) 将下载的dwr-版本号-src.zip \java\org\directwebremoting内的engine.js和util.js放入WEB应用
中,比如js文件夹下。
1.2.2 编辑配置文件
1. web.xml
以下几行代码必须被添加到WEN-INF/web.xml文件中。注意,要把<servlet>和其他<servlet>放在一起,
<servlet-mapping>要和其他<servlet-mapping>放在一起
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class> org.directwebremoting.servlet.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>
2. dwr.xml
在web.xml的同一目录下,创建dwr.xml,并且将要被调用的java类写入其中。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting
2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="service">
<param name="class" value="helloWorld.Service" />
</create>
</allow>
</dwr>
1.2.3 编写service
就像没有dwr一样,写一个简单类并加一个方法
是
package helloWorld;
public class Service {
public String sayHello(String yourName) {
//可以是访问数据库的复杂代码
return "Hello World " + yourName;
}
}
1.2.4 测试DWR
将代码放入应用服务器(比如Tomcat),启动。
然后在地址栏输入http://localhost:8080/你的工程/dwr
然后点击service,会看到刚才写的sayHello()的方法,输入自己的名字然后点击“Execute”,如果发现
确实是正确的返回结果,说明测试通过了,可以进入下一步了。
1.2.5 编写一个jsp
接下来最后一步就是创建一个jsp文件
1) 要引用几个dwr的js,其中engine.js必须要,如果需要用到dwr提供的一些方便的工具要引用util.js
2) 然后还要引用dwr自动生成的js,dwr/interface/service.js,注意js名字要和dwr.xml配置的一样
3) js里的service.sayHello和java类的那个有一点区别,多了个参数,用来callback返回的数据
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<title>My JSP 'first_dwr.jsp' starting page</title>
<script type='text/javascript' src='js/util.js'></script>
<script type='text/javascript' src='js/engine.js'></script>
<script type='text/javascript' src='dwr/interface/service.js'>
</script>
<script type="text/javascript">
function firstDwr(){
service.sayHello("Jorwen",callBackHello);
}
function callBackHello(data){
alert(data);
}
</script>
</head>
<body>
<input type="button" name="button" value="测试" onclick="firstDwr()">
</body>
</html>
地址栏输入http://localhost:8080/你的工程/first_dwr.jsp
显示的结果如下:
1.3 本章总结
相信看了此章节,大家一般都能做出这个实例来,也算是DWR刚入门了,在以后的教程里将详细介绍DWR
各个功能。帮助大家能开发出任何Ajax需求的功能来。更多进阶的例子可以参考范例精讲,您也可以通过
看范例学习DWR然后有疑问再查看该文档的相关章节。
第2章. web.xml配置
2.1 主要配置
要加入到你的web.xml最少的代码就是简单地去申明DWR servlet,没有它DWR就不起作用。
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
在DWR2.x里,DwrServlets是类org.directwebremoting.servlet.DwrServlet ,尽管
uk.ltd.getahead.dwr.DWRServlet仍然可以用。在DWR 1.x你不得不使用后者。
有些额外的servlet参数,在有些地方很重要。尤其debug参数
这个扩展DWR的标准结构是使用<init-params>。放在<servlet>内,就像如下使用
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
另外,启动服务时,如果报如下错。
java.lang.IllegalArgumentException: DefaultContainer can't find a
classes
是DWR2.0 加入了JDK5的注释(annotations).DwrServlet初始化的时候会去检查注释的类,找不到就
抱错了。如果你不用annotations也可以忽略掉这个错误。不过看起来总是不爽。解决方案如下
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
</servlet>
2.2 常用<init-param>参数列表
2.2.1 安全参数
allowGetForSafariButMakeForgeryEasier
开始版本:2.0
默认值:false
描述:设置成true使DWR工作在Safari 1.x , 会稍微降低安全性。
crossDomainSessionSecurity
开始版本:2.0
默认值:true
描述:设置成false使能够从其他域进行请求。注意,这样做会在安全性上有点冒险,参考一下这篇文章,
在没有理解这个后果前不要设置成为false。
debug
开始版本:1.0
默认值:false
描述:设置成true使DWR能够debug和进入测试页面
scriptSessionTimeout
开始版本:2.0
默认值:1800000(30分钟)
描述:script session 的超时设置
maxCallCount
开始版本:2.0rc2 和 1.1.4
默认值:20
描述:一次批量(batch)允许最大的调用数量。(帮助保护Dos攻击)
2.2.2 Ajax服务器加载时保护参数
pollAndCometEnabled
开始版本:2.0
默认值:false
描述:设置成true能增加服务器的加载能力,尽管DWR有保护服务器过载的机制。
maxWaitingThreads
开始版本:2.0
默认值:100
描述:最大等待线程数量。
preStreamWaitTime
开始版本:2.0
默认值:29000(单位:毫秒)
描述:对一个打开流前的反应,等待的最大时间
postStreamWaitTime
开始版本:2.0
默认值:1000(单位:毫秒)
描述:对一个打开流后的反应,等待的最大时间
2.2.3 其他参数
ignoreLastModified
开始版本:2.0
默认值:false
描述:默认值支持最后修改,这样就允许服务器端对客户端请求较少资源。设置为true就能屏蔽支持。
scriptCompressed
开始版本:1.1
默认值:false
描述:DWR能够执行简单的压缩,设置为true可以激活此功能。另外还有一个未公开的有关系的重要参
数“compressionLevel”,此参数允许你配置压缩类型。查看这里得到更多详细资料。
sessionCookieName
开始版本:2.0
默认值:JSESSIONID
描述:DWR通过检查文档和提取当前session ID支持URL重写。一些servlet引擎使用非标准的cookie
名。参数允许你改变默认值。
welcomeFiles
开始版本:2.0
默认值:index.html, index.htm, index.jsp
描述:类似于web.xml的<welcome-file-list>标签
2.3 日志配置
DWR工作在JDK1.3中不支持java.util.logging,但我们并不强迫任何人都去使用commons-logging或者
log4j,所以在使用HttpServlet.log()方法时DWR将正常工作,如果没有日志类的话。然而如果DWR可以
使用,那么它将使用日志。
Commoms-Logging
由于大多数servlet容器都使用它,几乎每个人都将使用commons-logging。所以如果你的webapp不明确
使用commons-logging,它将被默认设为可以使用。
在这些日志将被一些配置文件所约束,比如java.util.logging或者log4j,可以去查看他们各自的文档获得
详情。
HttpServlet.log()
如果你正在使用HttpServlet.log(), 以下的代码用来控制DWR日志
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
值可以是:FATAL,ERROR,WARN(默认),INFO,DEBUG
2.4 多个dwr.xml配置和J2EE角色定义
一般来说只需要一个dwr.xml文件,并且会被设为默认位置WEB-INF/dwr.xml。所以你不需要配置。
有3个原因说明你为何需要指定不同位置的dwr.xml文件:
. 你想保持dwr.xml的文件请参照下面的例子
<param-value>WEB-INF/classes/com/yourco/dwr/dwr.xml</param-value>
. 你可以有很多的远程方法类并且希望指定文件。在这个例子里将指定不同文件开始配置,不同
的param-name将重复多次DWR将轮流读取它们。
. DWR能够使J2EE URL具有给与不同用户组不同权限的安全机制。通过起不同名字,URL和权
限。
就像如下例子去使用
<init-param>
<param-name>config*****</param-name>
<param-value>WEB-INF/dwr.xml</param-value>
<description>What config file do we use?</description>
</init-param>
用一个字符串”config” 作为开始,设置param-name,每个param-name必须不同。
<servlet>
<servlet-name>dwr-user-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>config-user</param-name>
<param-value>WEB-INF/dwr-user.xml</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>dwr-admin-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>config-admin</param-name>
<param-value>WEB-INF/dwr-admin.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-admin-invoker</servlet-name>
<url-pattern>/dwradmin/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dwr-user-invoker</servlet-name>
<url-pattern>/dwruser/*</url-pattern>
</servlet-mapping>
<security-constraint>
<display-name>dwr-admin</display-name>
<web-resource-collection>
<web-resource-name>dwr-admin-collection</web-resource-name>
<url-pattern>/dwradmin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>dwr-user</display-name>
<web-resource-collection>
<web-resource-name>dwr-user-collection</web-resource-name>
<url-pattern>/dwruser/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
2.5 插件配置
大多数DWR的功能是可以作为插件的,所以就通过替换默认的类可以改变DWR的功能。你可以通过包
含<init-param>去覆盖默认的实现。举个例子:
<init-param>
<param-name>
org.directwebremoting.extend.ServerLoadMonitor
</param-name>
<param-value>com.example.MyCustomServerLoadMonitor</param-value>
</init-param>
没有规定我们越过主要的版本丢弃这些接口,但是我们将尝试提供简单的升级路径。
DWR2.0插件
. org.directwebremoting.Container
. org.directwebremoting.WebContextFactory.WebContextBuilder
. org.directwebremoting.ServerContextFactory.ServerContextBuilder
. org.directwebremoting.servlet.UrlProcessor
. org.directwebremoting.extend.AccessControl
. org.directwebremoting.extend.AjaxFilterManager
. org.directwebremoting.extend.ConverterManager
. org.directwebremoting.extend.CreatorManager
. org.directwebremoting.extend.DebugPageGenerator
. org.directwebremoting.extend.HtmlCallMarshaller
. org.directwebremoting.extend.HtmlPollHandler
. org.directwebremoting.extend.PageNormalizer
. org.directwebremoting.extend.PlainCallMarshaller
. org.directwebremoting.extend.PlainPollHandler
. org.directwebremoting.extend.Remoter
. org.directwebremoting.extend.ScriptSessionManager
. org.directwebremoting.extend.ServerLoadMonitor
默认的实现大多数在org.directwebremoting.impl包,细节是在ContainerUtil.setupDefaults()指定的。
DWR1.1插件
. uk.ltd.getahead.dwr.AccessControl
. uk.ltd.getahead.dwr.Configuration
. uk.ltd.getahead.dwr.ConverterManager
. uk.ltd.getahead.dwr.CreatorManager
. uk.ltd.getahead.dwr.Processor
. uk.ltd.getahead.dwr.ExecutionContext
默认的实现大多数在uk.ltd.getahead.dwr.impl包
2.6 测试模式配置
通过添加如下参数,设置debug测试模式
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
在debug模式里,DWR将为每个allow的类(请看下面的dwr.xml配置章节)生成测试页面。这些能变得非
常有用帮助了解DWR能做什么和如何工作。这个模式也能警告你以防止javascript的保留字,或者重载问
题。
然而这个模式不应该被用在现场部署,因为他能给黑客或者攻击者许多关于服务器的详细信息。
第3章. dwr.xml配置
3.1 纵览
dwr.xml是你用来配置DWR的文件,默认是将其放入WEB-INF文件夹。
创建一个dwr.xml文件
dwr.xml有如下的结构:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting
2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
<!-- 仅当需要扩展DWR时才需要 -->
<init>
<creator id="..." class="..." />
<converter id="..." class="..." />
</init>
<!-- 没有它DWR什么也做不了 -->
<allow>
<create creator="..." javascript="..." />
<convert converter="..." match="..." />
</allow>
<!-- 有必要告诉DWR方法签名 -->
<signatures>...</signatures>
</dwr>
3.2 <init>标签
这个初始化部分申明被用来创建远程beans而且这个类能被用来以某种过程转换。大多数例子你将不需要
用它,如果你想去定义一个新的Creator或者Converter,就要在此被申明。
在init部分里有了定义只是告诉DWR这些扩展类的存在,给出了如何使用的信息。这时他们还没有被使
用。这种方式很像Java中的import语句。多数类需要在使用前先import一下,但是只有import语句并不
表明这个类已经被使用了。每一个creator和converter都用id属性,以便后面使用。
3.3 <allow>标签
allow部分定义了DWR能够创建和转换的类。
3.3.1 Creator
每一个在类中被调用的方法需要一个<create …>有若干类型的creator,使用“new”关键字或者Spring 框
架等。
create元素是如下的结构
<allow>
<create creator="..." javascript="..." scope="...">
<param name="..." value="..." />
<auth method="..." role="..." />
<exclude method="..." />
<include method="..." />
</create>
...
</allow>
1. creator属性
1).new:Java用“new”关键字创造对象
是DWR默认的creator,如下所示
<create id="new" class="org.directwebremoting.create.NewCreator"/>
没有必要把它加入dwr.xml,它已经在DWR内部文件了。
这个creator将使用默认构造器创建类的实例,以下是用new创建器的好处
. 安全:DWR创造的对象生存的时间越短,多次调用中间的值不一致的错误机会越少。
. 内存消耗低: 如果你的站点用户量非常大,这个创造器可以减少VM的内存溢出。
2).none: 它不创建对象,看下面的原因。 (v1.1+)
none创建器不创建任何对象,它会假设你不须要创建对象。有2个使用的原因:
. 你可能在使用的scope不是"page"(看上面),并在在前面已经把这个对象创建到这个scope中了,
这时你就不需要再创建对象了。
. 还有一种情况是要调用的方法是静态的,这时也不需要创建对象。DWR会在调用创建器之前先检
查一下这个方法是不是静态的。
对于上诉两种情况,你仍然需要class参数,用来告诉DWR它是在操作的对象类型是什么。
3). scripted: 通过BSF使用脚本语言创建对象,例如BeanShell或Groovy。
要使用这个创造器,你需要把一些辅助库放到WEB-INF/lib文件夹下:比如BSF的jar包,你要用
的脚本语言的jar包。
new创造器在DWR中已经默认声明了:
<creator id="script" class="uk.ltd.getahead.dwr.create.ScriptedCreator"/>
这个创造器用BSF来执行脚本得到Bean,例如:
<allow>
...
<create creator="script" javascript="EmailValidator">
<param name="language" value="beanshell" />
<param name="script">
import org.apache.commons.validator.EmailValidator;
return EmailValidator.getInstance();
</param>
</create>
...
</allow>
script创造器有如下参数:
参数
DWR版本
描述
language
1.0
脚本语言,字符串,例如'beanshell'. (必需)
script
1.0
要执行的脚本。 (必需,除非scriptPath参数存在)
scriptPath
1.1
脚本文件路径。 (必需,除非script参数存在)
reloadable
1.1
是否检测脚本文件的改动,以重新加载 (可选, 默认true)
class
1.0
创造出对象的类型(可选). 如果没有DWR通过创造器得到类型。
注意:
当一个类是用script创造出来的,并且scope是session或application,如果你的脚本改变,session中的
类和script中的类就不一致了。这样会出现错误。虽然web容器不用重启,但是用户需要先登出(或以某种
方式清空session),然后再登录。
当clazz参数不为空,并且用来创造新实例,DWR简单的调用 class.newInstance() 方法。这种方法是没
问题的,除非脚本正在用某个参数创建一个类,或者调用某个函数来配置这个类。 不幸的是,每次请求都
要重新运行script并造成上面的问题。
4). spring: 通过Spring框架访问Bean。
详情请见DWR与Spring整合
5). jsf: 使用JSF的Bean。 (v1.1+)
详情请见DWR与JSF整合
6). struts: 使用Struts的FormBean。 (v1.1+)
详情请见DWR与Struts整合
7). pageflow: 访问Weblogic或Beehive的PageFlow。 (v1.1+)
详情请见DWR与Weblogic或Beehive的PageFlow整合
8). ejb3:使用EJB3 session bean。(v2.0+)
一个正在实验的创造器,用来访问EJB Session beans。直到进行更多的测试和正式的维护,否则还
不能作为产品被使用。
如果你想写自己的creator,你必须在<init>里注册它。
2. javascript属性
在浏览器里给你创建的对象命名。避免使用JavaScript保留字。这个名字将在页面里作为js被导入,就像
第2章节的那个jsp:
dwr.xml
<create creator="new" javascript="service">
<param name="class" value="helloWorld.Service" />
</create>
html / jsp
<html>
<head>
…
<script type='text/javascript' src='dwr/interface/service.js'>
…
3. scope属性
和定义在servlet的scope一样大的范围,它允许你指定哪个bean是可以获得的。选项可以是:application,
session, request和page。这些值应该已经被开发者们熟悉了。
scope选项是可选的,默认为page, 使用session请求cookies。目前,DWR还不支持URL重写。
4. param元素
被用来指定创造器的其他参数,每种构造器各有不同。例如,"new"创造器需要知道要创建的对象类型是什
么。每一个创造器的参数在各自的文档中能找到。
5. include和exclude元素
允许一个创造器去限制进入类的方法。一个创造器必须指定include列表或exclude列表之一。如果是
include列表则暗示默认的访问策略是"拒绝",include中的每个方法就是允许访问的方法;如果是exclude
列表则暗示默认的访问策略是"允许",exclude中的每个方法就是拒绝访问的方法。
比如:
<create creator="new" javascript="Fred">
<param name="class" value="com.example.Fred" />
<include method="setWibble" />
</create>
说明你只能在DWR中使用Fred的是setWibble方法。
6. auth元素
允许你指定一个J2EE的角色作为将来的访问控制检查:
<create creator="new" javascript="Fred">
<param name="class" value="com.example.Fred" />
<auth method="setWibble" role="admin" />
</create>
7. 使用静态方法
DWR会在调用创建器之前先检查一下这个方法是不是静态的,如果是那么创造器不会被调用。很显然这个
逻辑适用于所有创造器,尽管如此"null"创造器是最容易配置的。
8. 使用单例类
对于单例类的创建,最好适用BeanShell和BSF来实例化对象。请参考scripted创造器。
9. DWR与HttpSessionBindingListeners
DWR1.x中存贮已经创造的Bean的方法需要注意,它在每次请求时都会调用相同的 setAttribute() 方法。
就是说,如果一个Bean在dwr.xml中的声明周期设置为session,再每次调用bean中的方法时,DWR
都会执行一次 session.setAttribute(yourBean) 。这看上去没有什么危害,但是如果你要使用servlet的事
件机制的,就是说用了HttpSessionBindingListener接口,你就会发现valueBound和valueUnbound事件
在每次调用时都会发生,而不是你想像的在bean被创建时以及session过期时。
DWR2 只在第一次创建对象时调用 setAttribute() 。
3.3.2 Converter
我们需要确认所有的参数能被转换。许多JDK提供的类型使你能够使用,但是你如果要转换你自己的代码,
就必须告诉DWR。一般是指JavaBean的参数需要一个<convert…>标签作为入口。
你不需要在dwr.xml中<allow>部分的<convert>中定义。它们默认支持。
. 所有主要的类型,boolean, int , double等等。
. 包装类,Boolean, Integer等等。
. java.lang.String
. java.util.Date 和 java.sql.Times,java.sql.Timestamp。
. 数组(存放以上类型的)
. 集合类型 (List, Set, Map, Iterator等等) (存放以上类型的)
. DOM对象(来自于DOM, XOM, JDOM和DOM4J)
1. 日期转换器
如果你有一个String(例如:“2001-02-11”)在Javascript,你想把它转换成Java日期。那么你有2种
选择,一是使用Date.parse()然后使用DataConverter传入服务器端,还有一种选择是把该String传入,
然后用java的SimpleDateFormat(或者其他的)来转换。
同样,如果你有个Java的Date类型并且希望在HTML使用它。你可以先用SimpleDateFormat把它转换
成字符串再使用。也可以直接传Date给Javascript,然后用Javascript格式化。第一种方式简单一些,尽
管浪费了你的转换器,而且这样做也会是浏览器上的显示逻辑受到限制。其实后面的方法更好,也有一些
工具可以帮你,例如:
. The Javascript Toolbox Date formatter
. Web Developers Notes on Date formatting
2. 数组转换器
数组实体不太容易理解。默认情况下DWR能转换所有原生类型的数组,还有所有marshallable对象的数
组。这些marshallable对象包括前面介绍的String和Date类型。match属性看上去很怪。
<convert converter="array" match="[Z"/>
<convert converter="array" match="[B"/>
<convert converter="array" match="[S"/>
<convert converter="array" match="[I"/>
<convert converter="array" match="[J"/>
<convert converter="array" match="[F"/>
<convert converter="array" match="[D"/>
<convert converter="array" match="[C"/>
<convert converter="array" match="[L*"/>
上面没有解释 * 的作用 - 它是通配符,表示匹配接下来的所有字符串。这也是DWR可以转换任意类型的
数组的原因。
3. bean和对象转换器
两个没有默认打开的转换器是Bean 和 Object 转换器。Bean转换器可以把POJO转换成Javascript的
接合数组(类似与Java中的Map),或者反向转换。这个转换器默认情况下是没打开的,因为DWR要获得
你的允许才能动你的代码。
Object转换器很相似,不同的是它直接应用于对象的成员,而不是通过getter和setter方法。下面的例子
都是可以用object来替换bean的来直接访问对象成员。
如果你有一个在 <create ...> 中声明的远程调用Bean。它有个一参数也是一个bean,并且这个bean有
一个setter存在一些安全隐患,那么攻击者就可能利用这一点。
你可以为某一个单独的类打开转换器:
<convert converter="bean" match="your.full.package.BeanName"/>
如果要允许转换一个包或者子包下面的所有类,可以这样写:
<convert converter="bean" match="your.full.package.*"/>
显而易见,这样写是允许转换所有的JavaBean:
<convert converter="bean" match="*"/>
. BeanConverter 和 JavaBeans 规范
用于被BeanConverter转换的Bean必须符合JavaBeans的规范,因为转换器用的是Introspection,
而不是Reflection。这就是说属性要符合一下条件:有getter和setter,setter有一个参数,并且这个
参数的类型是getter的返回类型。setter应该返回void,getter应该没有任何参数。setter没有重载。
以上这些属于常识。就在eclipse里自动为每个属性添加setter,getter那种类型,如果你用的不是
JavaBean,那么你应该用ObjectConverter.
. 设置Javascript变量
DWR可以把Javascript对象(又名maps,或联合数组)转换成JavaBean或者Java对象。例子:
public class Remoted {
public void setPerson(Person p) {
// ...
}
}
public class Person {
public void setName(String name) { ... }
public void setAge(int age) { ... }
// ...
}
如果这个Remoted已经被配置成Creator了,Persion类也定义了BeanConverter,那么你可以通过下面
的方式调用Java代码:
var p = { name:"Fred", age:21 };
Remoted.setPerson(p);
. 限制转换器
就像你可以在creator的定义中剔出一些方法一样,converter也有类似的定义。
限制属性转换仅仅对于Bean有意义,很明显原生类型是不要需要这个功能的,所以只有
BeanConverter及其子类型(HibernateBeanConverter))有这个功能。
语法是这样的:
<convert converter="bean" match="com.example.Fred">
<param name="exclude" value="property1, property2" />
</convert>
这就保证了DWR不会调用 fred.getProperty1() 和fred.getProperty2两个方法。另外如果你喜欢"白
名单"而不是"黑名单"的话:
<convert converter="bean" match="com.example.Fred">
<param name="include" value="property1, property2" />
</convert>
安全上比较好的设计是使用"白名单"而不是"黑名单"。
. 访问对象的私有成员
通过'object'转换器的参数的一个名为force的参数,可以让DWR通过反射来访问对象私有成员。
语法是这样的:
<convert converter="object" match="com.example.Fred">
<param name="force" value="true" />
</convert>
直到DWR1.1.3,这里有一个bug,public的field反而不能被发现,所以你需要在public成员上设置
force=true。
4. 集合类型转换器
有个两个默认的转换器,针对Map和Collection:
<convert converter="collection" match="java.util.Collection"/>
<convert converter="map" match="java.util.Map"/>
一般来说这些转换器可以递归转换它们的内容。
但是也有两点不足之处:
. 仅仅用反射机制是没有方法明确集合里面是什么类型的。所以这两个转换器不能把集合里面的东西转
换成有意义的Javascript对象。
. 不能明确是那种类型的集合。 虽然我们不能让他们自动的起作用,我们可以在dwr.xml中用
signatures语法声明它们类型,使之正确转换。
5. 枚举类型转换器
枚举类型转换器默认是没有打开的。它在Java5中的Enum和Javascript的String之间进行转换。这个转
换器默认关闭是因为DWR要在转换你的代码之前得到你的同意。
枚举类型转换器是DWR 1.1版以后才支持的。
你可以这样设置来打开这个转换器:
<convert converter="enum" match="your.full.package.EnumName"/>
设置Javascript,一个简单的例子。假设你有下面的Java代码:
public class Remoted {
public void setStatus(Status p) {
// ...
}
}
enum Status {
PASS, FAIL,
}
如果Remoted类已经配置好Creator,并且Status枚举类型已经设置了EnumConverter。那么你就可以
在javascript中这样调用:
Remoted.setStatus("PASS");
6. DOM 对象
DWR可以自动转换来之DOM,DOM4J,JDOM和XOM的DOM树。你可以简单得用上面这些类库返回一
个Document、Element或者Node,DWR会把他们自动转换成浏览器的DOM对象。
在程序启动的时候会有一个常见的关于JDOM转换器的警告,你可以放心的忽略它,除非你要用JDOM:
INFO: Missing classdef for converter 'jdom'. Failed to load
uk.ltd.getahead.dwr.convert.JDOMConverter. Cause: org/jdom/Document
因为DWR没有办法知道你是否想用JDOM,所以这个信息设在INFO级别的。
如果你曾经尝试过使用JDOM,你会意识到在这种情况下这个转换器不可用的 - 这也是我们显示这个信息
的原因。
exist-db.org,我相信DWR能同exist-db很好的工作,因为它是建立在W3C DOM之上的,而DWR也支
持这个。
3.4 <signatures>标签
DWR使用反射机制在转换过程中找到它应该使用的类型。有时候类型的信息无法获得,在这种情况下你要
在此处用方法签名给予暗示。
signatures段使DWR能确定集合中存放的数据类型。例如下面的定义中我们无法知道list中存放的是什么
类型。
public class Check {
public void setLotteryResults(List nos)
{
...
}
}
signatures段允许我们暗示DWR应该用什么类型去处理。格式对以了解JDK5的泛型的人来说很容易理
解。
<signatures>
<![CDATA[
import java.util.List;
import com.example.Check;
Check.setLotteryResults(List<Integer> nos);
]]>
</signatures>
DWR中又一个解析器专门来做这件事,所以即便你的环境时JDK1.3 DWR也能正常工作。
解析规则基本上会和你预想规则的一样(有两个例外),所以java.lang下面的类型会被默认import。
第一个是DWR1.0中解析器的bug,某些环境下不能返回正确类型。所以你也不用管它了。
第二个是这个解析器时"阳光(sunny day)"解析器。就是说它非常宽松,不想编译器那样严格的保证你一定
正确。所以有时它也会允许你丢失import:
<signatures>
<![CDATA[
import java.util.List;
Check.setLotteryResults(List<Integer>);
]]>
</signatures>
将来的DWR版本会使用一个更正式的解析器,这个编译器会基于官方Java定义,所以你最好不要使用太
多这个不严格的东西。
signatures段只是用来确定泛型参数中的类型参数。DWR会自己使用反射机制或者运行时类型确定类型,
或者假设它是一个String类型。所以:
不需要signatures - 没有泛型参数:
public void method(String p);
public void method(String[] p);
需要signatures - DWR不能通过反射确定:
public void method(List<Date> p);
public void method(Map<String, WibbleBean> p);
不需要signatures - DWR能正确的猜出:
public void method(List<String> p);
public void method(Map<String, String> p);
不需要signatures - DWR可以通过运行时类型确定:
public List<Date> method(String p);
没有必要让Javascript中的所有对象的key都是String类型 - 你可以使用其他类型作为key。但是他们在
使用之前会被转换成String类型。DWR1.x用Javascript的特性把key转换成String。DWR2.0可能会用
toString()方法,在服务段进行这一转换。
第4章. 整合
4.1 DWR与Servlet
有2个Java类你一般需要用在DWR中,是webContext和WebContextFactory
在DWR 1.x 它们在uk.ltd.getahead.dwr 包, DWR 2.0+在org.directwebremoting包。这2个类给与你
访问标准Http servlet对象的入口。这些对象是:
. HttpServletRequest
. HttpServletResponse
. HttpSession
. ServletContext
. ServletConfig
4.1.1 使用webContext的方法:
import uk.ltd.getahead.dwr.WebContext;
import uk.ltd.getahead.dwr.WebContextFactory;
//
WebContext ctx = WebContextFactory.get();
req = ctx.getHttpServletRequest();
处理Http request和response做为只读是非常重要的。因为,当Http headers也许会通过,那么有些浏
览器会忽略它们(比如IE忽略缓存参数)。任何尝试改变Http body将会导致DWR错误。
WebContext使用一个本地线程变量,所以你能使用以上的代码放在任何地方。
也可以看一下 DWR的Java文档 ,或者详细看一下 WebContext 。
WebContext代替了DWR1.1中的ExecutionContext。
4.1.2 方法选择
在没有写依赖于DWR的代码时,要能够访问Http servlet对象是可以做到的(比如HttpServletRequest,
HttpServletResponse, HttpSession, ServletContext or ServletConfig)。DWR将自动填充它。
举个例子:
public class Remote {
public void method(int param, ServletContext cx, String s) { ... }
}
然后你将可以从Javascript中通访问它尽管没有ServletContext参数:
Remote.method(42, "test", callback);
DWR将为你填充这个参数。
对这个方法这里有个小小的警告,你要保证你的没有把’callback function’作为第一个参数,而应该把它作
为最后一个参数,或者作为元数据对象
4.2 DWR与Spring
4.2.1 让DWR和Spring一起工作的检查列表
1. 确认你用的是最新版的DWR。Spring创造器已经有了变化,所以你最好检查一下DWR的最新版本。
2. 确认你的Spring的Bean在DWR外面运行良好。
3. 配置DWR和Spring一起工作。 (看下面)
4. 查看演示页面: http://localhost:8080/[ YOUR-WEBAPP ]/dwr ,检查spring的Bean是否出现。
DWR对于Spring没有运行期依赖,所以如果你不使用Spring那么Spring的支持不会产生任何影响到。
4.2.2 Spring Creator
这个创造器会在spring beans.xml里查询beans,并且会使用Spring去创建它们。如果你已经使用Spring,
这个创造器会非常有用。否则将完全没有任何用处。
要让DWR使用Spring创造器去创建和远程调用beans,要像如下所示:
<allow>
...
<create creator="spring" javascript="Fred">
<param name="beanName" value="Shiela" />
</create>
</allow>
4.2.3 找到Spring配置文件
有3个方法可以找到Spring配置文件
1. ContextLoaderListener
最简单的用法使从Spring-MVC里使用
org.springframework.web.context.ContextLoaderListener
你不必使用整个Spring-MVC去确认这个普遍的解决方案使多么好。只要再你的web.xml里配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
2. 使用location参数
如果你喜欢指定的beans.xml在你的dwr.xml文件中,那么你能使用location参数。你可以指定你希望数
量的,必须有唯一的以”location”开头的命名。比如:location-1, location-2。这些locations是作为参数传
到Spring的ClassPathXmlApplicationContext:
<allow>
...
<create creator="spring" javascript="Fred">
<param name="beanName" value="Shiela" />
<param name="location" value="beans.xml" />
</create>
</allow>
3. 设置beenFactory目录
Spring创造器有一个静态的方法:setOverrideBeanFactory(BeanFactory),这个方法提供一个可编程的方
式去覆盖任何BeanFactories。
4.2.4 使用Spring配置DWR
Bram Smeets写了一个有意思的blog,教你配置DWR使用beans.xml代替WEB-INF/web.xml。
我也对于如何在beans.xml中指定dwr.xml很感兴趣,尽管这看上去有些Spring传染病的感觉。
4.3 DWR与JSF
DWR包括两个JSF的扩展点,一个创造器和一个ServletFilter。
4.3.1 JSF Creator
DWR1.1中有一个体验版的JsfCreator。你可以在dwr.xml中这样使用:
<allow>
...
<create creator="jsf" javascript="ScriptName">
<param name="managedBeanName" value="beanName" />
<param name="class" value="your.class" />
</create>
...
</allow>
这将允许你通过DWR调用ManagedBean。
4.3.2 Servlet Filter
DWR/Faces 过滤器允许你不在JSF的生命周期里调用FacesContext中的Bean。
要使用JsfCreator,你应该把DWR/Faces过滤器加到web.xml中。
<filter>
<filter-name>DwrFacesFilter</filter-name>
<filter-class>
uk.ltd.getahead.dwr.servlet.FacesExtensionFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>DwrFacesFilter</filter-name>
<url-pattern>/dwr/*</url-pattern>
</filter-mapping>
这两个需要放在web.xml中与其他的filter和filter-mapping放在一起。
4.4 DWR与Struts
DWR能够和任何框架结合。这个网站是个极端巧妙的证据,因为它把DWR使用在Drupal(PHP)。
DWR和Struts整合有2个层次。最基础的层次就是同时使用这两个框架,这是非常容易的,但是这样就
不允许在DWR和Struts之间共享Action了。
DWR能构调用任何方法,所以你也能从调用一个Struts action,除非你不想那么做。ActionForm的内容
是什么,当返回ActionForward时DWR怎么做?
一个比较好方法是重构你想调用的Action,提取出Action的逻辑。DWR和你的Action就可以同时调用相
同的方法了。
4.4.1 Struts creator
DWR1.1增加了一个StrutsCreator。你可以在dwr.xml中这样使用:
<allow>
...
<create creator="struts" javascript="ScriptName">
<param name="formBean" value="formBeanName" />
</create>
...
</allow>
这样你就能从DWR调用FormBeans。
4.4.2 开始顺序
如果正在使用Struts创造器,那么你应该确保Struts初始化在DWR之前。你要保证你在web.xml里有一
个<load-on-startup>的值,其中Struts的值比DWR设置地要低。
4.5 DWR与Weblogic或PageFlow
DWR中有一个创造器可以和Weblogic或者Beehive中的PageFlow一起工作。
PageFlow creator
DWR1.1中加入了一个PageFlowCreator。你可以这样使用:
<allow>
...
<create creator="pageflow" javascript="ScriptName"/>
...
</allow>
4.6 DWR与Hibernate
4.6.1 让DWR和Hibernate一起工作的检查列表
1. 确保你使用的是最新的DWR。Hibernate转换器是新东西,所以你需要下载最新版本
2. 确保你的Hiberante在没有DWR的时候工作正常。
3. 如果是Spring和Hibernate一起使用,那么你最好先了解一下如何将整合Spring。
4. 配置DWR,使之与Hibernate一起工作。 (看下面)。
5. 查看演示页面:http://localhost:8080/YOUR-WEBAPP/dwr,确定Spring的Bean可以出现。
4.6.2 HibernateBeanConverter
除了我们可以决定是否要使用lazy loaded属性,这个转换器非常类似于标准的BeanConverter。
在DWR1.1 Hibernate转换器被称为“hibernate”并且作用在hibernate2, 在DWR2.x有2个转换器被
称为“hibernate2”并且作用在hibernate3。
使用HibernateBeanConverter也许有点风险,原因如下:
. 结构:HibernateBeanConverter不符合MVC模式,所以不能把对象在数据曾和表现曾之间进行隔离。
这个风险可以通过在上面加上独立的bean来减轻。
. 性能: DWR试图通过相同的序列化方式来转换所有可以得到的属性(除了DWR仅仅读JavaBean属
性的时候)。所以可能会出现通过HTTP序列化了你的整个数据的情况。通常这并不是你想要的。要
减少这一风险可以使用BeanConverter(HibernateBeanConverter衍生于它)的排除某些属性的功能,
如下所示:
<param name="exclude" value="propertyToExclude1, propertyToExclude2"/>
HibernateBeanConverter会尝试不去读取没有初始化的属性。如果你只是想读取所有的东西那么应该使用
BeanConverter。
建议使用Hibernate3,实际上Hibernate2的情况,你会发现你得到的都是空的Bean。
4.6.3 Session管理
如果你使用Hibernate对象,你需要知道每一个DWR请求都是一个新的Servlet请求,所以你需要保证为
每个请求打开一个Hiberante的Session。
如果你用Spring,那么可以很方便的使用Spring里面的OpenSessionInViewFilter,它可以保证为每个请
求打开一个Hiberante的Session。类似的解决方案在其它Framework中也存在。
4.7 DWR与WebWork
WebWork支持在DWR2.0m3以后才有。
要可以通过DWR调用WW的Action,要做两件事。
4.7.1 配置dwr.xml
你必须在dwr的配置文件中加入这样的配置:
<create creator="none" javascript="DWRAction">
<param name="class"
value="org.directwebremoting.webwork.DWRAction" />
<include method="execute" />
</create>
<convert converter="bean"
match="org.directwebremoting.webwork.ActionDefinition">
<param name="include"
value="namespace,action,method,executeResult" />
</convert>
<convert converter="bean"
match="org.directwebremoting.webwork.AjaxResult" />
这样你AjaxWebWork Action调用返回一个action实例(而不是文字)。然后你必须包括action对象的转换
器定义(package级别或单独action)。
<convert converter="bean" match="your_action_package.*"/>
4.7.2 在JSP中导入脚本
下面这些代码开启DWR调用Action的功能。你还要导入DWRActionUtil.js脚本(在你的web脚本路径中)
像这样在JS中调用Action:
DWRActionUtil.execute(id, params, callback, [displayMessage]);
1. id 参数
. actionUri: 要调用action的URI(没有 .action). 例如:
DWRActionUtil.execute('/ajax/TestFM', 'myform', 'doOnTextResult');
. actionDefinitionObject: 在xwork.xml中定义的action对象. 必须指定下面的内容:
. namespace: xwork.xml中action的名称空间
. action: xwork.xml中action的名字
. executeResult: true|false (是否执行action的结果, 如果false直接返回action实例)
例如:
DWRActionUtil.execute({
namespace:'/ajax',
action:'TestJS',
executeResult:'true'
}, 'data', doOnJSResult, "stream...");
2. params 参数
. emptyParams: 传递{}忽略任何参数。例子:
DWRActionUtil.execute('/ajax/TestFM', {}, doOnJSResult, "stream...");
. fieldId: 被转换为action调用参数的字段的id。
例子:
<input id="mytext" name="mytext" value="some value" type="text"/>
DWRActionUtil.execute('/ajax/TestFM', 'mytext', doOnJSResult,
"stream...");
. formId: 表单的id. 所有的input值被转换为action调用参数。
Note : 如果你的action使用了parameter拦截器,那么你的action会得到正确的参数值,请参考WebWork
的文档。
3. callback 参数
. callbackFunction: 在DWR中,这个函数在
DWR 2.0
方佳玮 编著
部分原创/部分整理/部分翻译
版权声明
本书目前仅发行网络版,完全免费,转载请注明作者信息。任何出版社或个人未经作者
允许不得出版印刷。
另外如果发现本人的部分内容有所抄袭,请不要来找我理论,我本来做的就是公益事情。
版权所有,侵仅必究。
参考网站及资料
DWR官方网站
http://getahead.ltd.uk/dwr/
JavaScud Wiki
http://wiki.javascud.org/display/dwrcn/Home
IBM中国
http://www.ibm.com/developerworks/cn/
前言
Ajax向我们袭来的时候,很多写代码的程序员看到了Ajax的发展前景,但并不是每一
个程序员都能将页面与代码完美整合在一起,DOM、CSS、javascript让人眼花缭乱,不知
从何下手。
本书的读者必须有一定的Jsp,JavaScript,应用服务器(比如Tomcat)的基础和使用经
验,否则请在看此教程前先去了解一下。当然附录里有一些JavaScript的教程。
本书可以当作一本DWR完整的教程,也可以当作一本详细介绍DWR的“词典”,我
的目的只是通过本书,希望您能够了解一些DWR的基本知识、常用的用户界面组件、远程
方法调用等。并能够搭建DWR开发环境,实现DWR的快速开发。
非常感谢JavaScud Wiki网站,省去了我很多翻译时间,同时感谢网站的几位翻译人员。
由于本人也刚刚接触DWR,书中难免会有一些错误和表达不是太好的地方,请读者谅
解并提出您的宝贵意见。我很希望得到读者对本书的评价和建议。您可以把你在学习本书的
过程中所遇到的问题和建议发送到我的邮箱 jorwen.fang@gmail.com ,以便我对本书下一个
版本的更新,我会在第一时间给您回复。
感谢您阅读本书!希望这本书对你来说是一本有用的书。我是上海华东理工大学03届
计算机(金山)专业的方佳玮。
方佳玮
2007-01-22
目录
第1章. DWR入门 ................................................................................................................................ 8
1.1 简介 ................................................................................................................................. 8
1.2 第一个DWR程序:Hello World ....................................................................................... 9
1.2.1 将DWR放入你的工程 ............................................................................................. 9
1.2.2 编辑配置文件 ........................................................................................................... 9
1.2.3 编写service ........................................................................................................... 10
1.2.4 测试DWR .............................................................................................................. 10
1.2.5 编写一个jsp ........................................................................................................... 11
1.3 本章总结......................................................................................................................... 12
第2章. web.xml配置 .......................................................................................................................... 13
2.1 主要配置......................................................................................................................... 13
2.2 常用<init-param>参数列表 ............................................................................................. 14
2.2.1 安全参数 ................................................................................................................ 14
2.2.2 Ajax服务器加载时保护参数 ................................................................................... 14
2.2.3 其他参数 ................................................................................................................ 15
2.3 日志配置......................................................................................................................... 16
2.4 多个dwr.xml配置和J2EE角色定义 .............................................................................. 16
2.5 插件配置......................................................................................................................... 18
2.6 测试模式配置 ................................................................................................................. 19
第3章. dwr.xml配置 ........................................................................................................................... 20
3.1 纵览 ............................................................................................................................... 20
3.2 <init>标签 ....................................................................................................................... 20
3.3 <allow>标签 ................................................................................................................... 21
3.3.1 Creator ................................................................................................................... 21
3.3.2 Converter ............................................................................................................... 25
3.4 <signatures>标签 ........................................................................................................... 30
第4章. 整合 ....................................................................................................................................... 32
4.1 DWR与Servlet .............................................................................................................. 32
4.1.1 使用webContext的方法: .................................................................................... 32
4.1.2 方法选择 ................................................................................................................ 32
4.2 DWR与Spring ............................................................................................................... 34
4.2.1 让DWR和Spring一起工作的检查列表 ................................................................. 34
4.2.2 Spring Creator ....................................................................................................... 34
4.2.3 找到Spring配置文件 ............................................................................................. 34
4.2.4 使用Spring配置DWR ........................................................................................... 35
4.3 DWR与JSF ................................................................................................................... 36
4.3.1 JSF Creator ........................................................................................................... 36
4.3.2 Servlet Filter .......................................................................................................... 36
4.4 DWR与Struts ................................................................................................................ 37
4.4.1 Struts creator ......................................................................................................... 37
4.4.2 开始顺序 ................................................................................................................ 37
4.5 DWR与Weblogic或PageFlow ..................................................................................... 38
4.6 DWR与Hibernate ......................................................................................................... 39
4.6.1 让DWR和Hibernate一起工作的检查列表 ............................................................ 39
4.6.2 HibernateBeanConverter ....................................................................................... 39
4.6.3 Session管理 .......................................................................................................... 39
4.7 DWR与WebWork ......................................................................................................... 40
4.7.1 配置dwr.xml .......................................................................................................... 40
4.7.2 在JSP中导入脚本 ................................................................................................. 40
4.7.3 高级 ....................................................................................................................... 41
4.8 DWR与Acegi ................................................................................................................ 42
4.8.1 问题提出 ................................................................................................................ 42
4.8.2 解决方案 ................................................................................................................ 42
第5章. DWR中的JavaScript简介 ..................................................................................................... 44
5.1 简单的回调函数 .............................................................................................................. 44
5.2 调用元数据对象 .............................................................................................................. 45
5.3 查找回调函数 ................................................................................................................. 45
5.4 创造一个与Java对象匹配的Javascript对象 ................................................................. 46
第6章. engine.js 功能 ........................................................................................................................ 47
6.1 使用选项......................................................................................................................... 47
6.2 选项索引......................................................................................................................... 48
6.2.1 处理器(Handler) .................................................................................................... 48
6.2.2 调用处理器(Call Handler) .................................................................................... 48
6.2.3 Hooks (一个batch中可以注册多个hook) ............................................................. 49
6.2.4 全局选项(在单次调用或者批量调用中不可用) ....................................................... 49
6.2.5 废弃的选项 ............................................................................................................. 49
6.2.6 未来版本的选项 ..................................................................................................... 49
6.3 选项说明......................................................................................................................... 50
6.3.1 批量调用 ................................................................................................................ 50
6.3.2 顺序调用 ................................................................................................................ 50
6.3.3 错误警告和超时 ..................................................................................................... 50
6.3.4 远程调 Hooks ........................................................................................................ 51
6.3.5 远程调用选项 ......................................................................................................... 51
第7章. util.js 功能 .............................................................................................................................. 54
7.1 $() ................................................................................................................................. 54
7.2 addOptions and removeAllOptions ................................................................................ 54
7.3 addRows and removeAllRows ....................................................................................... 55
7.4 getText ........................................................................................................................... 56
7.5 getValue ......................................................................................................................... 56
7.6 getValues ....................................................................................................................... 57
7.7 onReturn ........................................................................................................................ 57
7.8 selectRange ................................................................................................................... 57
7.9 setValue ......................................................................................................................... 58
7.10 setValues ....................................................................................................................... 58
7.11 toDescriptiveString ......................................................................................................... 58
7.12 useLoadingMessage ...................................................................................................... 58
7.13 Submission box .............................................................................................................. 61
第8章. DWR进阶 ............................................................................................................................... 63
8.1 DWR Annotations ........................................................................................................ 63
8.1.1 初始配置 ................................................................................................................ 63
8.1.2 远程访问类 ............................................................................................................. 63
8.1.3 对象转换 ................................................................................................................ 64
8.2 错误和异常处理 .............................................................................................................. 64
8.2.1 错误处理 ................................................................................................................ 64
8.2.2 异常 ....................................................................................................................... 65
8.2.3 找出更多的信息 ..................................................................................................... 65
8.3 传递额外的数据到callback函数 .................................................................................... 66
8.4 从其他的URL读取数据 ................................................................................................. 67
8.5 安全 ............................................................................................................................... 68
第9章. 范例精讲 ................................................................................................................................ 71
9.1 购物车 ............................................................................................................................ 71
9.1.1 介绍 ....................................................................................................................... 71
9.1.2 实现目录 ................................................................................................................ 72
9.1.3 测试部署 ................................................................................................................ 74
9.1.4 调用远程对象 ......................................................................................................... 75
9.1.5 实现购物车 ............................................................................................................. 77
9.1.6 调用远程的 Cart 方法 ........................................................................................... 79
9.1.7 演示结果 ................................................................................................................ 81
9.1.8 总结 ....................................................................................................................... 81
第10章. 附录 ............................................................................................................................... 83
10.1 常见问题......................................................................................................................... 83
10.1.1 TransformerFactoryConfigurationError .................................................................. 83
10.1.2 XML解析错误 ........................................................................................................ 83
10.1.3 使用weblogic的类路径问题 .................................................................................. 83
10.1.4 没有cookies的情况下用DWR .................................................................... 84
10.2 JavaScript高级应用 ....................................................................................................... 85
10.2.1 用变量操纵函数 ..................................................................................................... 85
10.2.2 高阶函数 ................................................................................................................ 86
10.2.3 动态类型 ................................................................................................................ 87
10.2.4 灵活的对象模型 ..................................................................................................... 89
10.2.5 本节总结 ................................................................................................................ 91
第1章. DWR入门
1.1 简介
DWR是一个可以允许你去创建AJAX WEB站点的JAVA开源库。它可以让你在浏览器中的Javascript代
码调用Web服务器上的Java代码,就像在Java代码就在浏览器中一样。
DWR包含2个主要部分:
. 一个运行在服务器端的Java Servlet,它处理请求并且向浏览器发回响应。
. 运行在浏览器端的JavaScript,它发送请求而且还能动态更新网页。
DWR工作原理是通过动态把Java类生成为Javascript。它的代码就像Ajax魔法一样,你感觉调用就像发
生在浏览器端,但是实际上代码调用发生在服务器端,DWR负责数据的传递和转换。这种从Java到
JavaScript的远程调用功能的方式使DWR用起来有种非常像RMI或者SOAP的常规RPC机制,而且DWR
的优点在于不需要任何的网页浏览器插件就能运行在网页上。
Java从根本上讲是同步机制,然而AJAX却是异步的。所以你调用远程方法时,当数据已经从网络上返回
的时候,你要提供有反调 (callback) 功能的DWR。
这个图片显示了DWR如何选择一个下拉列表的内容作为JavaScript 的onclick事件的结果。
DWR动态在JavaScript里生成一个AjaxService类,去匹配服务气端的代码。由eventHandler去调用它,
然后DWR处理所有的远程细节,包括倒置 (converting) 所有的参数以及返回Javascript和Java之的
值。在示例中,先在eventHandler方法里调用AjaxService的getOptions() 方法,然后通过反调 (callback)
方法populateList(data) 得到返回的数据,其中data就是String[]{"1", "2", "3"},最后再使用DWR utility 把
data加入到下拉列表。
好了,DWR介绍完了,现在大家肯定很想知道如何做出第一个DWR吧!然后我们在下一章节以一个
HelloWorld示例带领大家入门。
1.2 第一个DWR程序:Hello World
有2中方法可以帮助你入门DWR,一个方法是去下载WAR文件并且去完整看一下代码,但是这样并不能
帮助你发现DWR是如何简单地集成到你当前地WEB应用,所以以下几个简单地步骤推荐看一下:
1.2.1 将DWR放入你的工程
1) 从官方网站下载dwr.jar包。然后将它放在你webapp的WEB-INF/lib目录下。
2) 将下载的dwr-版本号-src.zip \java\org\directwebremoting内的engine.js和util.js放入WEB应用
中,比如js文件夹下。
1.2.2 编辑配置文件
1. web.xml
以下几行代码必须被添加到WEN-INF/web.xml文件中。注意,要把<servlet>和其他<servlet>放在一起,
<servlet-mapping>要和其他<servlet-mapping>放在一起
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class> org.directwebremoting.servlet.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>
2. dwr.xml
在web.xml的同一目录下,创建dwr.xml,并且将要被调用的java类写入其中。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting
2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="service">
<param name="class" value="helloWorld.Service" />
</create>
</allow>
</dwr>
1.2.3 编写service
就像没有dwr一样,写一个简单类并加一个方法
是
package helloWorld;
public class Service {
public String sayHello(String yourName) {
//可以是访问数据库的复杂代码
return "Hello World " + yourName;
}
}
1.2.4 测试DWR
将代码放入应用服务器(比如Tomcat),启动。
然后在地址栏输入http://localhost:8080/你的工程/dwr
然后点击service,会看到刚才写的sayHello()的方法,输入自己的名字然后点击“Execute”,如果发现
确实是正确的返回结果,说明测试通过了,可以进入下一步了。
1.2.5 编写一个jsp
接下来最后一步就是创建一个jsp文件
1) 要引用几个dwr的js,其中engine.js必须要,如果需要用到dwr提供的一些方便的工具要引用util.js
2) 然后还要引用dwr自动生成的js,dwr/interface/service.js,注意js名字要和dwr.xml配置的一样
3) js里的service.sayHello和java类的那个有一点区别,多了个参数,用来callback返回的数据
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<title>My JSP 'first_dwr.jsp' starting page</title>
<script type='text/javascript' src='js/util.js'></script>
<script type='text/javascript' src='js/engine.js'></script>
<script type='text/javascript' src='dwr/interface/service.js'>
</script>
<script type="text/javascript">
function firstDwr(){
service.sayHello("Jorwen",callBackHello);
}
function callBackHello(data){
alert(data);
}
</script>
</head>
<body>
<input type="button" name="button" value="测试" onclick="firstDwr()">
</body>
</html>
地址栏输入http://localhost:8080/你的工程/first_dwr.jsp
显示的结果如下:
1.3 本章总结
相信看了此章节,大家一般都能做出这个实例来,也算是DWR刚入门了,在以后的教程里将详细介绍DWR
各个功能。帮助大家能开发出任何Ajax需求的功能来。更多进阶的例子可以参考范例精讲,您也可以通过
看范例学习DWR然后有疑问再查看该文档的相关章节。
第2章. web.xml配置
2.1 主要配置
要加入到你的web.xml最少的代码就是简单地去申明DWR servlet,没有它DWR就不起作用。
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
在DWR2.x里,DwrServlets是类org.directwebremoting.servlet.DwrServlet ,尽管
uk.ltd.getahead.dwr.DWRServlet仍然可以用。在DWR 1.x你不得不使用后者。
有些额外的servlet参数,在有些地方很重要。尤其debug参数
这个扩展DWR的标准结构是使用<init-params>。放在<servlet>内,就像如下使用
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
另外,启动服务时,如果报如下错。
java.lang.IllegalArgumentException: DefaultContainer can't find a
classes
是DWR2.0 加入了JDK5的注释(annotations).DwrServlet初始化的时候会去检查注释的类,找不到就
抱错了。如果你不用annotations也可以忽略掉这个错误。不过看起来总是不爽。解决方案如下
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
</servlet>
2.2 常用<init-param>参数列表
2.2.1 安全参数
allowGetForSafariButMakeForgeryEasier
开始版本:2.0
默认值:false
描述:设置成true使DWR工作在Safari 1.x , 会稍微降低安全性。
crossDomainSessionSecurity
开始版本:2.0
默认值:true
描述:设置成false使能够从其他域进行请求。注意,这样做会在安全性上有点冒险,参考一下这篇文章,
在没有理解这个后果前不要设置成为false。
debug
开始版本:1.0
默认值:false
描述:设置成true使DWR能够debug和进入测试页面
scriptSessionTimeout
开始版本:2.0
默认值:1800000(30分钟)
描述:script session 的超时设置
maxCallCount
开始版本:2.0rc2 和 1.1.4
默认值:20
描述:一次批量(batch)允许最大的调用数量。(帮助保护Dos攻击)
2.2.2 Ajax服务器加载时保护参数
pollAndCometEnabled
开始版本:2.0
默认值:false
描述:设置成true能增加服务器的加载能力,尽管DWR有保护服务器过载的机制。
maxWaitingThreads
开始版本:2.0
默认值:100
描述:最大等待线程数量。
preStreamWaitTime
开始版本:2.0
默认值:29000(单位:毫秒)
描述:对一个打开流前的反应,等待的最大时间
postStreamWaitTime
开始版本:2.0
默认值:1000(单位:毫秒)
描述:对一个打开流后的反应,等待的最大时间
2.2.3 其他参数
ignoreLastModified
开始版本:2.0
默认值:false
描述:默认值支持最后修改,这样就允许服务器端对客户端请求较少资源。设置为true就能屏蔽支持。
scriptCompressed
开始版本:1.1
默认值:false
描述:DWR能够执行简单的压缩,设置为true可以激活此功能。另外还有一个未公开的有关系的重要参
数“compressionLevel”,此参数允许你配置压缩类型。查看这里得到更多详细资料。
sessionCookieName
开始版本:2.0
默认值:JSESSIONID
描述:DWR通过检查文档和提取当前session ID支持URL重写。一些servlet引擎使用非标准的cookie
名。参数允许你改变默认值。
welcomeFiles
开始版本:2.0
默认值:index.html, index.htm, index.jsp
描述:类似于web.xml的<welcome-file-list>标签
2.3 日志配置
DWR工作在JDK1.3中不支持java.util.logging,但我们并不强迫任何人都去使用commons-logging或者
log4j,所以在使用HttpServlet.log()方法时DWR将正常工作,如果没有日志类的话。然而如果DWR可以
使用,那么它将使用日志。
Commoms-Logging
由于大多数servlet容器都使用它,几乎每个人都将使用commons-logging。所以如果你的webapp不明确
使用commons-logging,它将被默认设为可以使用。
在这些日志将被一些配置文件所约束,比如java.util.logging或者log4j,可以去查看他们各自的文档获得
详情。
HttpServlet.log()
如果你正在使用HttpServlet.log(), 以下的代码用来控制DWR日志
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
值可以是:FATAL,ERROR,WARN(默认),INFO,DEBUG
2.4 多个dwr.xml配置和J2EE角色定义
一般来说只需要一个dwr.xml文件,并且会被设为默认位置WEB-INF/dwr.xml。所以你不需要配置。
有3个原因说明你为何需要指定不同位置的dwr.xml文件:
. 你想保持dwr.xml的文件请参照下面的例子
<param-value>WEB-INF/classes/com/yourco/dwr/dwr.xml</param-value>
. 你可以有很多的远程方法类并且希望指定文件。在这个例子里将指定不同文件开始配置,不同
的param-name将重复多次DWR将轮流读取它们。
. DWR能够使J2EE URL具有给与不同用户组不同权限的安全机制。通过起不同名字,URL和权
限。
就像如下例子去使用
<init-param>
<param-name>config*****</param-name>
<param-value>WEB-INF/dwr.xml</param-value>
<description>What config file do we use?</description>
</init-param>
用一个字符串”config” 作为开始,设置param-name,每个param-name必须不同。
<servlet>
<servlet-name>dwr-user-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>config-user</param-name>
<param-value>WEB-INF/dwr-user.xml</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>dwr-admin-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>config-admin</param-name>
<param-value>WEB-INF/dwr-admin.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-admin-invoker</servlet-name>
<url-pattern>/dwradmin/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dwr-user-invoker</servlet-name>
<url-pattern>/dwruser/*</url-pattern>
</servlet-mapping>
<security-constraint>
<display-name>dwr-admin</display-name>
<web-resource-collection>
<web-resource-name>dwr-admin-collection</web-resource-name>
<url-pattern>/dwradmin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>dwr-user</display-name>
<web-resource-collection>
<web-resource-name>dwr-user-collection</web-resource-name>
<url-pattern>/dwruser/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
2.5 插件配置
大多数DWR的功能是可以作为插件的,所以就通过替换默认的类可以改变DWR的功能。你可以通过包
含<init-param>去覆盖默认的实现。举个例子:
<init-param>
<param-name>
org.directwebremoting.extend.ServerLoadMonitor
</param-name>
<param-value>com.example.MyCustomServerLoadMonitor</param-value>
</init-param>
没有规定我们越过主要的版本丢弃这些接口,但是我们将尝试提供简单的升级路径。
DWR2.0插件
. org.directwebremoting.Container
. org.directwebremoting.WebContextFactory.WebContextBuilder
. org.directwebremoting.ServerContextFactory.ServerContextBuilder
. org.directwebremoting.servlet.UrlProcessor
. org.directwebremoting.extend.AccessControl
. org.directwebremoting.extend.AjaxFilterManager
. org.directwebremoting.extend.ConverterManager
. org.directwebremoting.extend.CreatorManager
. org.directwebremoting.extend.DebugPageGenerator
. org.directwebremoting.extend.HtmlCallMarshaller
. org.directwebremoting.extend.HtmlPollHandler
. org.directwebremoting.extend.PageNormalizer
. org.directwebremoting.extend.PlainCallMarshaller
. org.directwebremoting.extend.PlainPollHandler
. org.directwebremoting.extend.Remoter
. org.directwebremoting.extend.ScriptSessionManager
. org.directwebremoting.extend.ServerLoadMonitor
默认的实现大多数在org.directwebremoting.impl包,细节是在ContainerUtil.setupDefaults()指定的。
DWR1.1插件
. uk.ltd.getahead.dwr.AccessControl
. uk.ltd.getahead.dwr.Configuration
. uk.ltd.getahead.dwr.ConverterManager
. uk.ltd.getahead.dwr.CreatorManager
. uk.ltd.getahead.dwr.Processor
. uk.ltd.getahead.dwr.ExecutionContext
默认的实现大多数在uk.ltd.getahead.dwr.impl包
2.6 测试模式配置
通过添加如下参数,设置debug测试模式
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
在debug模式里,DWR将为每个allow的类(请看下面的dwr.xml配置章节)生成测试页面。这些能变得非
常有用帮助了解DWR能做什么和如何工作。这个模式也能警告你以防止javascript的保留字,或者重载问
题。
然而这个模式不应该被用在现场部署,因为他能给黑客或者攻击者许多关于服务器的详细信息。
第3章. dwr.xml配置
3.1 纵览
dwr.xml是你用来配置DWR的文件,默认是将其放入WEB-INF文件夹。
创建一个dwr.xml文件
dwr.xml有如下的结构:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting
2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
<!-- 仅当需要扩展DWR时才需要 -->
<init>
<creator id="..." class="..." />
<converter id="..." class="..." />
</init>
<!-- 没有它DWR什么也做不了 -->
<allow>
<create creator="..." javascript="..." />
<convert converter="..." match="..." />
</allow>
<!-- 有必要告诉DWR方法签名 -->
<signatures>...</signatures>
</dwr>
3.2 <init>标签
这个初始化部分申明被用来创建远程beans而且这个类能被用来以某种过程转换。大多数例子你将不需要
用它,如果你想去定义一个新的Creator或者Converter,就要在此被申明。
在init部分里有了定义只是告诉DWR这些扩展类的存在,给出了如何使用的信息。这时他们还没有被使
用。这种方式很像Java中的import语句。多数类需要在使用前先import一下,但是只有import语句并不
表明这个类已经被使用了。每一个creator和converter都用id属性,以便后面使用。
3.3 <allow>标签
allow部分定义了DWR能够创建和转换的类。
3.3.1 Creator
每一个在类中被调用的方法需要一个<create …>有若干类型的creator,使用“new”关键字或者Spring 框
架等。
create元素是如下的结构
<allow>
<create creator="..." javascript="..." scope="...">
<param name="..." value="..." />
<auth method="..." role="..." />
<exclude method="..." />
<include method="..." />
</create>
...
</allow>
1. creator属性
1).new:Java用“new”关键字创造对象
是DWR默认的creator,如下所示
<create id="new" class="org.directwebremoting.create.NewCreator"/>
没有必要把它加入dwr.xml,它已经在DWR内部文件了。
这个creator将使用默认构造器创建类的实例,以下是用new创建器的好处
. 安全:DWR创造的对象生存的时间越短,多次调用中间的值不一致的错误机会越少。
. 内存消耗低: 如果你的站点用户量非常大,这个创造器可以减少VM的内存溢出。
2).none: 它不创建对象,看下面的原因。 (v1.1+)
none创建器不创建任何对象,它会假设你不须要创建对象。有2个使用的原因:
. 你可能在使用的scope不是"page"(看上面),并在在前面已经把这个对象创建到这个scope中了,
这时你就不需要再创建对象了。
. 还有一种情况是要调用的方法是静态的,这时也不需要创建对象。DWR会在调用创建器之前先检
查一下这个方法是不是静态的。
对于上诉两种情况,你仍然需要class参数,用来告诉DWR它是在操作的对象类型是什么。
3). scripted: 通过BSF使用脚本语言创建对象,例如BeanShell或Groovy。
要使用这个创造器,你需要把一些辅助库放到WEB-INF/lib文件夹下:比如BSF的jar包,你要用
的脚本语言的jar包。
new创造器在DWR中已经默认声明了:
<creator id="script" class="uk.ltd.getahead.dwr.create.ScriptedCreator"/>
这个创造器用BSF来执行脚本得到Bean,例如:
<allow>
...
<create creator="script" javascript="EmailValidator">
<param name="language" value="beanshell" />
<param name="script">
import org.apache.commons.validator.EmailValidator;
return EmailValidator.getInstance();
</param>
</create>
...
</allow>
script创造器有如下参数:
参数
DWR版本
描述
language
1.0
脚本语言,字符串,例如'beanshell'. (必需)
script
1.0
要执行的脚本。 (必需,除非scriptPath参数存在)
scriptPath
1.1
脚本文件路径。 (必需,除非script参数存在)
reloadable
1.1
是否检测脚本文件的改动,以重新加载 (可选, 默认true)
class
1.0
创造出对象的类型(可选). 如果没有DWR通过创造器得到类型。
注意:
当一个类是用script创造出来的,并且scope是session或application,如果你的脚本改变,session中的
类和script中的类就不一致了。这样会出现错误。虽然web容器不用重启,但是用户需要先登出(或以某种
方式清空session),然后再登录。
当clazz参数不为空,并且用来创造新实例,DWR简单的调用 class.newInstance() 方法。这种方法是没
问题的,除非脚本正在用某个参数创建一个类,或者调用某个函数来配置这个类。 不幸的是,每次请求都
要重新运行script并造成上面的问题。
4). spring: 通过Spring框架访问Bean。
详情请见DWR与Spring整合
5). jsf: 使用JSF的Bean。 (v1.1+)
详情请见DWR与JSF整合
6). struts: 使用Struts的FormBean。 (v1.1+)
详情请见DWR与Struts整合
7). pageflow: 访问Weblogic或Beehive的PageFlow。 (v1.1+)
详情请见DWR与Weblogic或Beehive的PageFlow整合
8). ejb3:使用EJB3 session bean。(v2.0+)
一个正在实验的创造器,用来访问EJB Session beans。直到进行更多的测试和正式的维护,否则还
不能作为产品被使用。
如果你想写自己的creator,你必须在<init>里注册它。
2. javascript属性
在浏览器里给你创建的对象命名。避免使用JavaScript保留字。这个名字将在页面里作为js被导入,就像
第2章节的那个jsp:
dwr.xml
<create creator="new" javascript="service">
<param name="class" value="helloWorld.Service" />
</create>
html / jsp
<html>
<head>
…
<script type='text/javascript' src='dwr/interface/service.js'>
…
3. scope属性
和定义在servlet的scope一样大的范围,它允许你指定哪个bean是可以获得的。选项可以是:application,
session, request和page。这些值应该已经被开发者们熟悉了。
scope选项是可选的,默认为page, 使用session请求cookies。目前,DWR还不支持URL重写。
4. param元素
被用来指定创造器的其他参数,每种构造器各有不同。例如,"new"创造器需要知道要创建的对象类型是什
么。每一个创造器的参数在各自的文档中能找到。
5. include和exclude元素
允许一个创造器去限制进入类的方法。一个创造器必须指定include列表或exclude列表之一。如果是
include列表则暗示默认的访问策略是"拒绝",include中的每个方法就是允许访问的方法;如果是exclude
列表则暗示默认的访问策略是"允许",exclude中的每个方法就是拒绝访问的方法。
比如:
<create creator="new" javascript="Fred">
<param name="class" value="com.example.Fred" />
<include method="setWibble" />
</create>
说明你只能在DWR中使用Fred的是setWibble方法。
6. auth元素
允许你指定一个J2EE的角色作为将来的访问控制检查:
<create creator="new" javascript="Fred">
<param name="class" value="com.example.Fred" />
<auth method="setWibble" role="admin" />
</create>
7. 使用静态方法
DWR会在调用创建器之前先检查一下这个方法是不是静态的,如果是那么创造器不会被调用。很显然这个
逻辑适用于所有创造器,尽管如此"null"创造器是最容易配置的。
8. 使用单例类
对于单例类的创建,最好适用BeanShell和BSF来实例化对象。请参考scripted创造器。
9. DWR与HttpSessionBindingListeners
DWR1.x中存贮已经创造的Bean的方法需要注意,它在每次请求时都会调用相同的 setAttribute() 方法。
就是说,如果一个Bean在dwr.xml中的声明周期设置为session,再每次调用bean中的方法时,DWR
都会执行一次 session.setAttribute(yourBean) 。这看上去没有什么危害,但是如果你要使用servlet的事
件机制的,就是说用了HttpSessionBindingListener接口,你就会发现valueBound和valueUnbound事件
在每次调用时都会发生,而不是你想像的在bean被创建时以及session过期时。
DWR2 只在第一次创建对象时调用 setAttribute() 。
3.3.2 Converter
我们需要确认所有的参数能被转换。许多JDK提供的类型使你能够使用,但是你如果要转换你自己的代码,
就必须告诉DWR。一般是指JavaBean的参数需要一个<convert…>标签作为入口。
你不需要在dwr.xml中<allow>部分的<convert>中定义。它们默认支持。
. 所有主要的类型,boolean, int , double等等。
. 包装类,Boolean, Integer等等。
. java.lang.String
. java.util.Date 和 java.sql.Times,java.sql.Timestamp。
. 数组(存放以上类型的)
. 集合类型 (List, Set, Map, Iterator等等) (存放以上类型的)
. DOM对象(来自于DOM, XOM, JDOM和DOM4J)
1. 日期转换器
如果你有一个String(例如:“2001-02-11”)在Javascript,你想把它转换成Java日期。那么你有2种
选择,一是使用Date.parse()然后使用DataConverter传入服务器端,还有一种选择是把该String传入,
然后用java的SimpleDateFormat(或者其他的)来转换。
同样,如果你有个Java的Date类型并且希望在HTML使用它。你可以先用SimpleDateFormat把它转换
成字符串再使用。也可以直接传Date给Javascript,然后用Javascript格式化。第一种方式简单一些,尽
管浪费了你的转换器,而且这样做也会是浏览器上的显示逻辑受到限制。其实后面的方法更好,也有一些
工具可以帮你,例如:
. The Javascript Toolbox Date formatter
. Web Developers Notes on Date formatting
2. 数组转换器
数组实体不太容易理解。默认情况下DWR能转换所有原生类型的数组,还有所有marshallable对象的数
组。这些marshallable对象包括前面介绍的String和Date类型。match属性看上去很怪。
<convert converter="array" match="[Z"/>
<convert converter="array" match="[B"/>
<convert converter="array" match="[S"/>
<convert converter="array" match="[I"/>
<convert converter="array" match="[J"/>
<convert converter="array" match="[F"/>
<convert converter="array" match="[D"/>
<convert converter="array" match="[C"/>
<convert converter="array" match="[L*"/>
上面没有解释 * 的作用 - 它是通配符,表示匹配接下来的所有字符串。这也是DWR可以转换任意类型的
数组的原因。
3. bean和对象转换器
两个没有默认打开的转换器是Bean 和 Object 转换器。Bean转换器可以把POJO转换成Javascript的
接合数组(类似与Java中的Map),或者反向转换。这个转换器默认情况下是没打开的,因为DWR要获得
你的允许才能动你的代码。
Object转换器很相似,不同的是它直接应用于对象的成员,而不是通过getter和setter方法。下面的例子
都是可以用object来替换bean的来直接访问对象成员。
如果你有一个在 <create ...> 中声明的远程调用Bean。它有个一参数也是一个bean,并且这个bean有
一个setter存在一些安全隐患,那么攻击者就可能利用这一点。
你可以为某一个单独的类打开转换器:
<convert converter="bean" match="your.full.package.BeanName"/>
如果要允许转换一个包或者子包下面的所有类,可以这样写:
<convert converter="bean" match="your.full.package.*"/>
显而易见,这样写是允许转换所有的JavaBean:
<convert converter="bean" match="*"/>
. BeanConverter 和 JavaBeans 规范
用于被BeanConverter转换的Bean必须符合JavaBeans的规范,因为转换器用的是Introspection,
而不是Reflection。这就是说属性要符合一下条件:有getter和setter,setter有一个参数,并且这个
参数的类型是getter的返回类型。setter应该返回void,getter应该没有任何参数。setter没有重载。
以上这些属于常识。就在eclipse里自动为每个属性添加setter,getter那种类型,如果你用的不是
JavaBean,那么你应该用ObjectConverter.
. 设置Javascript变量
DWR可以把Javascript对象(又名maps,或联合数组)转换成JavaBean或者Java对象。例子:
public class Remoted {
public void setPerson(Person p) {
// ...
}
}
public class Person {
public void setName(String name) { ... }
public void setAge(int age) { ... }
// ...
}
如果这个Remoted已经被配置成Creator了,Persion类也定义了BeanConverter,那么你可以通过下面
的方式调用Java代码:
var p = { name:"Fred", age:21 };
Remoted.setPerson(p);
. 限制转换器
就像你可以在creator的定义中剔出一些方法一样,converter也有类似的定义。
限制属性转换仅仅对于Bean有意义,很明显原生类型是不要需要这个功能的,所以只有
BeanConverter及其子类型(HibernateBeanConverter))有这个功能。
语法是这样的:
<convert converter="bean" match="com.example.Fred">
<param name="exclude" value="property1, property2" />
</convert>
这就保证了DWR不会调用 fred.getProperty1() 和fred.getProperty2两个方法。另外如果你喜欢"白
名单"而不是"黑名单"的话:
<convert converter="bean" match="com.example.Fred">
<param name="include" value="property1, property2" />
</convert>
安全上比较好的设计是使用"白名单"而不是"黑名单"。
. 访问对象的私有成员
通过'object'转换器的参数的一个名为force的参数,可以让DWR通过反射来访问对象私有成员。
语法是这样的:
<convert converter="object" match="com.example.Fred">
<param name="force" value="true" />
</convert>
直到DWR1.1.3,这里有一个bug,public的field反而不能被发现,所以你需要在public成员上设置
force=true。
4. 集合类型转换器
有个两个默认的转换器,针对Map和Collection:
<convert converter="collection" match="java.util.Collection"/>
<convert converter="map" match="java.util.Map"/>
一般来说这些转换器可以递归转换它们的内容。
但是也有两点不足之处:
. 仅仅用反射机制是没有方法明确集合里面是什么类型的。所以这两个转换器不能把集合里面的东西转
换成有意义的Javascript对象。
. 不能明确是那种类型的集合。 虽然我们不能让他们自动的起作用,我们可以在dwr.xml中用
signatures语法声明它们类型,使之正确转换。
5. 枚举类型转换器
枚举类型转换器默认是没有打开的。它在Java5中的Enum和Javascript的String之间进行转换。这个转
换器默认关闭是因为DWR要在转换你的代码之前得到你的同意。
枚举类型转换器是DWR 1.1版以后才支持的。
你可以这样设置来打开这个转换器:
<convert converter="enum" match="your.full.package.EnumName"/>
设置Javascript,一个简单的例子。假设你有下面的Java代码:
public class Remoted {
public void setStatus(Status p) {
// ...
}
}
enum Status {
PASS, FAIL,
}
如果Remoted类已经配置好Creator,并且Status枚举类型已经设置了EnumConverter。那么你就可以
在javascript中这样调用:
Remoted.setStatus("PASS");
6. DOM 对象
DWR可以自动转换来之DOM,DOM4J,JDOM和XOM的DOM树。你可以简单得用上面这些类库返回一
个Document、Element或者Node,DWR会把他们自动转换成浏览器的DOM对象。
在程序启动的时候会有一个常见的关于JDOM转换器的警告,你可以放心的忽略它,除非你要用JDOM:
INFO: Missing classdef for converter 'jdom'. Failed to load
uk.ltd.getahead.dwr.convert.JDOMConverter. Cause: org/jdom/Document
因为DWR没有办法知道你是否想用JDOM,所以这个信息设在INFO级别的。
如果你曾经尝试过使用JDOM,你会意识到在这种情况下这个转换器不可用的 - 这也是我们显示这个信息
的原因。
exist-db.org,我相信DWR能同exist-db很好的工作,因为它是建立在W3C DOM之上的,而DWR也支
持这个。
3.4 <signatures>标签
DWR使用反射机制在转换过程中找到它应该使用的类型。有时候类型的信息无法获得,在这种情况下你要
在此处用方法签名给予暗示。
signatures段使DWR能确定集合中存放的数据类型。例如下面的定义中我们无法知道list中存放的是什么
类型。
public class Check {
public void setLotteryResults(List nos)
{
...
}
}
signatures段允许我们暗示DWR应该用什么类型去处理。格式对以了解JDK5的泛型的人来说很容易理
解。
<signatures>
<![CDATA[
import java.util.List;
import com.example.Check;
Check.setLotteryResults(List<Integer> nos);
]]>
</signatures>
DWR中又一个解析器专门来做这件事,所以即便你的环境时JDK1.3 DWR也能正常工作。
解析规则基本上会和你预想规则的一样(有两个例外),所以java.lang下面的类型会被默认import。
第一个是DWR1.0中解析器的bug,某些环境下不能返回正确类型。所以你也不用管它了。
第二个是这个解析器时"阳光(sunny day)"解析器。就是说它非常宽松,不想编译器那样严格的保证你一定
正确。所以有时它也会允许你丢失import:
<signatures>
<![CDATA[
import java.util.List;
Check.setLotteryResults(List<Integer>);
]]>
</signatures>
将来的DWR版本会使用一个更正式的解析器,这个编译器会基于官方Java定义,所以你最好不要使用太
多这个不严格的东西。
signatures段只是用来确定泛型参数中的类型参数。DWR会自己使用反射机制或者运行时类型确定类型,
或者假设它是一个String类型。所以:
不需要signatures - 没有泛型参数:
public void method(String p);
public void method(String[] p);
需要signatures - DWR不能通过反射确定:
public void method(List<Date> p);
public void method(Map<String, WibbleBean> p);
不需要signatures - DWR能正确的猜出:
public void method(List<String> p);
public void method(Map<String, String> p);
不需要signatures - DWR可以通过运行时类型确定:
public List<Date> method(String p);
没有必要让Javascript中的所有对象的key都是String类型 - 你可以使用其他类型作为key。但是他们在
使用之前会被转换成String类型。DWR1.x用Javascript的特性把key转换成String。DWR2.0可能会用
toString()方法,在服务段进行这一转换。
第4章. 整合
4.1 DWR与Servlet
有2个Java类你一般需要用在DWR中,是webContext和WebContextFactory
在DWR 1.x 它们在uk.ltd.getahead.dwr 包, DWR 2.0+在org.directwebremoting包。这2个类给与你
访问标准Http servlet对象的入口。这些对象是:
. HttpServletRequest
. HttpServletResponse
. HttpSession
. ServletContext
. ServletConfig
4.1.1 使用webContext的方法:
import uk.ltd.getahead.dwr.WebContext;
import uk.ltd.getahead.dwr.WebContextFactory;
//
WebContext ctx = WebContextFactory.get();
req = ctx.getHttpServletRequest();
处理Http request和response做为只读是非常重要的。因为,当Http headers也许会通过,那么有些浏
览器会忽略它们(比如IE忽略缓存参数)。任何尝试改变Http body将会导致DWR错误。
WebContext使用一个本地线程变量,所以你能使用以上的代码放在任何地方。
也可以看一下 DWR的Java文档 ,或者详细看一下 WebContext 。
WebContext代替了DWR1.1中的ExecutionContext。
4.1.2 方法选择
在没有写依赖于DWR的代码时,要能够访问Http servlet对象是可以做到的(比如HttpServletRequest,
HttpServletResponse, HttpSession, ServletContext or ServletConfig)。DWR将自动填充它。
举个例子:
public class Remote {
public void method(int param, ServletContext cx, String s) { ... }
}
然后你将可以从Javascript中通访问它尽管没有ServletContext参数:
Remote.method(42, "test", callback);
DWR将为你填充这个参数。
对这个方法这里有个小小的警告,你要保证你的没有把’callback function’作为第一个参数,而应该把它作
为最后一个参数,或者作为元数据对象
4.2 DWR与Spring
4.2.1 让DWR和Spring一起工作的检查列表
1. 确认你用的是最新版的DWR。Spring创造器已经有了变化,所以你最好检查一下DWR的最新版本。
2. 确认你的Spring的Bean在DWR外面运行良好。
3. 配置DWR和Spring一起工作。 (看下面)
4. 查看演示页面: http://localhost:8080/[ YOUR-WEBAPP ]/dwr ,检查spring的Bean是否出现。
DWR对于Spring没有运行期依赖,所以如果你不使用Spring那么Spring的支持不会产生任何影响到。
4.2.2 Spring Creator
这个创造器会在spring beans.xml里查询beans,并且会使用Spring去创建它们。如果你已经使用Spring,
这个创造器会非常有用。否则将完全没有任何用处。
要让DWR使用Spring创造器去创建和远程调用beans,要像如下所示:
<allow>
...
<create creator="spring" javascript="Fred">
<param name="beanName" value="Shiela" />
</create>
</allow>
4.2.3 找到Spring配置文件
有3个方法可以找到Spring配置文件
1. ContextLoaderListener
最简单的用法使从Spring-MVC里使用
org.springframework.web.context.ContextLoaderListener
你不必使用整个Spring-MVC去确认这个普遍的解决方案使多么好。只要再你的web.xml里配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
2. 使用location参数
如果你喜欢指定的beans.xml在你的dwr.xml文件中,那么你能使用location参数。你可以指定你希望数
量的,必须有唯一的以”location”开头的命名。比如:location-1, location-2。这些locations是作为参数传
到Spring的ClassPathXmlApplicationContext:
<allow>
...
<create creator="spring" javascript="Fred">
<param name="beanName" value="Shiela" />
<param name="location" value="beans.xml" />
</create>
</allow>
3. 设置beenFactory目录
Spring创造器有一个静态的方法:setOverrideBeanFactory(BeanFactory),这个方法提供一个可编程的方
式去覆盖任何BeanFactories。
4.2.4 使用Spring配置DWR
Bram Smeets写了一个有意思的blog,教你配置DWR使用beans.xml代替WEB-INF/web.xml。
我也对于如何在beans.xml中指定dwr.xml很感兴趣,尽管这看上去有些Spring传染病的感觉。
4.3 DWR与JSF
DWR包括两个JSF的扩展点,一个创造器和一个ServletFilter。
4.3.1 JSF Creator
DWR1.1中有一个体验版的JsfCreator。你可以在dwr.xml中这样使用:
<allow>
...
<create creator="jsf" javascript="ScriptName">
<param name="managedBeanName" value="beanName" />
<param name="class" value="your.class" />
</create>
...
</allow>
这将允许你通过DWR调用ManagedBean。
4.3.2 Servlet Filter
DWR/Faces 过滤器允许你不在JSF的生命周期里调用FacesContext中的Bean。
要使用JsfCreator,你应该把DWR/Faces过滤器加到web.xml中。
<filter>
<filter-name>DwrFacesFilter</filter-name>
<filter-class>
uk.ltd.getahead.dwr.servlet.FacesExtensionFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>DwrFacesFilter</filter-name>
<url-pattern>/dwr/*</url-pattern>
</filter-mapping>
这两个需要放在web.xml中与其他的filter和filter-mapping放在一起。
4.4 DWR与Struts
DWR能够和任何框架结合。这个网站是个极端巧妙的证据,因为它把DWR使用在Drupal(PHP)。
DWR和Struts整合有2个层次。最基础的层次就是同时使用这两个框架,这是非常容易的,但是这样就
不允许在DWR和Struts之间共享Action了。
DWR能构调用任何方法,所以你也能从调用一个Struts action,除非你不想那么做。ActionForm的内容
是什么,当返回ActionForward时DWR怎么做?
一个比较好方法是重构你想调用的Action,提取出Action的逻辑。DWR和你的Action就可以同时调用相
同的方法了。
4.4.1 Struts creator
DWR1.1增加了一个StrutsCreator。你可以在dwr.xml中这样使用:
<allow>
...
<create creator="struts" javascript="ScriptName">
<param name="formBean" value="formBeanName" />
</create>
...
</allow>
这样你就能从DWR调用FormBeans。
4.4.2 开始顺序
如果正在使用Struts创造器,那么你应该确保Struts初始化在DWR之前。你要保证你在web.xml里有一
个<load-on-startup>的值,其中Struts的值比DWR设置地要低。
4.5 DWR与Weblogic或PageFlow
DWR中有一个创造器可以和Weblogic或者Beehive中的PageFlow一起工作。
PageFlow creator
DWR1.1中加入了一个PageFlowCreator。你可以这样使用:
<allow>
...
<create creator="pageflow" javascript="ScriptName"/>
...
</allow>
4.6 DWR与Hibernate
4.6.1 让DWR和Hibernate一起工作的检查列表
1. 确保你使用的是最新的DWR。Hibernate转换器是新东西,所以你需要下载最新版本
2. 确保你的Hiberante在没有DWR的时候工作正常。
3. 如果是Spring和Hibernate一起使用,那么你最好先了解一下如何将整合Spring。
4. 配置DWR,使之与Hibernate一起工作。 (看下面)。
5. 查看演示页面:http://localhost:8080/YOUR-WEBAPP/dwr,确定Spring的Bean可以出现。
4.6.2 HibernateBeanConverter
除了我们可以决定是否要使用lazy loaded属性,这个转换器非常类似于标准的BeanConverter。
在DWR1.1 Hibernate转换器被称为“hibernate”并且作用在hibernate2, 在DWR2.x有2个转换器被
称为“hibernate2”并且作用在hibernate3。
使用HibernateBeanConverter也许有点风险,原因如下:
. 结构:HibernateBeanConverter不符合MVC模式,所以不能把对象在数据曾和表现曾之间进行隔离。
这个风险可以通过在上面加上独立的bean来减轻。
. 性能: DWR试图通过相同的序列化方式来转换所有可以得到的属性(除了DWR仅仅读JavaBean属
性的时候)。所以可能会出现通过HTTP序列化了你的整个数据的情况。通常这并不是你想要的。要
减少这一风险可以使用BeanConverter(HibernateBeanConverter衍生于它)的排除某些属性的功能,
如下所示:
<param name="exclude" value="propertyToExclude1, propertyToExclude2"/>
HibernateBeanConverter会尝试不去读取没有初始化的属性。如果你只是想读取所有的东西那么应该使用
BeanConverter。
建议使用Hibernate3,实际上Hibernate2的情况,你会发现你得到的都是空的Bean。
4.6.3 Session管理
如果你使用Hibernate对象,你需要知道每一个DWR请求都是一个新的Servlet请求,所以你需要保证为
每个请求打开一个Hiberante的Session。
如果你用Spring,那么可以很方便的使用Spring里面的OpenSessionInViewFilter,它可以保证为每个请
求打开一个Hiberante的Session。类似的解决方案在其它Framework中也存在。
4.7 DWR与WebWork
WebWork支持在DWR2.0m3以后才有。
要可以通过DWR调用WW的Action,要做两件事。
4.7.1 配置dwr.xml
你必须在dwr的配置文件中加入这样的配置:
<create creator="none" javascript="DWRAction">
<param name="class"
value="org.directwebremoting.webwork.DWRAction" />
<include method="execute" />
</create>
<convert converter="bean"
match="org.directwebremoting.webwork.ActionDefinition">
<param name="include"
value="namespace,action,method,executeResult" />
</convert>
<convert converter="bean"
match="org.directwebremoting.webwork.AjaxResult" />
这样你AjaxWebWork Action调用返回一个action实例(而不是文字)。然后你必须包括action对象的转换
器定义(package级别或单独action)。
<convert converter="bean" match="your_action_package.*"/>
4.7.2 在JSP中导入脚本
下面这些代码开启DWR调用Action的功能。你还要导入DWRActionUtil.js脚本(在你的web脚本路径中)
像这样在JS中调用Action:
DWRActionUtil.execute(id, params, callback, [displayMessage]);
1. id 参数
. actionUri: 要调用action的URI(没有 .action). 例如:
DWRActionUtil.execute('/ajax/TestFM', 'myform', 'doOnTextResult');
. actionDefinitionObject: 在xwork.xml中定义的action对象. 必须指定下面的内容:
. namespace: xwork.xml中action的名称空间
. action: xwork.xml中action的名字
. executeResult: true|false (是否执行action的结果, 如果false直接返回action实例)
例如:
DWRActionUtil.execute({
namespace:'/ajax',
action:'TestJS',
executeResult:'true'
}, 'data', doOnJSResult, "stream...");
2. params 参数
. emptyParams: 传递{}忽略任何参数。例子:
DWRActionUtil.execute('/ajax/TestFM', {}, doOnJSResult, "stream...");
. fieldId: 被转换为action调用参数的字段的id。
例子:
<input id="mytext" name="mytext" value="some value" type="text"/>
DWRActionUtil.execute('/ajax/TestFM', 'mytext', doOnJSResult,
"stream...");
. formId: 表单的id. 所有的input值被转换为action调用参数。
Note : 如果你的action使用了parameter拦截器,那么你的action会得到正确的参数值,请参考WebWork
的文档。
3. callback 参数
. callbackFunction: 在DWR中,这个函数在
- DWR中文文档.rar (1.1 MB)
- 下载次数: 352
相关推荐
本压缩包文件“Ajax&DWR帮助文档.rar”提供了有关这两种技术的详细资料,包括“DWR中文文档.pdf”和“AJAX入门手册.chm”,旨在帮助开发者深入理解和应用Ajax与DWR。 Ajax是一种在不刷新整个页面的情况下与服务器...
这个“dwr-3.0.0.rar”文件是DWR技术的3.0版本的压缩包,包含了运行和开发基于DWR的应用所需的所有组件。 DWR的核心功能在于它创建了一个安全的、高效的桥梁,使得前端JavaScript代码可以直接调用后端Java方法,就...
文档`DWR.xml.doc`应该包含了关于这些配置选项的详细解释和示例。同时,`www.pudn.com.txt`可能是相关的资料链接或社区讨论,它可能会提供额外的使用技巧和最佳实践。 理解并熟练配置`dwr.xml`是使用DWR构建高效...
"dwr中文文档和实例.rar"包含了对DWR全面的中文解释和实践案例,对于想要深入理解和使用DWR的人来说,是一份极其宝贵的学习资源。 首先,DWR中文文档会详细介绍DWR的基本概念和工作原理。DWR的核心功能是提供了一个...
标题"jt_dwr_spring.rar_jt"表明这是一个关于"jt"项目的压缩包,其中包含了"DWR (Direct Web Remoting) 与 Spring 框架的整合"相关的资源。"jt"可能代表某个项目或团队的缩写。 描述提到"DWR 和 Spring 相整合从而...
Direct Web Remoting (DWR) 是一个开源Java库,它允许在Web应用程序中实现JavaScript与服务器端Java...通过这个"**dwr.rar**"压缩包,你可以获取到DWR的核心组件,并根据提供的文档和示例快速开始你的AJAX开发之旅。
本教程通过详细的文档(Spring+Struts+Hibernate+DWR集成教程.doc)指导,涵盖了这四大框架的配置、整合、实例演示等多个方面,旨在帮助开发者深入理解和实践这一经典的技术组合,提升开发技能,打造高效的企业级...
压缩包内的"DWR中文文档2.pdf"很可能是DWR3的中文用户指南或开发者手册,对于学习和使用DWR3框架具有很高的参考价值,详细介绍了如何配置、使用DWR以及解决常见问题。"dwr.rar"可能包含了DWR的源码或者库文件,便于...
标题 "ext2+spring+hibernate+dwr.rar_dwr MenuManage.js_ext2 ja" 提示我们这是一个关于集成技术的项目,其中包含了ext2、Spring、Hibernate和DWR(Direct Web Remoting)四个主要组件。这个项目的具体实现是通过...
这个“DWR 中文文档(Java与Ajax).rar”压缩包提供了关于DWR的详细中文指南,对理解和使用DWR进行Java和Ajax开发大有裨益。 DWR的核心功能是实现JavaScript与Java之间的直接远程调用(Remote Procedure Call,RPC)...
结合DWR的官方文档和这些源码,开发者不仅可以学习到DWR的工作原理,还可以根据需求定制自己的DWR实现,提升Web应用的性能和用户体验。同时,对源码的深入理解也有助于培养开发者的问题排查和调试能力,对于提升个人...
结合这些技术,OA办公自动化管理系统能够实现诸如文档管理、工作流审批、通知公告、日程安排等多种功能,适应现代企业的日常运营需求。课程设计中采用这样的技术组合,既能让学生了解企业级开发的实际应用,也能锻炼...
通过解压 "dwr3.0.rar",你将获得DWR 3.0的完整源码、文档、示例以及部署所需的资源。这将帮助你深入了解DWR的工作原理,并在实际项目中快速应用。对于学习和开发基于Java的Web应用,特别是需要利用AJAX技术来提升...
标题"DWR.rar_dwr"表明这个压缩包包含了与DWR相关的资源,可能是文档、代码示例或者教程材料。其中,"www.pudn.com.txt"可能是一个文本文件,源自网站www.pudn.com,可能包含关于DWR的介绍、链接或者其他相关资源。...
综合以上信息,我们可以推测这个“dwr.rar_full”可能是一个包含完整DWR项目源代码的压缩包,包括可能的UI设计资源和相关文档。对于想要研究DWR、学习Web远程调用技术或者需要调试DWR应用的人来说,这是一个非常有...
在`dwr.rar`压缩包中,可能包含了DWR的库文件、示例代码、配置文件以及文档等资源,可以帮助学习者快速理解和使用DWR框架。通过研究这些内容,你可以了解如何配置和使用DWR,从而在自己的项目中实现高效、便捷的Ajax...
这个压缩包“DWR与界面开发.rar”包含了关于如何利用DWR来增强Web界面开发的资料,可能是教程、示例代码或者最佳实践文档。下面将详细探讨DWR及其在界面开发中的应用。 DWR的核心概念是提供了一个安全、高效的方式...