DWR学习笔记(三)

来源:百度文库 编辑:神马文学网 时间:2024/05/11 16:06:02

DWR学习笔记(三)

js 2010-01-02 19:23:55 阅读32 评论0   字号: 订阅

四.DWR配置文件dwr.xml文件详解:放置到WEB-INF目录
 
  
      
      
          
          
      


      
      
          
          
      


      
      ...
  

 
  1.标签:声明被用来创建远程beans和声明能被用来以某种过程转换的类。
      大多数例子你将不需要用它,如果你想去定义一个新的Creator或者Converter,就要在此声明。
      在init部分中定义只是告诉DWR这些扩展类的存在,给出了如何使用的信息。
      这时这里声明的类并没有被使用。这种方式很像Java中的import语句。
      多数类需要在使用前先import一下,但是只有import语句并不表明这个类已经被使用了。
      每一个creator和converter都用是id属性标识,以便后面使用时直接引用。
       
  2.标签:allow标签中定义了DWR能够创建和转换的类。
  
   A.子标签:一个类对应一个标签.
    
    i.creator属性:告诉DWR产生对应类的对象的方式,因为DWR要在页面通过js调用该类的对象的方法,
          而我们没有手动产生对象,那么对象只能是由DWR来产生,
          所以要告诉DWR产生对象的方式或者是new一个通过构造方法或者是通过从Spring的Ioc容器中取得等,
          总之要指定一个生成对象的方式。
          
       **注意:如果想写自己的creator创建器,必须在里注册声明它,然后才可以在的creator属性中指定并使用。
          
       (1)new创建器:指定DWR生成类的对象的方式是通过Java的new关键字,调用缺省构造(因为DWR将采用反射机制)方法产生对象。
           这也是DWR的默认creator,
           所以这个配置不用放到中声明,因为DWR内部已经加入。
         
       (2)none创建器:告诉DWR不要创建对象。有两种情况适合这种情况!!          
            <1>可以指定一个scope值(page除外),并且在调用该对应类的方法之前已经把这个对象创建到指定的scope中,
            这时就不需要再创建对象了,用到时DWR会从scope指定的作用域中查找对象。
            <2>另一种情况是要调用的方法是静态的,这时也不需要创建对象。
            DWR会在调用创建器之前先检查一下这个方法是不是静态的。如果是静态的直接用就行。
       
       (3)spring创建器:通过Spring框架访问Bean
       
       (4)struts创建器:使用Struts的ActionFormBean
       
       (5)jsf创建器:使用JSF的Bean
       
       (6)pageflow创建器:访问Weblogic或Beehive的PageFlow。
       
       (7)script创建器(不常用):通过BSF使用脚本语言创建对象,例如BeanShell或Groovy。
             要使用这个创造器,你需要把一些辅助库放到lib目录,
             比如BSF的jar包,要用的脚本语言的jar包等。
             <用到时再看文档>
       
       (8)ejb3创建器(测试中,未投入使用):使用EJB3 session bean,一个正在实验的创造器,
                 用来访问EJB Session beans。直到进行更多的测试和正式的维护,
                 否则还不能作为产品被使用
       
    ii.javascript属性:指定对应的类的对象在js中使用时的对象名(变量名),
           即JSP页面中可用指定的名字调用对应的类中的方法。
           
       **注意:页面中还要导入以指定的javascript属性值为文件名的js文件
         
         这是DWR加载dwr.xml配置文件时内部在规定目录"dwr/interface/"动态生成的对应对象名的js文件,
         供页面中导入,以便实现调用java对象。
         
    iii.scope属性:和servlet、jsp中的scope属性一样,指定作用域范围,分别有page、request、session、application四个作用域。
          默认为page作用域。
          
    iv.子标签:辅助指定的creator创造器属性值的其他参数,每种创造器对应的子标签的值都不相同。
          例如"new"创造器需要知道要创建的对象类型是什么,
          每一种creator创造器的对应的子标签的参数在各自的文档中能找到。
    
    v.子标签:用于限定DWR在页面可以调用对应类的方法。
             例如
               
               
              

             说明在页面通过DWR只能调用DWRTest类中的sayHello()方法;
             如果用指定就是不能调用sayHello()方法,其他方法仍然可以调用。
    
    vi.子标签(了解):允许指定一个JavaEE的角色作为将来的访问控制检查:
    
            
             
             
            

    
    **注意:
      (1)使用静态方法时,DWR会在调用创建器之前先检查一下这个方法是不是静态的,
         如果是那么创造器不会被调用。这个规则适用于所有创造器。
      (2)scope属性:指定的范围是对应的类对象的保存作用域,对于DWR1.x版本,
           它在每次请求时都会调用一次setAttribute()方法,就是每次在页面调用对象的方法时,
           DWR都会调用一侧scope.setAttribute()方法;
           而DWR 2只在第一次创建对象时调用scope.setAttribute()方法,
           解决了如果使用servlet的事件机制时,
           如HttpRequestAttributeListener每次都会触发属性事件的麻烦。
      
      (3)使用单例类时(了解),对于单例类的创建,最好使用BeanShell和BSF来实例化对象,即script创建器。
      
   B.子标签:为了确保DWR页面调用java对象方法传入参数时所有的参数能被正确的转换。
          之所以涉及到转换的原因就是,我们是通过js来调用的java对象方法,传入的参数也都是js的类型,
          但是DWR会在内部真实的通过传入的js参数调用对应的java对象的方法,
          此时就应该保证js的类型能够正确的转换成java中的参数类型。
          例如java方法sayHello(String name)接受java的String类型,
          但是js调用是传入的是一个var类型的,为了让DWR内部调用sayHello时成功将var类型转换成String类型。
          当然这个是不用特别指出的,但是有时我们会自定义一些类型,此时就要声明转换器。
          
      (1)不需要用指定转换器的类型有:这些DWR默认支持它们的转换
         
         <1>所有的基本数据类型,boolean, int , double等
         <2>包装类,Boolean, Integer等
         <3>java.lang.String
         <4>java.util.Date 和 java.sql.Times,java.sql.Timestamp
         <5>数组,但是限制为存放以上类型的数组,不包括自定义的或者集合的数组。
         <6>DOM对象(来自于DOM, XOM, JDOM和DOM4J)
         
      (2)Bean和Object转换器:DWR是支持这两种参数的转换的,只不过默认情况是关闭状态。
             Bean转换器可以把POJO转换成Javascript的接合数组(类似与Java中的Map),
             或者反向转换(即java对象的方法返回一个Bean对象,js中接受的将会是转换好了的接合数组)。
             Object转换器与Bean转换器很相似,不同的是它直接应用于对象的成员,而不是通过调用getter和setter方法。
             这也要求作为Bean参数的对象必须符合javaBean的规范(要有getter和setter方法)
         **说明:应用的场合就是当我们定义的java类中的方法的参数中有自定义的Bean规范的自定义对象,
           那么在页面js调用传递参数的时候会出现转换异常,因为DWR不知道怎么转换,
           此时就可以为该参数对象的java类指定开启转换器功能。
           
         **使用方法:
            <1>只为单个类开启Bean转换器功能,也就是说当其他Bean类也作为参数时,它的Bean转换器是关闭的。
               
               
            <2>为一个包中的所有类都打开Bean转换器功能
               
            
            <3>为所有类都打开转换器功能
               
            
            <4>Object转换器的使用方法道理相同
            
         **详细说明:像上面通过converter指定bean属性值为什么就可以开启转换器功能呢?
            是因为DWR内部已经实现了对bean值将会分配一个BeanConverter类作为对应参数类的转换器,
            也就是当涉及到指定的类的转换时,那么BeanConverter就会进行转换功能,这都是DWR内部的实现。
            对于converter="object"的时候,那么DWR将会通过ObjectConverter转换类来处理指定的要进行转换的类。
            
         **限制转换器(基本不会用):类似中的子标签,
              只不过只有BeanConverter及其子转换器HibernateBeanConverter有这个功能。
              也就是只有converter="bean"时才能用此功能。
              
             
              

              意思是DWR使用转换器BeanConverter时只能调用getProperty1()和getProperty2()方法完成转换。
              
         **访问对象的私有成员(基本不会用):用的时候可以查看文档。
         
      (3)集合类型转换器:默认是开启的上面已经说明,此处类出DWR内部的配置供了解参考。此处我们分析它的缺点!!
         
         <1>
         <2>
         
         **缺点与不足:用反射机制是没有方法明确集合里面是什么类型的。
              所以这两个转换器不能把集合里面的东西转换成有意义的Javascript对象。
              
         **解决方法:可以在dwr.xml中标签语法声明集合中元素的类型,使之正确转换。
            <详细见下边>
            
      (4)枚举类型转换器(了解):用时可以查看文档
      
      (5)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级别的。
         
  3.标签:DWR使用反射机制在转换过程中找到它应该使用的类型。
          有时候类型的信息无法获得,在这种情况下你要在此处用方法签名给予声明。
          signatures段使DWR能确定集合中存放的数据类型(泛型指定的类型)。
       
   A.**主要目的:就是让DWR在页面中通过js调用java方法时,用来确定集合泛型参数中的类型参数,
        以完成正确的从js类型转换成java类型,正确的传入调用的方法中,完成操作。
      
   B.例如下面的定义中我们无法知道list中存放的是什么类型。
       
    public class Check{
     public void setLotteryResults(List nos){
      ......
     }
    }
    
    **问题:如果在jsp中通过js调用该方法并且传递参数时,
      DWR不知道将js生成的集合中的元素转换成java的什么类型然后传给该方法。
      
    **解决方案:重新声明了一下Check类中的方法,此时通过了泛型,
       这样调用时传的参数集合中的元素DWR就知道转换成java的什么类型进而传给该方法。
       
                 //导入需要的类,和java中import一样,
         //导入了类就相当于告诉DWR转换的类型是什么类型了,默认java.lang包中的类不用导入!
         import java.util.List;
         import com.example.Check;
         Check.setLotteryResults(List nos);
        ]]>
       

       
   C.用与不用signatures段举例说明:
     
    i.DWR调用这样的方法传参数时DWR自己会知道
      怎样将js类型转换成对应的java类型,因为没有泛型参数或说成涉及不到泛型参数。
       
      public void method(String p);
      public void method(String[] p);
       
    ii.DWR调用传参数时,可以知道泛型指定的类型怎么转换,不需要signatures段特意标识。
     
      public void method(List p);
      public void method(Map p);
      public List method(String p);
       
    iii.DWR调用传入参数时,将不知道怎样转换,
     其实主要是不知道怎样将js中的类型转换成对应的WibbleBean类型,
     随意应该通过signatures来导入一下该类的全名,以便告诉DWR进而完成转换。
        
      public void method(List p);
      public void method(Map p);