dwr.xml 配置文件詳解

1.創建dwr.xml 配置文件 
任何一個dwr.xml的文件都須要包含DWR DOCTYPE的聲明行,格式以下: 
javascript

Xml代碼  收藏代碼java

  1. <!DOCTYPE dwr PUBLIC  
        "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"  
        "http://www.getahead.ltd.uk/dwr/dwr10.dtd">  
    //整個配置文件的大致結構以下:  
    <dwr>  
      <init>  
        <creator id="..." class="..."/>  
        <converter id="..." class="..."/>  
      </init>  
      <allow>  
        <create creator="..." javascript="..." scope="...">  
          <param name="..." value="..."/>  
        </create>  
        <convert convertor="..." match="..."/>  
      </allow>  
      <signatures>  
        ...  
      </signatures>  
    </dwr>

有幾個術語有必要理解,參數叫作converted,遠程Bean叫作created.若是遠程Bean A有個方法A.blah(B),那麼你須要爲A創建一個created,爲B創建一個converted. 

配置文件init部分聲明那些用於創建遠程bean和在方法調用中轉換bean的類.這部分是可選擇性配置的,多數狀況下能夠沒必要使用它,若是你想定義一個新的creator或者converter那麼就必須在部分中聲明,but do double check on the ones that are currently available first. 
在init部分的做用是告訴DWR一些類實例和關於這些類怎樣運行的信息.實際上並不會使用.這有點向java中的import語句,多數類在使用以前須要引入,但引入了類並不意味着這些在使用,每一個creator和converter須要有個id屬性來容許之後進行引用. 
配置文件的allow部分定義哪些類能夠創建和轉換,每一個被准許的類均可以有一個'create'或者'convert'配置行.下面列出的類的轉換在默認狀況下不須要進一步的設置. 
  一、全部基本類型,boolean,int,double等等 
  二、基本類型的對象形式實現的類,Boolean,Integer等等 
  三、java.lang.String 
  四、java.util.date 和三個SQL形式的派生類 
  五、以上全部類型的數組形式 
  六、以上全部類型的集合,List,Set,Map(有些侷限性) 
However nothing is added to the list of classes that can be created (i.e. put up for remoting) without you declaring it. 

2The Converters 

DWR已經默認定義和初始化了經常使用的Converter,他們分別以下: 
程序員

Xml代碼  收藏代碼ajax

  1. <converter id="null"  
        class="uk.ltd.getahead.dwr.convert.NullConverter"/>  
    <converter id="primitive"  
        class="uk.ltd.getahead.dwr.convert.PrimitiveConverter"/>  
    <converter id="bignumber"  
        class="uk.ltd.getahead.dwr.convert.BigNumberConverter"/>  
    <converter id="string"  
        class="uk.ltd.getahead.dwr.convert.StringConverter"/>  
    <converter id="date"  
        class="uk.ltd.getahead.dwr.convert.DateConverter"/>  
    <converter id="array"  
        class="uk.ltd.getahead.dwr.convert.ArrayConverter"/>  
    <converter id="map"  
        class="uk.ltd.getahead.dwr.convert.MapConverter"/>  
    <converter id="collection"  
        class="uk.ltd.getahead.dwr.convert.CollectionConverter"/>  
    <converter id="bean"  
        class="uk.ltd.getahead.dwr.convert.BeanConverter"/>  
    <converter id="hibernate"  
        class="uk.ltd.getahead.dwr.convert.HibernateBeanConverter"/>  
    <converter id="dom"  
        class="uk.ltd.getahead.dwr.convert.DOMConverter"/>  
    <converter id="dom4j"  
        class="uk.ltd.getahead.dwr.convert.DOM4JConverter"/>  
    <converter id="jdom"  
        class="uk.ltd.getahead.dwr.convert.JDOMConverter"/>  
    <converter id="xom"  
        class="uk.ltd.getahead.dwr.convert.XOMConverter"/>  
    <converter id="servlet" class="uk.ltd.getahead.dwr.convert.ServletConverter"/>

這裏僅僅是定義了Converter而且簡單的放在<convert….>元素以內,任何的<convert….>元素內容都有兩個必須定義的屬性.一個是對converter定義的引用和converter可以轉換的類. 
例如最簡單的converter是null converter,它做用是把null和void值轉換成javascript的null和undefined值.它是全部converter中最簡單的,就象調用java的靜態方法同樣,因此並不須要建立對象. 
默認的時候DWR將java void值轉換成javascript的null值就是這樣設置<convert converter="null" match="void"/>. 有時java.lang.Void也須要進行這樣的轉換,因此設置也是類似的<convert converter="null" match="java.lang.Void"/>.從java中傳遞null值到javascript是沒有任何危險性的,因此DWR將這個做爲默認的converter,因此你本身不用再把這個converter添加到配置文件的<allow>部分中去. 
基本類型的converter轉換int,boolean,double等.固然還包括對應的對象形式Integerv,Boolean等等.DWR中在allow預約義了16個配置項目分別用於全部基本類型的轉換.就象這樣<convert converter="primitive" match="java.lang.Long"/><convert converter="primitive" match="long"/>. 
String類型和Date一樣預先定義了Converter,這些converter都沒有辦法進行改變的,全部的String,Date和數值類型都統一採用默認的converter. 
2.1 Array Converters 
Array的配置項目沒有上面介紹的那麼直觀,默認狀況下DWR裝載全部的基本類型和可裝載的對象,這些包括String,Date等先前介紹的類型.java高級程序員可能會理解爲何match的這行有點奇怪. 
spring

Xml代碼  收藏代碼shell

  1. <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*"/>


*符號在上面沒有提到,其實這是個能夠表示任何字符的通配符號.這些數組可裝載的的類型和其餘可裝載的類型是同樣的. 
2.2 Bean Converters一種不能採用默認方式定義的converter就是Bean Converter,這個是將POJO對象轉換成javascript相關的數組,反向也同樣.基於安全因素的考慮這種類型的converter不能採用默認的方式實現. 
假設有個bean而且經過<create ...>語句設置成遠程可用,有種類型的參數他自己是一個帶有setter的java bean,但setter會產生嚴重的隱患.攻擊者可能促使這隱患的發生.經過下面的語句就能夠設置但個類的bean converter 
<convert converter="bean" match="your.full.package.BeanName"/> 
要想容許轉換指定包或子包下全部類的轉換能夠按照下面的設置 
<convert converter="bean" match="your.full.package.*"/> 
很明顯,能夠採用下面的方式來轉換全部的java bean 
<convert converter="bean" match="*"/> 
2.3 Restricting Property Conversion(指定屬性轉換) 
將象用exclude和incluce來通知DWR隔離creator的方法同樣,converter也有一個相似的配置方法.由於指定屬性轉換隻有針對bean纔有效(基本類型的轉換沒有必要指定屬性),這個功能只能應用與特定的converter即BeanConverter和從次類派生的全部類.相關配置語法以下 
apache

Xml代碼  收藏代碼編程

  1. <convert converter="bean" match="com.example.Fred"/>  
      <param name="exclude" value="property1, property2"/>  
    </convert>

這樣就能夠限定DWR不能調用Fred對象的getProperty1()和getProperty2()方法,一般這被成爲拒絕訪問方式,固然你也能夠採用下面的方式配置能夠訪問的方法(受權訪問方式) 
<convert converter="bean" match="com.example.Fred"/> 
  <param name="include" value="property1, property2"/> 
</convert> 
較好的安全控制大部分都是採用受權訪問方式. 
2.4 Collection Converters 
DWR最後兩個默認的converter是Maps和Collections 
數組

Xml代碼  收藏代碼瀏覽器

  1. <convert converter="collection" match="java.util.Collection"/>  
    <convert converter="map" match="java.util.Map"/>

一般converter是採用遞歸方法轉換集合中的全部對象. 
這裏有兩個地方須要注意: 
僅僅經過反射方法沒有辦法知道集合元素中的類型,因此上面的兩個converter能將任何集合轉換成相對javascript而言有意義的對象.然而沒有辦法將不一樣的集合類類型分別採用不一樣的轉換方法.由於沒有辦法徹底自動進行轉換,咱們能夠應用dwr.xml文件的special signatures syntax配置部分設置類型的轉換處理過程. 
2.5 DOM Objects 
DWR 自動將DOM、DOM4J、JDOM和XOM轉換成DOM樹,前面這幾種類型都僅僅返回Document,Element,Node.DWR會自動將這些轉換成瀏覽器DOM對象.一般在啓動JDOM Converter時會有一個提示信息,除非你想採用JDOMconverter不然能夠忽略. 
INFO: Missing classdef for converter 'jdom'. Failed to load uk.ltd.getahead.dwr.convert.JDOMConverter. Cause: org/jdom/Document 
由於DWR沒有辦法知道你是否採用jdom converter,因此提示信息是info級別.若是你想採用jdom converter,你必須很清楚地知道jdom converter是否能夠被加載.這就是DWR保留上面的提示信息的緣由. 
3 The Creators 
DWR共有三種Creator,最簡單的」new」是調用bean的默認構造函數建立實例.」scripted」容許採用其餘腳本語言建立實例.如BeanShell.在遠程bean的默認構造函數不能進行進一步配置的狀況下這種類型的creator比較有用.」Spring」類型容許你經過spring建立實例. 
下面是關於creator的參考資料和配置參數說明. 
Creator Parameter User
new class 類的全名稱(包括包路徑)
scripted language BSF框架支持的腳本語言名稱(BSF爲apache項目)
scripted script 返回遠程對象的腳本,腳本能夠指定一些屬性,多數狀況下通常只設置param節點配置.屬性不多設置.
spring Location* 任何以location開頭的參數,每一個參數都是指定一個spring的配置文件,在參數沒有設置的狀況下DWR會去讀取spring的全局的配置文件.
spring beanName 從配置文件中讀取的bean的名稱
「scope參數容許你配置creator的生命週期,共有如下幾個選項:application,session,request,page.這些參數對於用過jsp或servlet的開發人員並不陌生. 
3.1 Uing static methods 
若是你想遠程調用一個creator的靜態方法,而且creator是new類型.由於調用遠程bean的方法前DWR不會檢測將要執行的方法是否是靜態方法,若是是靜態方法那麼creator就不用建立.這種機制能夠適用任何類型的creator,但new類型的creator是最簡單配置的. 
3.2 Security 
Creator能夠配置類的成員函數的訪問權限.creator有受權訪問(指明能夠被訪問的方法)和拒絕訪問(指明不容許訪問的方法)兩種配置方式. 
若是要設置除了setWibble方法以外的全部方法都不可訪問能夠採用下面的設置. 

Xml代碼  收藏代碼

  1. <create creator="new" javascript="Fred">  
      <param name="class" value="com.example.Fred"/>  
      <exclude method="setWibble"/>  
    </create>

若是採用j2ee訪問角色控制的模式 
<create creator="new" javascript="Fred"> 
  <param name="class" value="com.example.Fred"/> 
  <auth method="setWibble" role="admin"/> 
</create> 
3.3 The 'spring' Creator 
3.4 The 'new' Creator 
DWR已經默認定義了new creator. 
<creator id="new" class="uk.ltd.getahead.dwr.create.NewCreator"/>DWR已經將這配置到了內置的dwr.xml文件中,並不須要進行額外的配置. 
Creator經過調用類的默認的構造方法建立實例.應用new creator有如下幾個優勢: 
安全性    
生命週期比較短的creator能夠獲得更好的安全性,經過不一樣的應用狀況設置適合的生命週期. 
低內存開銷 
在訪問量比較大的狀況下,能夠不用擔憂發生內存泄露的狀況. 
配置一個creator的建立和遠程方法調用設置: 

Xml代碼  收藏代碼

  1. <allow>  
      <create creator="new" javascript="Blah">  
        <param name="class" value="java.util.Date"/>  
      </create>  
      ...   
    </allow>

上面的配置信息表示將java.util.date提供給客戶端調用,而且引用名稱是Blash.當你在客戶端調用Blash.toString(reply)時,後臺將採用java.util.date的默認構造方法建立一個實例.而後調用實例的tostring方法.客戶端的javascript將返回給reply對象(此時reply是java.util.date的字符串形式) 
3.5 The 'scripted' Creator 
DWR 已經默認配置了scripted creator配置, 
<creator id="script" class="uk.ltd.getahead.dwr.create.ScriptedCreator"/>這種類型的creator採用BSF執行腳本語言並返回bean.例如 

Xml代碼  收藏代碼

  1. <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>



4 Signatures in dwr.xml 
Signatures部分用於配置Collections中裝載對象元素的類型.舉個例子來講:下面的java代碼沒有辦法對List集合中的對象進行轉換. 

Java代碼  收藏代碼

  1. public class Check  
    {  
      public void setLotteryResults(List nos)  
      {  
          ...  
      }  
    }


Singatures配置容許咱們對DWR要操做的對象類型進行配置.對於瞭解JDK5泛型編程的開發人員來講下面的格式是很容易理解的. 

Xml代碼  收藏代碼

  1.   

  2. <signatures>  
      <![CDATA[ 
      import java.util.List; 
      import com.example.Check; 
      Check.setLotteryResults(List<Integer> nos); 
      ]]>  
    </signatures>


DWR有個專門用於解析上面配置語句的解析器,雖然上面的是JDK5中才有的特性,由於有解析器的緣由這也能夠應用與JDK5以前的版本. 
解析規則是不可見的,但有兩種例外狀況. 
一種狀況是由於DWR1.0的解析器中有個Bug,在有些場合會沒法處理返回值的類型.因此應該要避免這種狀況的發生. 
一種狀況是由於解析器是一個語法寬鬆的解析器,他不象編譯器同樣對語法有很是嚴格的要求,全部有時可能一些重要的語句沒有配置而沒法事先發現. 

Xml代碼  收藏代碼

  1.  

  2. <signatures>  
      <![CDATA[ 
      import java.util.List; 
      Check.setLotteryResults(List<Integer>); 
      ]]>  
    </signatures>


DWR的未來版本可能會採用符合java官方規範的解析器,這樣能夠避免許多出錯的狀況. 
Signature部分只用於泛型參數到基本類型參數的轉換,對於其餘的類型DWR採用反射機制或運行時類型來肯定.在沒有泛型參數的狀況下能夠不配置Signature. 

Java代碼  收藏代碼

  1. public void method(String p);  
    public void method(String[] p);

下面的就須要配置,由於反射機制沒法完成次類功能. 

Java代碼  收藏代碼

  1. public void method(List<Date> p);  
    public void method(Map<String, WibbleBean> p);

下面能夠不用配置,DWR能夠自動完成轉換. 

Java代碼  收藏代碼

  1. public void method(List<String> p);  
    public void method(Map<String, String> p);


下面能夠不用設置,DWR能夠採用運行時轉換. 

Java代碼  收藏代碼

  1. public
     List<Date> method(String p);

有一個值得注意的地方是在javascript中全部對象的keys都是一個字符串,你也能夠把其餘對象做爲keys.他們在使用以前都會轉換成字符串形式.DWR1.x將採用這個特性來轉換成String.之後對象的轉換將會在服務器端完成. 

5 Scripting Introduction 
DWR生成的javascript代碼和java代碼很類似並經過dwr.xml配置輸出.相比普通java異步調用之下,經過ajax生成遠程接口和java 代碼的最大挑戰是AJAX異步功能. 
DWR經過引入一個回調函數,當數據從服務返回數據是調用這個函數。有兩種推薦的方法使用回調函數。一在參數列表加入回調功能。二增長調用元數據對象調用。 
也能夠將回調的功能放在參數列表的前頭,可是不建議使用這樣的用法,由於在處理自動HTTP對象時候會出現問題。這些方法通常會保持向後兼容。 
5.1 Simple Callback Functions 
假設有個下面的java方法。 

Java代碼  收藏代碼

  1. public class Remote  
    {  
        public String getData(int index) { ... }  
    }

在javascript中就能夠如下面的方式引用。 

Js代碼  收藏代碼

  1. <script type="text/javascript"  
        src="[WEBAPP]/dwr/interface/Remote.js"> </script>  
    <script type="text/javascript"  
        src="[WEBAPP]/dwr/engine.js"> </script>  
    ...  
    function handleGetData(str)  
    {  
      alert(str);  
    }


Remote.getData(42, handleGetData); 
「42」只是一個傳給getdata方法的參數。固然你能夠採用下面的寫法。 
Remote.getData(42, function(str) { alert(str); }); 
5.2 Call Meta-Data Objects 
另外一種使用回調功能的方法是指定一個回調功能選項或其餘可選項。上面的例子就變成下面的形式。 

Js代碼  收藏代碼

  1. Remote.getData(42, {  
      callback:function(str) { alert(str); }  
    });


這個方法具備如下幾個優勢:能夠依照你的編碼習慣來編寫程序,更重要的是容許你增長額外的調用選項。 
5.3 Timeouts and Handling Errors 
除了使用回調功能你還能夠指定超時時限和錯誤處理方法。例如: 

Js代碼  收藏代碼

  1. Remote.getData(42, {  
      callback:function(str) { alert(str); },  
      timout:5000,  
      errorHandler:function(message) { alert("Oops: " + message); }  
    });
  2. 5.4   

Finding the callback method 
下面有幾個實例來講明回調功能各個參數選項的配置,由於javascript是不支持函數重載的。 
Remote.method({ timeout:3 }, { errorHandler:somefunc }); 
上面的兩個參數一個是bean的參數一個是回調元數據對象。可是沒有方法去區別這兩種參數選項。在拋開特定的瀏覽器環境,咱們假設null==undefined,因此具備如下規則: 
若是一個函數的每一個調用都是回調函數,那麼他就沒有調用元數據對象,全部的參數都是普通java參數。 
若是一個最後一個參數具備一個回調功能,那麼這個參數就是調用元數據對象。其他的就是普通java參數。 
若是第一個參數爲null,咱們就認爲沒有回調功能。其他的就是普通java參數。此外還要檢查最後一個參數是否爲null,若是是則會給予提示信息。 
若是最後一個參數爲null,則沒有回調功能。 
還有一個不是很好的約定格式,要表示錯誤信息。 
6 Engin.js文件 
這個文件是DWR的引擎文件,他承擔着把後臺自動生成的javascript接口與前臺調用之間的銜接責任。因此任何使用DWR的地方都須要這個文件。 
每一個使用DWR的頁面都必須引入這個文件: 

Xml代碼  收藏代碼

  1. <script type='text/javascript'  
        src='/[YOUR-WEB-APP]/dwr/engine.js'>  
    </script>


6.1 Call Batching 
應用批量功能能夠一次性調用多個遠程bean方法,由於他是將多個調用作爲一次請求,這就減小了與服務器的交互。能夠減小許多的開銷。 
一個批量方法調用以DWREngine.beginBatch()開始WREngine.endBatch()結束。當DWREngine.endBatch()被調用時就說明開始調用批量方法,DWR就將這些方法打包在一塊兒做爲一次請求發送給服務器。 
DWR會確保全部的方法都回被調用,因此使用批量功能是要注意是否提交了批量調用,若是沒有提交批量調用那麼這些須要調用的方法將永遠排在調用隊列中直到提交批量調用。 
注意:批量調用方法會有一些缺點,好比他不能在那些已經幫定在一塊兒的方法調用順序不能保證同步。 
例如全部的調用元數據對象的接管函數,超時設定,錯誤處理等的調用都是在批量的級別上,而不是在調用的級別上。若是一個批量調用含有兩個不一樣超時時間設定的方法,那麼除了最後一個以外的全部其餘方法的超時設定都被忽略。 
6.2 Call Ordering 
由於AJAX是個普通的異步遠程方法調用模式,因此遠程調用的返回結果的順序可能和你發送請求的順序不一致。DWREngine.setOrdered(boolean)方法容許你設置遠程調用返回結果的順序和你發送調用請求的順序保持一致。DWR是經過一個遠程方法調用已經結束後在發送下一個調用請求來實現這個功能的。 
通常狀況咱們並不須要返回結果順序和發送請求順序保持一致。DWR默認是不保持一致的。 
提示:由於保持上面的順序會對應用程序的性能和響應時間,若是其中的一個消息發生丟失那麼瀏覽器可能會有意想不到之外狀況發生。在使用這個功能的時候必須認真考慮是否真的有必要使用。一般比較好的方法是使用異步模式調用。 
6.3 Handling Errors and Warnings 
對於一些服務器端發生的錯誤或警告狀況DWR都回調用默認的錯誤和警告方法而且傳遞一個相關信息,一般這些發生的錯誤和異常對於用戶來講是不可見的。 
下面這個方法主要用於以消息框的方式或者在狀態欄裏顯示一個錯誤或警告的消息。 
要改變錯誤的處理方法可使用這個方法:DWREngine.setErrorHandler(function), 
改變警告的處理方法可使用這個方法:DWREngine.setWarningHandler(function). 
6.4 Remoting Hooks 
參考 DWREngine.setPreHook(function) and DWREngine.setPostHook(function). 
若是你想在執行遠程方法調用以前或以後進行一些處理的話,你可使用上面的兩個方法。上面參數中設置的目標方法必須是沒有參數的。若是你想限制特定的組件在一次方法調用沒有結束以前不容許再次調用,那麼使用上面的方法將頗有用。 
Post 執行Hooks一般是設置pre-hooks,通常用來撤消先前的操做。關於Hooks的例子能夠參照;DWRUtil.useLoadingMessage() 函數。 
6.5 Remoting Options(遠程調用設置) 
關於DWR處理遠程調用有若干個設置選項,Method和Verbs對於用戶來講是透明的,但對於不一樣的瀏覽器可能會有影響。一般DWR會選擇正確的方法處理,若是想饒過某些瀏覽器產生的影響這些參數設置將很是有用。 
DWREngine.setMethod(newmethod) 
設置Method的實際執行方法,但被設置的方法不能確保被調用。只是DWR首先會嘗試調用這個方法。newmethod 必須是DWREngine.XMLHttpRequest 或着 DWREngine.IFrame. 
DWREngine.setVerb(verb) 
容許設置iframe 和 XMLHttpRequest提交數據時的方式,必須是POST或者GET,若是瀏覽器不支持POST形式,DWR會自動切換到GET方式。

相關文章
相關標籤/搜索