PR

DWRと連携してみよう

 本連載第4回「DWRで今日から楽々Ajax」で紹介したDWRのバージョンはRC 3なので,Guiceとの連携は実装されていませんでした。しかし,バージョンアップが行われ,DWR 2.0 RC 4以降からGuiceとの連携ができるようになりました。

 連携の機能はGuiceのWikiに「3rdPartyModules」として紹介されています。ポイントは,DWRとGuiceを連携させることによってdwr.xmlを使用せず,すべてJavaで記述できるようになることです。

 では,早速GuiceとDWRの連携を試してみましょう。DWRの最新版(DWR Version 2.0.1)をダウンロード・ページからダウンロードしてください。

 使用するHTMLとbean,サービスは第4回で使用したものと同じソース(service,bean,HTML)を使用します。ただし,インジェクションを行うため,サービスにはインタフェースを作成しています(リスト27)。これらは,連携する場合でも特に変更はありません。


package jp.co.nikkeibp.itpro.guice.dwr;
public interface IMessageService {
    MessageBean execute(String value);
}
リスト27●サービスのインタフェース


package jp.co.nikkeibp.itpro.guice.dwr;
public class MessageService implements IMessageService {
    public MessageBean execute(String value) {
    MessageBean message = new MessageBean();
    message.setMessage(value + "DWR Version 2.0.1 + Guice ");
    return message;
    }
}
リスト28●サービスの実装クラス


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
  content="text/html; charset=UTF-8" />
<title>JavaScript→Java呼び出し</title>
<!-- (1)リモートオブジェクトのインタフェースを取得する -->
<script type="text/javascript"
  src="dwr/interface/MessageService.js">
 </script>
<!-- DWRから提供されている共通JavaScriptの読み込み -->
<script type="text/javascript" src="dwr/engine.js"> </script>
<script type="text/javascript" src="dwr/util.js"> </script>

<script>
  function show() {
    // HTMLからデータを取得
    var message = dwr.util.getValue("message");
    // リモートオブジェクトの実行(第二引数はコールバック関数)
    MessageService.execute(message, loadMessage);
  }
  // コールバック関数の引数でリモートオブジェクトのreturn値を取得
  function loadMessage(messageBean) {
    // HTMLへデータを設定
    dwr.util.setValue("result", messageBean.message);
  }
</script>
</head>
<body>
<h2>DWR2.0 JavaScript→Java呼び出しサンプル</h2>
<p>何か入力してください: <input type="text" id="message" /> 
<input type="button" value="表示" onclick="show()" /><br/>
メッセージ: <span id="result"
  style="background:#CCFF99; padding:4px;"></span>
</p>
</body>
</html>
リスト30●ユーザー・インタフェースとなるHTML

 では,連携を行うためのクラスを作成しましょう。まずorg.directwebremoting.guice.DwrGuiceServletContextListenerを継承したモジュールを作成します。DWRで使用するサービスをこのモジュール内で設定します。bindRemotedAsメソッドの引数に,JavaScriptの名前と使用するサービスのインタフェースを指定します。

 あとは今までと同じようにtoメソッドで実装クラスを指定し,inメソッドでスコープを指定します。このサービスをJavaScriptとして使用するため,DwrScopes#SCRIPTスコープを指定します。

 また,サービスの戻り値として,作成したMessageBeanを使用するため,その定義にFluentConfiguratorを使用しています。ここでしか使わないので内部クラスにしています。

 JavaBeanとして使用するため,org.directwebremoting.convert.BeanConverterを使用してコンバートを行います。


package jp.co.nikkeibp.itpro.guice.dwr;
import org.directwebremoting.convert.BeanConverter;
import org.directwebremoting.extend.Configurator;
import org.directwebremoting.fluent.FluentConfigurator;
import org.directwebremoting.guice.DwrGuiceServletContextListener;
import org.directwebremoting.guice.DwrScopes;
public class Module extends DwrGuiceServletContextListener {
  @Override
  protected void configure() {
  bindRemotedAs(
    "MessageService",
    IMessageService.class)
    .to(MessageService.class)
    .in(DwrScopes.SCRIPT);
    bind(Configurator.class).toInstance(new FluentConfigurator() {
      public void configure() {
        withConverterType("bean", BeanConverter.class.getName());
        withConverter("bean", MessageBean.class.getName());
      } 
    });
  }
}
リスト31●DWRで使用するサービスをモジュールで指定する

 次に,web.xmlに,DWRとGuiceの連携を行うためのサーブレットとモジュールを指定します。サーブレットは,org.directwebremoting.guice.DwrGuiceServletを使用します。

 また,先ほど作成したモジュールをサーブレット・コンテキスト・リスナーとして登録します。


<servlet>
  <servlet-name>dwr-invoker</servlet-name>
  <servlet-class>
    org.directwebremoting.guice.DwrGuiceServlet
  </servlet-class>
  <init-param>
     <param-name>debug</param-name>
    <param-value>true</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>
<listener>
  <listener-class>
    jp.co.nikkeibp.itpro.guice.dwr.Module
  </listener-class>
</listener>
リスト32●DWRで使用するサービスのモジュールでの指定

 このアプリケーションを実行すると図9のようになります。

図9●出張費精算(ToBeのフロー)
図9●出張費精算(ToBeのフロー)

 前述の通り,Guiceでbeanやサービスが管理され,dwr.xmlを記述する必要がなくなることがおわかりいただけかと思います。

まとめ

 以上紹介してきたように,GuiceはまったくXMLファイルを記述することなく,DIを行うことができます。すべてJavaで記述するので,初めてGuiceを使う場合でもストレスなくアプリケーションを作成することが可能です。

 また,公式サイトのGuice Issuesなどでも,新しい機能などに関する話し合いが活発に行われており,Guiceはまだまだ進化しそうです。

 さらに,SpringでもGuice同様,XMLファイルを使用しないでDIを行うことができるフレームワーク「SpringJavaConfig」の作成が行われています。まだ正式リリースにはなっていませんが,今後開発が進んでいくと予想されます。DIを使用する場合に,XMLファイルではなくJavaを使用するという選択肢が今後どんどん増えていくようです。

 “XMLファイルを見るのも嫌だ”と思ったら,一度試しにGuiceで簡単なプログラムを作成してみてください。統合開発環境(IDE)の機能などを使用して,どんどん作っていけるので,ストレスを感じることなくDIを実現できると思います。ぜひ,DIを実現する際に使用するフレームワークとしてお使いいただければと思います。