トップ » 技術記事 » チャット作成で学ぶWebリモーティング(5) - DWRとSpringの連携

チャット作成で学ぶWebリモーティング(5) - DWRとSpringの連携

タグ: Ajax DWR Java javascript Spring

リモートサービスのソースコード

では、リモートサービスのソースコード (ChatServiceRemote.java) がどうなったかを見ていきたいと思います。クライアントとやり取りするデータ (DTO) に関しては、以前から変更がないので省略します。

ソースコードを読む前に、このクラスが何をすべきかをもう一度確認しておきましょう。
- Ajaxクライアントとのやり取り。
このクラスの存在意義はまさに「Ajaxクライアントとビジネスサービスの仲介役」なので、当然クライアントとのやり取りを行います。これには、前回説明したReverseAjaxなども含みます。
- ビジネスサービスの呼び出し。
当然ながら、上で作成したビジネスサービス (ChatService) を使用します。ChatServiceのインスタンスは、SpringのDIによって取得します。
- データオブジェクトの変換 (DTO ⇔ 業務データ)。
HTMLエスケープ (”<”を”<”に変えるなど) もこのクラスが行うべきです。

ではこれを踏まえて、ソースコードを読んでみてください。画面に表示する日付の形式も、DIによって取得していることに注目。こうしておけば、形式の変更は設定ファイルを修正するだけで行うことができます。

package remote;

import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;

import service.ChatMessage;
import service.ChatService;

/**
 * チャット用のリモーティングAPIを提供するクラス
 * @author Shumpei Shiraishi
 */
public class ChatServiceRemote {

  private ChatService chatService;

  // メッセージのタイムスタンプを表示する際の日付フォーマット
  private DateFormat timestampFormat;

  public void setChatService(ChatService chatService) {
    this.chatService = chatService;
  }
  public void setChatTimestampFormat(DateFormat df) {
    this.timestampFormat = df;
  }

  /**
   * チャットメッセージを追加します。
   * @param messageDto メッセージを格納したDTO
   */
  @SuppressWarnings("unchecked")
  public void addMessage(ChatMessageDTO messageDto) {
    ChatMessage msg = new ChatMessage();
    msg.setText(messageDto.getText());
    msg.setUser(messageDto.getUser());
    msg.setTimestamp(new Date());
    chatService.addMessage(msg);

    // Reverse Ajaxを用いてメッセージを配信

    List<ChatMessageDTO> messages = getAllMessages();

    WebContext wc = WebContextFactory.get();
    String currentPage = wc.getCurrentPage();

    Collection<ScriptSession> sessions =
      (Collection<ScriptSession>) wc.getScriptSessionsByPage(currentPage);
    for (ScriptSession sess : sessions) {
      sess.addScript(
        new ScriptBuffer("_showMessages(")
          .appendData(messages)
          .appendScript(");"));
    }
  }

  /**
   * 全てのチャットメッセージを取得します。
   * @return 全チャットメッセージ
   */
  public List<ChatMessageDTO> getAllMessages() {
    // HTMLエスケープしながらコピーし、返す
    List<ChatMessage> messages = chatService.getAllMessages();
    List<ChatMessageDTO> result = new ArrayList<ChatMessageDTO>();
    for (ChatMessage origMsg : messages) {
      ChatMessageDTO message = new ChatMessageDTO();
      message.setUser(escapeHtml(origMsg.getUser()));
      message.setText(escapeHtml(origMsg.getText()));
      message.setTimestamp(
        escapeHtml(timestampFormat.format(origMsg.getTimestamp())));
      result.add(message);
    }
    return result;
  }
}

動作させるための設定

ソースコードの内容は大体把握できましたか?ではあとは、SpringとDWRのそれぞれについて必要な設定を行っていきます。

Spring設定ファイル (WEB-INF/applicationContext.xml)

まずは、Springで行う設定です。リモートサービスとビジネスサービスのどちらもSpringに管理してもらい、リモートサービスに対するDIも設定します。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

  <!– チャットのリモートサービス –>
  <bean id="chatServiceRemote" class="remote.ChatServiceRemote">
    <property name="chatService" ref="chatService"/>
    <property name="chatTimestampFormat">
      <bean class="java.text.SimpleDateFormat">
        <constructor-arg value="MM/dd HH:mm:ss"/>
      </bean>
    </property>
  </bean>

  <!– チャットのビジネスサービス –>
  <bean id="chatService" class="service.impl.ChatServiceImpl">
  </bean>
</beans>
DWRの設定ファイル (WEB-INF/dwr.xml)

dwr.xmlは以下のようになっています。Creatorを”spring”にし、Springで定義したBeanのIDをパラメータに指定していることを確認してください。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">

<dwr>
  <allow>
    <!– チャットのリモーティングサービス。
      Springのコンテナからインスタンスを取得
     –>
    <create creator="spring" javascript="ChatService" scope="application">
      <!– Springで定義したBeanの名称 –>
      <param name="beanName" value="chatServiceRemote"/>
    </create>

    <!– DTOのコンバータ定義 –>
    <convert converter="bean" match="remote.ChatMessageDTO"/>
  </allow>
</dwr>
web.xmlの設定

あとは、サーブレットコンテナ上でSpringを使用するため、web.xmlに必要な設定を記述します。詳しいことはSpringのドキュメントや書籍を参照してもらうとして、今回追加した設定は以下のようなものです。

...(略)...
<context-param>
  <!– Log4Jの設定ファイルがある場所を指定 –>
  <param-name>log4jConfigLocation</param-name>
  <param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<context-param>
  <!– コンテキスト設定ファイルの場所を指定 –>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    /WEB-INF/applicationContext.xml
  </param-value>
</context-param>
<listener>
  <!– このリスナが、Springのコンテナを起動する –>
  <listener-class>
    org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>
…(略)…

動作確認とまとめ

以上の変更を行ったら、アプリケーションサーバに配置して、ブラウザからアクセスしてみてください。動作は今までと変わらないはずです。しかし、DIやAOP、そしてSpringが持つ様々なフレームワークとのアダプタ機能が将来的に利用できるようになったと言う点で、アプリは非常に大きな進化を遂げています。

今回のソースコードはこちらからダウンロードしてください。

今回は、Springとの連携について基本的な方法をお伝えしました。次回は、Springのバージョン2から利用できるようになった「コンテキスト設定ファイルにおける名前空間の拡張」機能を用いて、全ての設定をコンテキスト設定ファイル内で完結させる方法を学んでいきたいと思います。

ご意見、ご感想お待ちしています。

Series Navigation«DWRのReverse Ajaxで簡単Comet!Spring2の名前空間拡張機能を用いたDWRの設定»

1 2

執筆者紹介

shiraishi

shiraishi

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

TrackBack URL :