DWRのオブジェクト変換
DWRのオブジェクト変換ではできないこと
DWRでは、JavaScriptで連想配列を作って、リモートオブジェクトの引数にすることができます。それについては公式ドキュメントのイントロダクションを見てください*1。
ただし、次の場合オブジェクトを変換することはできません。
- リモートオブジェクトで定義してるメソッドの引数と、JavaScriptから連想配列で作って渡すオブジェクトのプロパティが異なる場合
- この場合JavaScriptで引数として渡すオブジェクトは、定義されている引数とインタフェイスが同じであったり、サブクラスであってもだめです。
こんな例を考える
名前 | タイプ | 詳細 |
StringBean | クラス | ContentsBeanを実装したデータ型 |
ContentsBean | インタフェイス | データ型 |
ContentsBeanContener | クラス | ContentsBeanを保持するためのデータ型 |
これをhtmlから呼んでみます
function post(){ var stringBean = {str:"値を送信してみます"}; StringBeanContener.setBean(stringBean); }
StringBeanクラスを意識して作った連想配列をsetBeanに渡します。
ContentsBeanContenerには次のようなメソッドを実装する
public void setBean(ContentsBean bean){ this.bean = bean; } public ContentsBean getBean(){ return this.bean; }
実際にsetBeanが受け取る引数はStringBeanでなく、ContentsBeanです。
StringBean
public class StringBean implements ContentsBean{ String str; //コンストラクタ public StringBean(String str){ this.str = str } getterとsetter… }
その代わりStringBeanはContentsBeanを実装して作られています.
ContentsBeanインタフェイス
interface ContentsBean{ }
これは特に中身を決めていません
これを実行するとサーバのコンソールにこんなエラーが表示されます
No methods called class 'ContentsBeanContener.setBean' are applicable for the passed parameters.
どうやらsetBeanの引数はStringBeanとして定義しないといけなかったようです。
この場合こう直すのが正解
ContentsBeanContenerには次のようなメソッドを実装する
public void setBean(StringBean bean){ this.bean = bean; } public StringBean getBean(){ return this.bean; }
引数の型と返り値の型を変更しました。
逆にサーバから値を受け取る場合はインタフェイスを使っても大丈夫です
ContentsBeanContenerのgetBeanメソッドをindex.htmlから実行してみます。これを実行するとContentsBean(実体はStringBean)が返ってきます。この場合はContentsBeanをStringBeanと同じように扱えます
function call(){ ContentsBeanContener.getBean(callback); } function callback(bean){ document.write(bean.str); //インタフェイスはContentsBeanだが、StringBeanが入ってる }