Guiceを使った依存オブジェクト切り離し

では、実際にユーザ処理を依存部分として切り離してみましょう。
以下のようにインタフェースおよびクラスを追加・修正することにします。

インタフェース/クラス 修正内容
test.Repositoryインタフェース 新規作成する。以下のメソッドを定義する。
  • User queryValidUser(String id, String password)
    ... 指定されたID、パスワードを持つユーザを取得する。存在しない場合はnullを返す。
  • User queryUser(String id)
    ... 指定されたIDを持つユーザを取得する。存在しない場合はnullを返す。
  • User[] queryUsers()
    ... すべてのユーザを返す。
test.mock.MockRepositoryクラス 新規作成する。test.Repositoryインタフェースを実装する。
データベースアクセスなどはせず、内部に定数としてID、名前、パスワードの配列を持つ。
test.db.DBRepositoryクラス 新規作成する。test.Repositoryインタフェースを実装する。
EntityManagerを通じてデータベースアクセスをおこなう。
test.(アクション名)Actionクラス 以下のように修正する。
  • コンストラクタ (アクション名)Action(Repository repository)
    ... コンストラクタの引数にRepositoryオブジェクトを追加。このオブジェクトはGuiceから提供される。
  • メンバ Repository _repository
    ... コンストラクタに指定されたRepositoryオブジェクトへの参照を保持する。
  • メソッド String execute()
    ... メンバ _repository を通じてユーザ情報の取得をおこなうように修正。


Guiceを使用可能にする

  1. 以下のファイルをダウンロードし、適当なディレクトリに展開してください。

    ダウンロード guice-1.0.zip


  2. Guiceに関連するJARファイルをWEB-INF/libにコピーします。
    zipファイルから以下のファイルをWEB-INF/libにコピーしてください。

    • guice-1.0.jar
    • guice-struts2-plugin-1.0.jar
    • guice-servlet-1.0.jar


  3. struts2todoプロジェクトを右クリックし「Properties」を選択し、「Java Build Path」に WEB-INF/lib以下のJARファイルを設定してください。

    これで、JavaプログラムからJARファイル内にあるクラスを参照可能になります。

サービスとクライアントの実装

依存部分のインタフェース、および実装クラスを記述します。

ダウンロード Repository.java

12~13行目:
 12: @ImplementedBy(MockRepository.class)
 13: public interface Repository {

サービスのインタフェースの宣言。
アノテーションにより、test.mock.MockRepositoryをサービスの実装として使用することを宣言します。
サービスの実装を変更したい場合はアノテーションの内容を変更します。

ダウンロード MockRepository.java
14行目:
 14: private static User[] USERS = new User[]{ createUser(1), createUser(2), createUser(3) };

ユーザ情報を定数として宣言。
この実装では、ユーザ情報チェック時の処理はこの定数に基づいておこないます。
54~56行目:
 54: public User queryUser(String userID) {
 55:     return findUser(userID);
 56: }

70~78行目:
 70: private User findUser(String id) {
 71:     for(int i = 0; i < USERS.length; i ++) {
 72:         User user = USERS[i];
 73:         if(user.getId().equals(id)) {
 74:             return user;
 75:         }
 76:     }
 77:     return null;
 78: }

ユーザ情報の取得処理の実装。

ダウンロード DBRepository.java
53~62行目:
 53: public User queryUser(String userID) {
 54:     EntityManager entityManager = getEntityManager();
 55:     Query query = entityManager.createQuery("SELECT u FROM User u WHERE u.id='"
 56:             + userID + "'");
 57:     List users = query.getResultList();
 58:     if(users.size() == 0) {
 59:         return null;
 60:     }
 61:     return (User) users.get(0);
 62: }

ユーザ情報の取得処理の実装。
この実装では、JPAによってデータベースの内容を参照しています。


ActionクラスをRepositoryインタフェースを使用するように修正します。
ダウンロード AbstractDBAction.java LoginAction.java AddAction.java DeleteAction.java EditAction.java FinishAction.java ListAction.java SearchAction.java


設定ファイルの記述

WEB-INF/web.xmlを以下のように修正します。
ここでは、GuiceをWEBアプリケーションに組み込むことを指定します。

ダウンロード web.xml

14~21行目:
 14: <filter>
 15:     <filter-name>
 16:         Guice Servlet Filter
 17:     </filter-name>
 18:     <filter-class>
 19:         com.google.inject.servlet.GuiceFilter
 20:     </filter-class>
 21: </filter>

Guice Servlet Filterの宣言。
23~30行目:
 23: <filter-mapping>
 24:     <filter-name>
 25:         Guice Servlet Filter
 26:     </filter-name>
 27:     <url-pattern>
 28:         /*
 29:     </url-pattern>
 30: </filter-mapping>

Guice Servlet Filterの呼び出し条件。
struts2todo以下のすべてのパスに対するリクエストに対して、 Guice Servlet Filterを呼び出します。

ここまでのファイル

ここまででプロジェクトディレクトリの内容は以下のようになります。
正しく作成できているか、確認してください。

ダウンロード struts2todo_1.zip


デバッグ

  1. まず、MockRepositoryサービスで動作確認をおこないます。
    ブラウザで以下のURLを開きます。

    http://localhost:8080/struts2todo/login.action

  2. 次に、RepositoryインタフェースのImplementedByアノテーションの値をDBRepositoryに変更し、動作確認をおこないます。
    ブラウザで以下のURLを開きます。

    http://localhost:8080/struts2todo/login.action