てことで、動作を確認したいので簡単なサンプルを作成しました。
動作させるためには、以下のものを用意します。
ひとつずついきます。
[web.xml]
<?xml version="1.0" encoding="Windows-31J"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>MyDWRSamples</display-name> <description> My DWR Samples </description> <!-- 各種フィルター定義 --> <filter> <filter-name>requestEncodingFilter</filter-name> <filter-class>gsf.util.servlet.filter.UTF8EncodingFilter</filter-class> </filter> <filter> <filter-name>responseCharsetFilter</filter-name> <filter-class>gsf.util.servlet.filter.ShiftJISCharsetResponseFilter</filter-class> </filter> <!-- 各フィルターのマッピング --> <filter-mapping> <filter-name>requestEncodingFilter</filter-name> <url-pattern>/app/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>responseCharsetFilter</filter-name> <url-pattern>/app/*</url-pattern> </filter-mapping> <!-- サーブレットの定義 DWRサーブレットの定義 --> <servlet> <servlet-name>DWRInvoker</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <!-- サーブレットのマッピング --> <servlet-mapping> <servlet-name>DWRInvoker</servlet-name> <url-pattern>/app/*</url-pattern> </servlet-mapping> </web-app>
web.xmlには、DWRサーブレットを指定します。このサーブレットがJSとJAVAの連携を
行います。init-paramにdebugを指定しておくと
http://xxxxx/アプリ名/app/
にアクセスすると、連携できるクラスの一覧が表示されたりします。
これ、かなり便利ですので開発中はtrueにしておきましょう。
次は、DWRの設定ファイルです。
このファイルに、連携設定を書きます。
[dwr.xml]
<?xml version="1.0" encoding="Windows-31J"?> <dwr> <allow> <convert converter="bean" match="gsf.samples.dwr.DWRSample001"/> <create creator="new" javascript="DWRSample001"> <param name="class" value="gsf.samples.dwr.DWRSample001"/> </create> </allow> </dwr>
最初のconvert要素は、javascript側で使用するための設定みたいです。
ドキュメントちゃんと読んでないのであまり意味わかってません・・。
多分、javascript内でjavaのbeanを使用する際に、設定する項目だと
おもいますので、今回のサンプルでは定義する必要がないかも・・。w
次は、連携クラスを設定。見たままですが、該当クラスをnewしてねって
お願いしています。
次は、連携クラス.
こちらは普通のクラスです。
DWRは実装には手を出してこないので何かのクラスを継承しなければ
ならないということはありません。そのままクラスを書きます。
通常、開発ではこの部分はDAOやサービスが連携モジュールになるでしょう。
// vim:set ts=4 sw=4 et ws is nowrap ft=java fenc=cp932 ff=dos: package gsf.samples.dwr; public class DWRSample001{ public String toUpperCase(String message){ if(message == null){ return ""; } try{ Thread.currentThread().sleep(500); }catch(Exception ex){} return message.toUpperCase(); } }
今回は、単に受け取ったデータを大文字にして返しているだけです。
ただ、それだと通信処理がすぐ終わってしまうので明示的に500ミリ秒
処理をとめてから戻しています。
最後に画面HTMLです。
<html> <head> <script src="app/interface/DWRSample001.js"></script> <script src="app/engine.js"></script> <script src="app/util.js"></script> <script> function sendValue(){ var field1Value = $("field1").value; if(field1Value != ""){ DWRSample001.toUpperCase(field1Value, myCallBackFunction); $("statusArea").innerHTML = "バックグラウンドで通信中・・・・"; } } function myCallBackFunction(upperCasedValue){ $("field2").value = upperCasedValue; $("statusArea").innerHTML = "通信完了。"; } </script> </head> <body> <br/> <br/> <hr/> <center> <span id="statusArea" style="color:red"></span> <br/> <input id="field1" type="text" name="field1" value="" onChange="sendValue();"/> <br/> <br/> <input id="field2" type="text" name="field2" value="" onFocus="document.getElementById('field1').focus();"/> </center> <hr/> <br/> <br/> </body> </html>
画面側での決まりごとは以下の点です。
- 以下の3つをHEADタグ内でscript定義する。
<script src="アプリ名/interface/[dwr.xmlで定義したjavascript属性の値].js"></script> <script src="アプリ名/engine.js"></script> <script src="アプリ名/util.js"></script>
- サーバー側と連携する際、戻り値を受け取る場合は最後の引数にコールバック関数を渡す.
今回の画面では、myCallBackFunction関数がコールバック関数となります。
なぜ、
var returnValue = DWRSample001.toUpperCase(field1Value);
とせずに、コールバックが必要なのでしょうか。
答えは、この処理が非同期で実行されるからです。
同期実行なら処理が終わるまで待たされますが、非同期なので
メソッドコールしたらすぐに処理が戻ってきます。でも、サーバー側の処理が
終わったわけではないので、値が受け取れません。
そのため、終わり次第、こちらの処理が走るようにするわけです。
なのでコールバックが必要になります。
Ajaxアプリは通信が非同期で行われるので、この辺を理解して処理を
考えないといけません。
あとは、デプロイしたら完了です。
実際に画面を立ち上げると、入力フィールドが二つあり上の入力フィールドに値を
入力してエンターなどを押下するとサーバーとの連携が始まります。
連携が終わると下側の入力フィールドに大文字に変換された値が表示されます。
ちなみに、htmlのjavascriptソースコード内で
$("hoge").value
などとしている部分がありますが、これはprototype.jsにあるのと同じように
document.getElementById("hoge").value
のショートカット関数です。DWRUtil.jsに定義されています。
DWRのサイトは、ドキュメントが充実している模様ですので、ちょこちょこ
読んで理解していきたいとおもいます。