dwr.xml 配置

来源:互联网 发布:投诉淘宝店铺有用吗 编辑:程序博客网 时间:2024/04/27 21:48

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属性,以便后面使用。
 
  21 / 92
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它是在操作的对象类型是什么。
 
 
 
  22 / 92
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并造成上面的问题。
 
 
  23 / 92
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重写。
 
 
 
  24 / 92
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() 。 
  25 / 92
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可以转换任意类型的
数组的原因。  
 
  26 / 92
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) { ... }
  // ...

  27 / 92
如果这个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。 
  28 / 92
 
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"); 
  29 / 92
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也支
持这个。 
  30 / 92
 

原创粉丝点击