posts - 30, comments - 5, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          DWR.xml配置文件說明書

          Posted on 2010-05-04 10:43 無所謂 閱讀(435) 評論(0)  編輯  收藏 所屬分類: DWR

          1、建立dwr.xml 配置文件

          任何一個dwr.xml的文件都需要包含DWR DOCTYPE的聲明行,格式如下:

          <!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'配置行.下面列出的類的轉換在默認情況下不需要進一步的設置.

          1、所有基本類型,boolean,int,double等等

          2、基本類型的對象形式實現的類,Boolean,Integer等等

          3、java.lang.String

          4、java.util.date 和三個SQL形式的派生類

          5、以上所有類型的數組形式

          6、以上所有類型的集合,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.

          2、The Converters

          DWR已經默認定義和初始化了常用的Converter,他們分別如下:

          <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值就是這樣設置de><convert converter="null" match="void"/>de>. 有時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的這行有點奇怪.

          <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和從次類派生的所有類.相關配置語法如下

          <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

          <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方法之外的所有方法都不可訪問可以采用下面的設置.

          <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的創建和遠程方法調用設置:

           

          <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.例如

           

          <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集合中的對象進行轉換.

           

          public class Check 



          public void setLotteryResults(List nos) 



           

          }
           

          }
           

           

          Singatures配置允許我們對DWR要操作的對象類型進行配置.對于了解JDK5泛型編程的開發人員來說下面的格式是很容易理解的.

          <signatures>

          <![CDATA[

          import java.util.List;

          import com.example.Check;

          Check.setLotteryResults(List<Integer> nos);

          ]]>

          </signatures>

          DWR有個專門用于解析上面配置語句的解析器,雖然上面的是JDK5中才有的特性,因為有解析器的原因這也可以應用與JDK5之前的版本.

          解析規則是不可見的,但有兩種例外情況.

          一種情況是因為DWR1.0的解析器中有個Bug,在有些場合會無法處理返回值的類型.所以應該要避免這種情況的發生.

          一種情況是因為解析器是一個語法寬松的解析器,他不象編譯器一樣對語法有非常嚴格的要求,所有有時可能一些重要的語句沒有配置而無法事先發現.

           

          <signatures> 

          <![CDATA[ 

          import java.util.List; 

          Check.setLotteryResults(List<Integer>); 

          ]]> 

          </signatures> 

           

          DWR的將來版本可能會采用符合java官方規范的解析器,這樣可以避免許多出錯的情況.

          Signature部分只用于泛型參數到基本類型參數的轉換,對于其他的類型DWR采用反射機制或運行時類型來確定.在沒有泛型參數的情況下可以不配置Signature.

          public void method(String p);

          public void method(String[] p);

          下面的就需要配置,因為反射機制無法完成次類功能.

          public void method(List<Date> p);

          public void method(Map<String, WibbleBean> p);

          下面可以不用配置,DWR可以自動完成轉換.

          public void method(List<String> p);

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

          下面可以不用設置,DWR可以采用運行時轉換.

          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方法。

          public class Remote

          {

          public String getData(int index) { ... }

          }

          在javascript中就可以以下面的方式引用。

           

          <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

          另一種使用回調功能的方法是指定一個回調功能選項或其他可選項。上面的例子就變成下面的形式。

          Remote.getData(42, {

          callback:function(str) { alert(str); }

          });

          這個方法具有以下幾個優點:可以依照你的編碼習慣來編寫程序,更重要的是允許你增加額外的調用選項。

          5.3 Timeouts and Handling Errors

          除了使用回調功能你還可以指定超時時限和錯誤處理方法。例如:

          Remote.getData(42, {

          callback:function(str) { alert(str); },

          timout:5000,

          errorHandler:function(message) { alert("Oops: " + message); }

          });

          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的頁面都必須引入這個文件:

          <script type='text/javascript'

          src='/[YOUR-WEB-APP]/dwr/engine.js'>

          </script>

          6.1 Call Batching

          應用批量功能可以一次性調用多個遠程bean方法,因為他是將多個調用做為一次請求,這就減少了與服務器的交互??梢詼p少許多的開銷。

          一個批量方法調用以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方式。

          主站蜘蛛池模板: 康保县| 明水县| 蒲城县| 盘山县| 易门县| 蒙山县| 宝鸡市| 呼伦贝尔市| 社会| 鄂尔多斯市| 邛崃市| 安多县| 仲巴县| 剑河县| 忻城县| 获嘉县| 合江县| 瑞金市| 大厂| 剑阁县| 连城县| 东城区| 那坡县| 舒城县| 台中县| 蓬莱市| 平安县| 宁都县| 镇康县| 阿尔山市| 甘德县| 南京市| 昌邑市| 揭西县| 子长县| 白沙| 嘉峪关市| 恭城| 朝阳区| 兴海县| 灵武市|