SeamFramework.org Community Documentation

- 前のページ
- 次のページ

## 第26章 SeamとGoogle Web Toolkit

こういった動的なAjaxアプリケーションをGoogle Web Toolkit (GWT)を使って開発したいときのために、SeamはGWTウィジェットが直接Seamコンポーネントと連携できる統合レイヤを用意しています。

GWTを使う上でGWT toolsについては既に知っていることを前提にしています。より細かい情報については http://code.google.com/webtoolkit/を参照ください。この章ではGWTがどう機能し、どのように使うかといったところについては説明しません。

## 26.1. 設定

SeamアプリケーションでGWTを使う場合に特別な設定は必要ではありません、しかしSeamリソースサーブレットが動作するように設定されていなければなりません。詳細は章 30. Seam の設定と Seam アプリケーションのパッケージングを参照ください。

## 26.2. コンポーネントの用意する

GWT経由で呼ばれるSeamコンポーネントを用意する最初のステップは、呼び出したいメソッドをもつ同期、非同期サービス両方のインタフェースを作成することです。両インタフェースともGWTの提供する`com.google.gwt.user.client.rpc.RemoteService`を継承します。

    public interface MyService extends RemoteService {

        public String askIt(String question);

     }

非同期インタフェースは一意であるべきですが、`AsyncCallback` パラメタを各メソッドで宣言している場合は除きます。

    public interface MyServiceAsync extends RemoteService {

       public void askIt(String question, AsyncCallback callback);

    }

この`MyServiceAsync`のサンプルのような非同期インタフェースはGWTで実装され、直接的に実装することはありません。

次のステップでは同期インタフェースを実装するSeamコンポーネントを作成します。

    @Name("org.jboss.seam.example.remoting.gwt.client.MyService")

    public class ServiceImpl implements MyService {

       @WebRemote

       public String askIt(String question) {

          if (!validate(question)) {

             throw new IllegalStateException("Hey, this shouldn't happen, I checked on the client, " +

             "but its always good to double check.");

          }

          return "42. Its the real question that you seek now.";

       }

       public boolean validate(String q) {

          ValidationUtility util = new ValidationUtility();

          return util.isValid(q);

       }

    }

この Seam コンポーネントの名前は (上に示した) GWT クライアントインタフェースの完全修飾名と一致 しなければなりません。さもないと、Seam リソースサーブレットは クライアントが GWT の呼び出しをするときにそれを見つけることができなくなってしまいます。メソッドが GWT を介してアクセスできるようにするには、 `@WebRemote` アノテーションを付ける必要があります。

## 26.3. GWTウィジェットを Seam コンポーネントに関連づける

次のステップは、コンポーネントに非同期インタフェースを返すメソッドを書きます。このメソッドはウィジェットクラスで用意し、非同期クライアントのスタブへの参照を取得するために利用されます。

    private MyServiceAsync getService() {

       String endpointURL = GWT.getModuleBaseURL() + "seam/resource/gwt";

       MyServiceAsync svc = (MyServiceAsync) GWT.create(MyService.class);

       ((ServiceDefTarget) svc).setServiceEntryPoint(endpointURL);

       return svc;

    }

最後のステップはクライアントスタブのメソッドを呼び出すウィジェットのコードを書きます。次のサンプルではラベルとテキスト入力フィールドとボタンで構成される画面を作成します。

    public class AskQuestionWidget extends Composite {

       private AbsolutePanel panel = new AbsolutePanel();

       public AskQuestionWidget() {

          Label lbl = new Label("OK, what do you want to know?");

          panel.add(lbl);

          final TextBox box = new TextBox();

          box.setText("What is the meaning of life?");

          panel.add(box);

          Button ok = new Button("Ask");

          ok.addClickListener(new ClickListener() {

             public void onClick(Widget w) {

                ValidationUtility valid = new ValidationUtility();

                if (!valid.isValid(box.getText())) {

                   Window.alert("A question has to end with a '?'");

                } else {

                   askServer(box.getText());

                }

             }

          });

          panel.add(ok);

          initWidget(panel);

       }

       private void askServer(String text) {

          getService().askIt(text, new AsyncCallback() {

             public void onFailure(Throwable t) {

                Window.alert(t.getMessage());

             }

             public void onSuccess(Object data) {

                Window.alert((String) data);

             }

          });

       }

       ...

ボタンをクリックすると`askServer()`メソッドを呼び出し、入力テキストを渡します（この例では、入力値が正しい質問か確認するバリデーションも行なわれます）。`askServer()`メソッドは非同期クライアントスタブ(`getService()`メソッドで返される)への参照を取得し、`askIt()`メソッドを呼び出します。その結果 (もしくは呼び出し失敗時のエラーメッセージ)はアラートメッセージとして表示されます。

このサンプルの完全なコードはSeamのインストールディレクトリ内の `examples/remoting/gwt`ディレクトリにあります。

## 26.4. GWTとAntターゲット

GWTアプリのデプロイにはコンパイル-Javascriptステップ(コードをコンパクトにして難読化します）があります。そしてコマンドラインの代わりに使えるantユーティリティやGWT標準のGUIユーティリティがあります。これらを使うためにはant-taskのjarとダウンロードしてあるGWT(これはホストモードのときに必要）がクラスパスに存在していなければなりません

次にそれらをantファイルの最初の方に置きます。

    <taskdef uri="antlib:de.samaflost.gwttasks"

       resource="de/samaflost/gwttasks/antlib.xml"

       classpath="./lib/gwttasks.jar"/>

       <property file="build.properties"/>

その内容を持つ、`build.properties`ファイルを作成します。

    gwt.home=/gwt_home_dir

もちろん、これはGWTがインストールされた場所を直接指しています。次にターゲットを作成します。

    <!-- GWT�zg�)j��ƣ�ƣgY.

       GWT�F4oS6gYLGWT�%k������Y�ŁLB�~Y -->

       <target name="gwt-compile">

          <!-- Sn4 GWT�� "re homing" WfD~Yng

          GWT����`QcfD~Y - URL�����kY�_�kLjcfD~Y -->

          <delete>

             <fileset dir="view"/>

          </delete>

          <gwt:compile outDir="build/gwt"

             gwtHome="${gwt.home}"

             classBase="${gwt.module.name}"

             sourceclasspath="src"/>

          <copy todir="view">

             <fileset dir="build/gwt/${gwt.module.name}"/>

          </copy>

       </target

    >

呼ばれたときにこのターゲットはGWTアプリケーションをコンパイルし、そのコンパイル結果を指定されたディレクトリ（warの`webapp`にある. GWTはHTMLとJavascriptも生成するので憶えておいてください）にコピーします。`gwt-compile` が生成するコードは一切編集しません、編集する時はGWTソースディレクトリのリソースにて行います。

GWTはホストモードブラウザがあることを覚えておいてください。GWT開発をしているのであれば使っているべきです。もし使ってなく、毎回コンパイルをしているといった場合、ツールを最大限に活用できていません。(本音でいうと、もしホストモードを使えないもしくは使わないのであれば、絶対GWTを使うべきではない、とまで言い切ります。それぐらい価値のあるものだからです）

- 前のページ第25章 リモーティング
- 上に戻る
- ホーム
- 次のページ第27章 Spring Framework 統合