トップ » 技術記事 » チャット作成で学ぶWebリモーティング(3) - DWRのアノテーションを使用する

チャット作成で学ぶWebリモーティング(3) - DWRのアノテーションを使用する

タグ: Ajax DWR Java javascript

どうも皆さん、こんにちは。白石です。

今回はWebリモーティングに関する連載の第三回目です。前回の記事では、今回の連載で使用するチャットアプリケーションを、DWRの基本的な機能を用いて作成しました。今回は、DWR2から利用可能になったアノテーションを利用して、アプリケーションの設定作業を簡略化する方法について説明したいと思います。

アノテーションを用いたサービスの公開

DWRのバージョン2からは、Java5から利用可能になったアノテーションを用いて、リモーティングの各種設定を行えるようになりました。アノテーションを用いると、XMLを用いた設定ファイルを必要とせず、設定情報を全てソースコード内に記述できるため、全体的な可読性が良くなります。

アノテーションを使用して設定を行うために必要な作業は以下の通りです。

  1. org.directwebremoting.annotationsパッケージ内のアノテーションをクラスに付与し、設定を行う。
  2. 1で設定したクラスを、DwrServletの初期化パラメータとして指定する (web.xmlの編集)。

たったこれだけです。
では、具体的にソースコードがどう変わったかを見ていきましょう。

ChatServiceRemote.javaの編集

まずは、Ajaxクライアントから直接呼び出し可能なメソッドを持つ、リモートプロキシのソースがどう変わったかを見ていきます。メソッドの中身は前回と同じですので、全て省略します。

@RemoteProxy(name="ChatService", scope=ScriptScope.APPLICATION)
public class ChatServiceRemote {
  // メッセージのタイムスタンプを表示する際の日付フォーマット
  private DateFormat timestampFormat = new SimpleDateFormat("MM/dd HH:mm:ss");

  // チャットメッセージを保持するリスト
  private List<ChatMessageDTO> messages = new ArrayList<ChatMessageDTO>();

  /**
   * チャットメッセージを追加します。
   * @param messageDto メッセージを格納したDTO
   */
  @RemoteMethod
  public void addMessage(ChatMessageDTO messageDto) {
    … (略) …
  }

  /**
   * 全てのチャットメッセージを取得します。
   * @return 全チャットメッセージ
   */
  @RemoteMethod
  public List<ChatMessageDTO> getAllMessages() {
    … (略) …
  }
}

クラスに@RemoteProxyというアノテーションが付与されています。このアノテーションが付与されたクラスはリモートプロキシとして動作する、という設定です。
name属性は必須で、JavaScript内でこのプロキシを参照するための名前になります。
scope属性は、このプロキシが所属するスコープの指定です。ここでは、プロキシをシングルトンとして扱うために、ScriptScope.APPLICATIONを指定しています (Webアプリケーションコンテキスト内にプロキシのオブジェクトが置かれます)。

addMessage()、getAllMessages()と言った、Ajaxクライアントからも利用可能なメソッドについては、@RemoteMethodというアノテーションを付与しています。

以上でリモートプロキシに対するアノテーションの設定は完了です。が、まだ設定は終わりではありません。前回の記事で説明したとおり、リモートメソッドの引数や戻り値で使用するオブジェクトについては、「コンバータ」(Javaオブジェクト⇔JavaScriptオブジェクトの変換を行うモジュール) の設定が必要です。

ChatMessageDTO.javaの編集

今回のチャットアプリケーションで、リモートメソッドの引数や戻り値で使用されているのはこのChatMessageDTOクラスのオブジェクトです。DWRでは、Ajaxクライアントとリモートプロキシの間でやり取りされるオブジェクトのことを「Data Transfer Object」と呼んでいます。以下のソースを見てください。

package remote;

import java.io.Serializable;

import org.directwebremoting.annotations.DataTransferObject;
import org.directwebremoting.annotations.RemoteProperty;

/**
 * リモーティングでチャットデータの入れ物として用いられるBean
 * @author Shumpei Shiraishi
 */
@DataTransferObject
public class ChatMessageDTO implements Serializable {
  private static final long serialVersionUID = 1L;
  // 発言したユーザ
  @RemoteProperty private String user;
  // 投稿されたメッセージ
  @RemoteProperty private String text;
  // 投稿日時
  @RemoteProperty private String timestamp;

  … (setter/getterは略) …
}

クラスに対し、@DataTransferObjectというアノテーションが付与されているのがお分かりでしょう。
さらに、Ajaxクライアントからアクセス可能なプロパティについては、@RemotePropertyというアノテーションを指定します。@RemotePropertyは、この例のようにフィールドに付与するか、もしくはプロパティのgetterメソッドに付与します。

これで、Javaクラスに対するアノテーションの設定は完了です。では先ほど述べた手順通り、これらをDwrServletの初期化パラメータに指定して設定を完了させましょう。

web.xmlの編集

web.xmlで行うことは、アノテーションを付与したクラスの完全修飾名を、DwrServletの初期化パラメータ「classes」に並べて指定することです。区切り文字にはカンマを使用します。

<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>
  <init-param>
    <param-name>debug</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>classes</param-name>
    <param-value>
      remote.ChatMessageDTO,
      remote.ChatServiceRemote
    </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

ここまで完了したら、アプリケーションサーバを起動して動作を確認してみましょう。前回と変わらず、正常にチャットが動作すればOKです。簡単ですね。

DWR2で利用可能なアノテーション

DWR2で利用可能なアノテーションについての簡単なリファレンスをここに記します。フィルタなど、まだ連載中で説明していない要素についても記載してあります。

@Auth
リモートメソッドに付与し、JavaEEのセキュリティロールによるアクセス制御を実現します。

属性
String role ロールの名称 (必須)
@DataTransferObject
JavaScriptとJavaの間でやり取りされるデータオブジェクトに付与します。

属性
Class< ? extends Converter> converter 使用するコンバータ (デフォルトはBeanConverter)
@Param[] params コンバータに与えるパラメータ
@Filter
リモートプロキシに対して付与し、メソッド呼び出しに対するフィルタを定義します。

属性
Class< ? extends AjaxFilter> type フィルタのクラスを指定します。(必須)
@Param[] params フィルタに与えるパラメータ
@Filters
リモートプロキシに対し、複数のフィルタを指定する場合に使用します。

属性
@Filter[] value フィルタ
@GlobalFilter
あらゆるリモート呼び出しに対するフィルタを定義します。このアノテーションは、AjaxFilterインターフェースを実装したクラスに対してしか付与できません。

属性
@Param[] params フィルタに与えるパラメータ
@Param
各所で使われるパラメータ

属性
String name パラメータの名前
String value パラメータの値
@RemoteMethod
リモートからアクセス可能なメソッドであることを表す。

属性
なし
@RemoteProperty
リモートアクセス可能なプロパティに対して付与する。このアノテーションは、BeanConverterを利用するDataTransferObject内でのみ有効

属性
なし
@RemoteProxy
リモートアクセス可能なクラスであることを表す。

属性
Class< ? extends Creator> creator インスタンスを作成するクリエータを指定する (デフォルトはNewCreator)
@Param[] params クリエータに与えるパラメータ
String name JavaScript上でアクセスするための変数名 (デフォルトは単純クラス名)
ScriptScope scope スコープ (デフォルトはPAGE)

また、@RemoteProxy.scopeで指定するenum ScriptScopeで、列挙されている値についても説明を載せておきます。

列挙値 説明
APPLICATION アプリケーション (ServletContext) スコープ
PAGE REQUESTと同じ (使用が推奨されているのはPAGE)
REQUEST リクエスト (HttpServletRequest) スコープ
SCRIPT Webページ上で宣言したJavaScript変数と同じ生存期間
SESSION セッション (HttpSession) スコープ
最後に

今回は、DWR2で導入されたアノテーションに関する説明でした。アノテーションを使用すると、設定情報がソースコード内に一元化できるので非常に便利です。DWR2を使う上では、積極的に使っていきたいテクニックです。
今回のソースコードはこちら

Series Navigation«DWRの基本DWRのReverse Ajaxで簡単Comet!»

執筆者紹介

shiraishi

shiraishi

最近書いてばっかりいます。 眠いとおんなじことばかり書きます。 そして、大概眠いです。

TrackBack URL :