Bean 和 Object 轉(zhuǎn)換器
兩個(gè)沒(méi)有默認(rèn)打開(kāi)的轉(zhuǎn)換器是Bean 和 Object 轉(zhuǎn)換器。Bean轉(zhuǎn)換器可以把POJO轉(zhuǎn)換成Javascript的接合數(shù)組(類(lèi)似與Java中的Map),或者反向轉(zhuǎn)換。這個(gè)轉(zhuǎn)換器默認(rèn)情況下是沒(méi)打開(kāi)的,因?yàn)镈WR要獲得你的允許才能動(dòng)你的代碼。

Object轉(zhuǎn)換器很相似,不同的是它直接應(yīng)用于對(duì)象的成員,而不是通過(guò)getter和setter方法。下面的例子都是可以用object來(lái)替換bean的來(lái)直接訪問(wèn)對(duì)象成員。

如果你有一個(gè)在 <create ...> 中聲明的遠(yuǎn)程調(diào)用Bean。它有個(gè)一參數(shù)也是一個(gè)bean,并且這個(gè)bean有一個(gè)setter存在一些安全隱患,那么攻擊者就可能利用這一點(diǎn)。

你可以為某一個(gè)單獨(dú)的類(lèi)打開(kāi)轉(zhuǎn)換器:

<convert converter="bean" match="your.full.package.BeanName"/>
如果要允許轉(zhuǎn)換一個(gè)包或者子包下面的所有類(lèi),可以這樣寫(xiě):

<convert converter="bean" match="your.full.package.*"/>
顯而易見(jiàn),這樣寫(xiě)是允許轉(zhuǎn)換所有的JavaBean:

<convert converter="bean" match="*"/>
BeanConverter 和 JavaBeans 規(guī)范
用于被BeanConverter轉(zhuǎn)換的Bean必須符合JavaBeans的規(guī)范,因?yàn)檗D(zhuǎn)換器用的是Introspection,而不是Reflection。這就是說(shuō)屬性要符合一下條件:有g(shù)etter和setter,setter有一個(gè)參數(shù),并且這個(gè)參數(shù)的類(lèi)型是getter的返回類(lèi)型。setter應(yīng)該返回void,getter應(yīng)該沒(méi)有任何參數(shù)。setter沒(méi)有重載。以上這些屬于常識(shí)。如果你用的不是JavaBean,那么你應(yīng)該用ObjectConverter.

設(shè)置Javascript變量
DWR可以把Javascript對(duì)象(又名maps,或聯(lián)合數(shù)組)轉(zhuǎn)換成JavaBean或者Java對(duì)象。

一個(gè)簡(jiǎn)單的例子可以幫助你。假設(shè)你有下面的Java代碼:

public class Remoted {
  public void setPerson(Person p) {
    // ...
  }
}

public class Person {
  public void setName(String name) { ... }
  public void setAge(int age) { ... }
  // ...
}
如果這個(gè)Remoted已經(jīng)被配置成Creator了,Persion類(lèi)也定義了BeanConverter,那么你可以通過(guò)下面的方式調(diào)用Java代碼:

var p = { name:"Fred", age:21 };
Remoted.setPerson(p);
限制屬性轉(zhuǎn)換
就像你可以在creator的定義中剔出一些方法一樣,converter也有類(lèi)似的定義。

限制屬性轉(zhuǎn)換僅僅對(duì)于Bean有意義,很明顯原生類(lèi)型是不要需要這個(gè)功能的,所以只有BeanConverter及其子類(lèi)型(HibernateBeanConverter))有這個(gè)功能。

語(yǔ)法是這樣的:

<convert converter="bean" match="com.example.Fred">
  <param name="exclude" value="property1, property2"/>
</convert>
這就保證了DWR不會(huì)調(diào)用 fred.getProperty1() 和fred.getProperty2兩個(gè)方法。另外如果你喜歡"白名單"而不是"黑名單"的話:

<convert converter="bean" match="com.example.Fred">
  <param name="include" value="property1, property2"/>
</convert>
安全上比較好的設(shè)計(jì)是使用"白名單"而不是"黑名單"。

對(duì)象的私有成員
通過(guò)'object'轉(zhuǎn)換器的參數(shù)的一個(gè)名為force的參數(shù),可以讓DWR通過(guò)反射來(lái)訪問(wèn)對(duì)象私有成員。

語(yǔ)法是這樣的:

<convert converter="object" match="com.example.Fred">
  <param name="force" value="true"/>
</convert>
直到DWR1.1.3,這里有一個(gè)bug,public的field反而不能被發(fā)現(xiàn),所以你需要在public成員上設(shè)置force=true。