DWR學(xué)習(xí)筆記(三)
js 2010-01-02 19:23:55 閱讀32 評(píng)論 字號(hào):大中小 訂閱
四.DWR配置文件dwr.xml文件詳解:放置到WEB-INF目錄
<dwr>
<!-- 僅當(dāng)需要擴(kuò)展DWR時(shí)才需要 -->
<init>
<creator id="..." class="..." />
<converter id="..." class="..." />
</init>
<!-- 沒有它DWR什么也做不了 -->
<allow>
<create creator="..." javascript="..." />
<convert converter="..." match="..." />
</allow>
<!-- 有必要告訴DWR方法簽名 -->
<signatures>...</signatures>
</dwr>
1.<init>標(biāo)簽:聲明被用來創(chuàng)建遠(yuǎn)程beans和聲明能被用來以某種過程轉(zhuǎn)換的類。
大多數(shù)例子你將不需要用它,如果你想去定義一個(gè)新的Creator或者Converter,就要在此聲明。
在init部分中定義只是告訴DWR這些擴(kuò)展類的存在,給出了如何使用的信息。
這時(shí)這里聲明的類并沒有被使用。這種方式很像Java中的import語句。
多數(shù)類需要在使用前先import一下,但是只有import語句并不表明這個(gè)類已經(jīng)被使用了。
每一個(gè)creator和converter都用是id屬性標(biāo)識(shí),以便后面使用時(shí)直接引用。
2.<allow>標(biāo)簽:allow標(biāo)簽中定義了DWR能夠創(chuàng)建和轉(zhuǎn)換的類。
A.<create>子標(biāo)簽:一個(gè)類對(duì)應(yīng)一個(gè)<create>標(biāo)簽.
i.creator屬性:告訴DWR產(chǎn)生對(duì)應(yīng)類的對(duì)象的方式,因?yàn)镈WR要在頁面通過js調(diào)用該類的對(duì)象的方法,
而我們沒有手動(dòng)產(chǎn)生對(duì)象,那么對(duì)象只能是由DWR來產(chǎn)生,
所以要告訴DWR產(chǎn)生對(duì)象的方式或者是new一個(gè)通過構(gòu)造方法或者是通過從Spring的Ioc容器中取得等,
總之要指定一個(gè)生成對(duì)象的方式。
**注意:如果想寫自己的creator創(chuàng)建器,必須在<init>里注冊(cè)聲明它,然后才可以在<create>的creator屬性中指定并使用。
(1)new創(chuàng)建器:指定DWR生成類的對(duì)象的方式是通過Java的new關(guān)鍵字,調(diào)用缺省構(gòu)造(因?yàn)镈WR將采用反射機(jī)制)方法產(chǎn)生對(duì)象。
這也是DWR的默認(rèn)creator,<create id="new" class="org.directwebremoting.create.NewCreator"/>
所以這個(gè)配置不用放到<init>中聲明,因?yàn)镈WR內(nèi)部已經(jīng)加入。
(2)none創(chuàng)建器:告訴DWR不要?jiǎng)?chuàng)建對(duì)象。有兩種情況適合這種情況!!
<1>可以指定一個(gè)scope值(page除外),并且在調(diào)用該<create>對(duì)應(yīng)類的方法之前已經(jīng)把這個(gè)對(duì)象創(chuàng)建到指定的scope中,
這時(shí)就不需要再創(chuàng)建對(duì)象了,用到時(shí)DWR會(huì)從scope指定的作用域中查找對(duì)象。
<2>另一種情況是要調(diào)用的方法是靜態(tài)的,這時(shí)也不需要?jiǎng)?chuàng)建對(duì)象。
DWR會(huì)在調(diào)用創(chuàng)建器之前先檢查一下這個(gè)方法是不是靜態(tài)的。如果是靜態(tài)的直接用就行。
(3)spring創(chuàng)建器:通過Spring框架訪問Bean
(4)struts創(chuàng)建器:使用Struts的ActionFormBean
(5)jsf創(chuàng)建器:使用JSF的Bean
(6)pageflow創(chuàng)建器:訪問Weblogic或Beehive的PageFlow。
(7)script創(chuàng)建器(不常用):通過BSF使用腳本語言創(chuàng)建對(duì)象,例如BeanShell或Groovy。
要使用這個(gè)創(chuàng)造器,你需要把一些輔助庫放到lib目錄,
比如BSF的jar包,要用的腳本語言的jar包等。
<用到時(shí)再看文檔>
(8)ejb3創(chuàng)建器(測試中,未投入使用):使用EJB3 session bean,一個(gè)正在實(shí)驗(yàn)的創(chuàng)造器,
用來訪問EJB Session beans。直到進(jìn)行更多的測試和正式的維護(hù),
否則還不能作為產(chǎn)品被使用
ii.javascript屬性:指定<create>對(duì)應(yīng)的類的對(duì)象在js中使用時(shí)的對(duì)象名(變量名),
即JSP頁面中可用指定的名字調(diào)用<create>對(duì)應(yīng)的類中的方法。
**注意:頁面中還要導(dǎo)入以指定的javascript屬性值為文件名的js文件
<script type='text/javascript' src='dwr/interface/對(duì)象名.js'>
這是DWR加載dwr.xml配置文件時(shí)內(nèi)部在規(guī)定目錄"dwr/interface/"動(dòng)態(tài)生成的對(duì)應(yīng)對(duì)象名的js文件,
供頁面中導(dǎo)入,以便實(shí)現(xiàn)調(diào)用java對(duì)象。
iii.scope屬性:和servlet、jsp中的scope屬性一樣,指定作用域范圍,分別有page、request、session、application四個(gè)作用域。
默認(rèn)為page作用域。
iv.<param>子標(biāo)簽:輔助指定的creator創(chuàng)造器屬性值的其他參數(shù),每種創(chuàng)造器對(duì)應(yīng)的<param>子標(biāo)簽的值都不相同。
例如"new"創(chuàng)造器需要知道要?jiǎng)?chuàng)建的對(duì)象類型是什么,<param name="class" value="對(duì)應(yīng)的類全名" />
每一種creator創(chuàng)造器的對(duì)應(yīng)的<param>子標(biāo)簽的參數(shù)在各自的文檔中能找到。
v.<include>和<exclude>子標(biāo)簽:用于限定DWR在頁面可以調(diào)用<create>對(duì)應(yīng)類的方法。
例如<create creator="new" javascript="dwrTest">
<param name="class" value="com.lj.dwrproject.DWRTest" />
<include method="sayHello" />
</create>
說明在頁面通過DWR只能調(diào)用DWRTest類中的sayHello()方法;
如果用<exclude>指定就是不能調(diào)用sayHello()方法,其他方法仍然可以調(diào)用。
vi.<auth>子標(biāo)簽(了解):允許指定一個(gè)JavaEE的角色作為將來的訪問控制檢查:
<create creator="new" javascript="dwrTest">
<param name="class" value="com.lj.dwrproject.DWRTest" />
<auth method="sayHello" role="admin" />
</create>
**注意:
(1)使用靜態(tài)方法時(shí),DWR會(huì)在調(diào)用創(chuàng)建器之前先檢查一下這個(gè)方法是不是靜態(tài)的,
如果是那么創(chuàng)造器不會(huì)被調(diào)用。這個(gè)規(guī)則適用于所有創(chuàng)造器。
(2)scope屬性:指定的范圍是<create>對(duì)應(yīng)的類對(duì)象的保存作用域,對(duì)于DWR1.x版本,
它在每次請(qǐng)求時(shí)都會(huì)調(diào)用一次setAttribute()方法,就是每次在頁面調(diào)用對(duì)象的方法時(shí),
DWR都會(huì)調(diào)用一側(cè)scope.setAttribute()方法;
而DWR 2只在第一次創(chuàng)建對(duì)象時(shí)調(diào)用scope.setAttribute()方法,
解決了如果使用servlet的事件機(jī)制時(shí),
如HttpRequestAttributeListener每次都會(huì)觸發(fā)屬性事件的麻煩。
(3)使用單例類時(shí)(了解),對(duì)于單例類的創(chuàng)建,最好使用BeanShell和BSF來實(shí)例化對(duì)象,即script創(chuàng)建器。
B.<convert>子標(biāo)簽:為了確保DWR頁面調(diào)用java對(duì)象方法傳入?yún)?shù)時(shí)所有的參數(shù)能被正確的轉(zhuǎn)換。
之所以涉及到轉(zhuǎn)換的原因就是,我們是通過js來調(diào)用的java對(duì)象方法,傳入的參數(shù)也都是js的類型,
但是DWR會(huì)在內(nèi)部真實(shí)的通過傳入的js參數(shù)調(diào)用對(duì)應(yīng)的java對(duì)象的方法,
此時(shí)就應(yīng)該保證js的類型能夠正確的轉(zhuǎn)換成java中的參數(shù)類型。
例如java方法sayHello(String name)接受java的String類型,
但是js調(diào)用是傳入的是一個(gè)var類型的,為了讓DWR內(nèi)部調(diào)用sayHello時(shí)成功將var類型轉(zhuǎn)換成String類型。
當(dāng)然這個(gè)是不用特別指出的,但是有時(shí)我們會(huì)自定義一些類型,此時(shí)就要聲明轉(zhuǎn)換器。
(1)不需要用<convert>指定轉(zhuǎn)換器的類型有:這些DWR默認(rèn)支持它們的轉(zhuǎn)換
<1>所有的基本數(shù)據(jù)類型,boolean, int , double等
<2>包裝類,Boolean, Integer等
<3>java.lang.String
<4>java.util.Date 和 java.sql.Times,java.sql.Timestamp
<5>數(shù)組,但是限制為存放以上類型的數(shù)組,不包括自定義的或者集合的數(shù)組。
<6>DOM對(duì)象(來自于DOM, XOM, JDOM和DOM4J)
(2)Bean和Object轉(zhuǎn)換器:DWR是支持這兩種參數(shù)的轉(zhuǎn)換的,只不過默認(rèn)情況是關(guān)閉狀態(tài)。
Bean轉(zhuǎn)換器可以把POJO轉(zhuǎn)換成Javascript的接合數(shù)組(類似與Java中的Map),
或者反向轉(zhuǎn)換(即java對(duì)象的方法返回一個(gè)Bean對(duì)象,js中接受的將會(huì)是轉(zhuǎn)換好了的接合數(shù)組)。
Object轉(zhuǎn)換器與Bean轉(zhuǎn)換器很相似,不同的是它直接應(yīng)用于對(duì)象的成員,而不是通過調(diào)用getter和setter方法。
這也要求作為Bean參數(shù)的對(duì)象必須符合javaBean的規(guī)范(要有g(shù)etter和setter方法)
**說明:應(yīng)用的場合就是當(dāng)我們定義的java類中的方法的參數(shù)中有自定義的Bean規(guī)范的自定義對(duì)象,
那么在頁面js調(diào)用傳遞參數(shù)的時(shí)候會(huì)出現(xiàn)轉(zhuǎn)換異常,因?yàn)镈WR不知道怎么轉(zhuǎn)換,
此時(shí)就可以為該參數(shù)對(duì)象的java類指定開啟轉(zhuǎn)換器功能。
**使用方法:
<1>只為單個(gè)類開啟Bean轉(zhuǎn)換器功能,也就是說當(dāng)其他Bean類也作為參數(shù)時(shí),它的Bean轉(zhuǎn)換器是關(guān)閉的。
<convert converter="bean" match="your.full.package.BeanName"/>
<2>為一個(gè)包中的所有類都打開Bean轉(zhuǎn)換器功能
<convert converter="bean" match="your.full.package.*"/>
<3>為所有類都打開轉(zhuǎn)換器功能
<convert converter="bean" match="*"/>
<4>Object轉(zhuǎn)換器的使用方法道理相同
**詳細(xì)說明:像上面通過converter指定bean屬性值為什么就可以開啟轉(zhuǎn)換器功能呢?
是因?yàn)镈WR內(nèi)部已經(jīng)實(shí)現(xiàn)了對(duì)bean值將會(huì)分配一個(gè)BeanConverter類作為對(duì)應(yīng)參數(shù)類的轉(zhuǎn)換器,
也就是當(dāng)涉及到指定的類的轉(zhuǎn)換時(shí),那么BeanConverter就會(huì)進(jìn)行轉(zhuǎn)換功能,這都是DWR內(nèi)部的實(shí)現(xiàn)。
對(duì)于converter="object"的時(shí)候,那么DWR將會(huì)通過ObjectConverter轉(zhuǎn)換類來處理指定的要進(jìn)行轉(zhuǎn)換的類。
**限制轉(zhuǎn)換器(基本不會(huì)用):類似<create>中的<include>和<exclude>子標(biāo)簽,
只不過只有BeanConverter及其子轉(zhuǎn)換器HibernateBeanConverter有這個(gè)功能。
也就是只有converter="bean"時(shí)才能用此功能。
<convert converter="bean" match="com.lj.dwrproject.DWRTest">
<param name="include" value="property1, property2" />
</convert>
意思是DWR使用轉(zhuǎn)換器BeanConverter時(shí)只能調(diào)用getProperty1()和getProperty2()方法完成轉(zhuǎn)換。
**訪問對(duì)象的私有成員(基本不會(huì)用):用的時(shí)候可以查看文檔。
(3)集合類型轉(zhuǎn)換器:默認(rèn)是開啟的上面已經(jīng)說明,此處類出DWR內(nèi)部的配置供了解參考。此處我們分析它的缺點(diǎn)!!
<1><convert converter="collection" match="java.util.Collection"/>
<2><convert converter="map" match="java.util.Map"/>
**缺點(diǎn)與不足:用反射機(jī)制是沒有方法明確集合里面是什么類型的。
所以這兩個(gè)轉(zhuǎn)換器不能把集合里面的東西轉(zhuǎn)換成有意義的Javascript對(duì)象。
**解決方法:可以在dwr.xml中<signatures>標(biāo)簽語法聲明集合中元素的類型,使之正確轉(zhuǎn)換。
<詳細(xì)見下邊>
(4)枚舉類型轉(zhuǎn)換器(了解):用時(shí)可以查看文檔
(5)DOM對(duì)象:默認(rèn)也是開啟的。
DWR可以自動(dòng)轉(zhuǎn)換來之DOM,DOM4J,JDOM和XOM的DOM樹。
可以簡單得用上面這些類庫返回一個(gè)Document、Element或者Node,DWR會(huì)把他們自動(dòng)轉(zhuǎn)換成瀏覽器的DOM對(duì)象。
**小小的問題(了解):在程序啟動(dòng)的時(shí)候會(huì)有一個(gè)常見的關(guān)于JDOM轉(zhuǎn)換器的警告,
可以放心的忽略它,除非你要用JDOM:
INFO: Missing classdef for converter 'jdom'.
Failed to load uk.ltd.getahead.dwr.convert.JDOMConverter. Cause: org/jdom/Document
因?yàn)镈WR沒有辦法知道你是否想用JDOM,所以這個(gè)信息設(shè)在INFO級(jí)別的。
3.<signatures>標(biāo)簽:DWR使用反射機(jī)制在轉(zhuǎn)換過程中找到它應(yīng)該使用的類型。
有時(shí)候類型的信息無法獲得,在這種情況下你要在此處用方法簽名給予聲明。
signatures段使DWR能確定集合中存放的數(shù)據(jù)類型(泛型指定的類型)。
A.**主要目的:就是讓DWR在頁面中通過js調(diào)用java方法時(shí),用來確定集合泛型參數(shù)中的類型參數(shù),
以完成正確的從js類型轉(zhuǎn)換成java類型,正確的傳入調(diào)用的方法中,完成操作。
B.例如下面的定義中我們無法知道list中存放的是什么類型。
public class Check{
public void setLotteryResults(List nos){
......
}
}
**問題:如果在jsp中通過js調(diào)用該方法并且傳遞參數(shù)時(shí),
DWR不知道將js生成的集合中的元素轉(zhuǎn)換成java的什么類型然后傳給該方法。
**解決方案:重新聲明了一下Check類中的方法,此時(shí)通過了泛型,
這樣調(diào)用時(shí)傳的參數(shù)集合中的元素DWR就知道轉(zhuǎn)換成java的什么類型進(jìn)而傳給該方法。
<signatures>
<![CDATA[
//導(dǎo)入需要的類,和java中import一樣,
//導(dǎo)入了類就相當(dāng)于告訴DWR轉(zhuǎn)換的類型是什么類型了,默認(rèn)java.lang包中的類不用導(dǎo)入!
import java.util.List;
import com.example.Check;
Check.setLotteryResults(List<Integer> nos);
]]>
</signatures>
C.用與不用signatures段舉例說明:
i.DWR調(diào)用這樣的方法傳參數(shù)時(shí)DWR自己會(huì)知道
怎樣將js類型轉(zhuǎn)換成對(duì)應(yīng)的java類型,因?yàn)闆]有泛型參數(shù)或說成涉及不到泛型參數(shù)。
public void method(String p);
public void method(String[] p);
ii.DWR調(diào)用傳參數(shù)時(shí),可以知道泛型指定的類型怎么轉(zhuǎn)換,不需要signatures段特意標(biāo)識(shí)。
public void method(List<String> p);
public void method(Map<String, String> p);
public List<Date> method(String p);
iii.DWR調(diào)用傳入?yún)?shù)時(shí),將不知道怎樣轉(zhuǎn)換,
其實(shí)主要是不知道怎樣將js中的類型轉(zhuǎn)換成對(duì)應(yīng)的WibbleBean類型,
隨意應(yīng)該通過signatures來導(dǎo)入一下該類的全名,以便告訴DWR進(jìn)而完成轉(zhuǎn)換。
public void method(List<Date> p);
public void method(Map<String, WibbleBean> p);