Direct Web Remoting
そのサンプリングを始めるにあたり、ようやく辿りついた、との感慨深い。
Ajaxが流行り始めた頃、(残念ながら廃刊になってしまった)「Javaワールド」誌を休暇中の旅先に持っていった。
JavaでAjax(XHR;XMLHttpRequestによる非同期通信を用いた処理系)を実現するツールとして、このDWRが掲載されていた。
その頃、(このログでサンプリングしてきた)YUIはバージョン0.11。
それから3年以上。DWRも、現時点で2.05(stable)とともに3.0(RC1)が配布されている。
Downloadは、DWRのホームページ(リンクはこちら)のダウンロードページ(リンクはこちら)から行う。
サンプリングはV2.05で行う。開発環境は以下。
開発するには、dwr.jarだけが必要であるが、dwr.warをTomcatのwebapps下に置くと、展開されてExampleが動くようになる。
以下では、このExampleの先頭にある「Dynamic Text(一番簡単なXHRの例)」を、Eclipse環境で簡単に改造する。
初期画面(demo.html)は以下。
上で「名前」を入力し、送信ボタンを押すと、以下のようなレスポンスが返る(demo.html)。
リクエストパラメータである「名前」は、XHRでTomcat(Web Application Server)に送られ、『こんにちは 「名前」 さん』という文字列が戻る、という仕組みである。
先に「開発にはdwr.jarだけが必要」と書いたが、(DWRは)内部的にcommons-loggingを利用しているので、必要に応じて、Apacheのcommons-loggingのホームページ(リンクはこちら)からダウンロードしておく(1.1.1をダウンロードした)。
Eclipseの設定はそれぞれと思うが、Tomcat Pluginを入れている環境では、プロジェクト作成時にjavaプロジェクトから、Tomcatプロジェクトを選択する。
まず、WEB-INF/libディレクトリに、dwr.jarを入れる(必要に応じて、commons-logging.jarを入れる)。
次に、WEB-INF/web.xmlを以下のようにする(DWR.warのweb.xmlを参照)。
<?xml version="1.0" encoding="utf-8"?> <!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 id="dwr"> <display-name>DWR (Direct Web Remoting)</display-name> <description>Sampling DWR</description> <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWR Servlet</display-name> <description>Direct Web Remoter Servlet</description> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <!-- This should NEVER be present in live --> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <!-- Remove this unless you want to use active reverse ajax --> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <!-- By default DWR creates application scope objects when they are first used. This creates them when the app-server is started --> <init-param> <param-name>initApplicationScopeCreatorsAtStartup</param-name> <param-value>true</param-value> </init-param> <!-- This enables full streaming mode. It's probably better to leave this out if you are running across the internet --> <init-param> <param-name>maxWaitAfterWrite</param-name> <param-value>-1</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> </web-app>
web.xml(Deployment Descriptor)は、アプリケーション基本設定を行うものであるが、上では、
- servlerタグ配下で、org.directwebremoting.servlet.DwrServletの初期パラメータ(init-param)設定を行う。同時に、load-on-startupでアプリケーション起動時にこのサーブレットをロードする設定をする(load-on-startupは数が小さいほど、先にローディングされる)。
- servlet-mapping配下は、一種の「おまじない」。/dwrというディレクトリは存在しないが、このように設定しておく。
としている。
また、このサンプルでは、以下の1つのHTML(+Javascript)と1つのJavaクラスを作成する。
ファイル名 | 役割 |
demo.html | 「名前」の入力を促し、それをXHRでWeb Application Serverに送る。結果(『こんにちは、「名前」さん』という文字列)をコールバック関数で受け取って表示する。 |
Demo.java | demo.htmlからの「名前」を受け取り、『こんにちは、「名前」さん』という文字列をreturnするPOJO。testパッケージに作成した。 |
ここで、Demo.javaが(ServletAPIに関係ない)POJOであることは非常に重要である。
POJOということは、Unitテストが簡易化されるなどのアドバンテージがある。
DWRを利用するにあたっては、WEB-INF配下に、dwr.xmlという設定ファイルを置く。
これは、(HTML中の)JavascriptとPOJO(Demo.java)をワイアリングするための設定ファイルである。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://directwebremoting.org/schema/dwr20.dtd"> <dwr> <allow> <!-- test.Demoというクラスのオブジェクトが「new」によって生成され、 クライアントのJavaScriptでは「Demo」という名前で参照できる ことを意味 --> <create creator="new" javascript="Demo"> <param name="class" value="test.Demo"/> </create> </allow> </dwr>
これらのリソースの配置図は以下。
以下に、demo.htmlとDemo.javaを示す。
まず、demo.html。
「おまじない」がある。util.jsはdwrユーティリティー(setValueとかgetValueとかの関数類)のために必要なので、engine.jsと一緒に必ず読み込む。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>DWRのサンプリング</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <style type="text/css" id="defaultstyle"> body { margin:0; padding:0; } #container { margin: 2px; padding: 3px; line-height:1.5em; width: 500px; height: auto; border:1px dashed #999999; } </style> <!-- Demo.jsはDWRによって自動生成される。 dwr/はドキュメントルートとの相対参照。 --> <script src='dwr/interface/Demo.js'></script> <!-- engine.jsは必須 --> <script src='dwr/engine.js'></script> <!-- util.jsは必須 --> <script src='dwr/util.js'></script> <script type="text/javascript"> function update() { var name = dwr.util.getValue("demoName"); // Demoは、dwr.xmlで定義したPOJO名。sayHelloはメソッド名。 // 第一引数は、sayHelloの引数、第二引数はCallback関数となる。 Demo.sayHello(name, // Callback関数 function(data) { dwr.util.setValue("demoReply", data); } ); } </script> </head> <body> <div id="container"> <p> 簡単なDWRのデモです。<br> 名前を入力して、「送信」ボタンを押してください。 </p> <p> 名前: <input type="text" id="demoName"> <input value="送信" type="button" onclick="update()"> <br> 返信: <span id="demoReply"></span> </p> </div> </body> </html>
最後にDemo.java。
demo.htmlとDemo.javaは、dwr.xmlを要に相互に関係しているので、3つのリソースを一緒に眺めるのがよい。
package test; /** * DWRのデモ * * 名前(name)を受け取って、「こんにちは、name」を返す。 * */ public class Demo { public String sayHello(String name) { return "こんにちは " + name + " さん"; } }