SeamFramework.orgCommunity Documentation
こういった動的なAjaxアプリケーションをGoogle Web Toolkit (GWT)を使って開発したいときのために、SeamはGWTウィジェットが直接Seamコンポーネントと連携できる統合レイヤを用意しています。
GWTを使う上でGWT toolsについては既に知っていることを前提にしています。より細かい情報については http://code.google.com/webtoolkit/を参照ください。この章ではGWTがどう機能し、どのように使うかといったところについては説明しません。
SeamアプリケーションでGWTを使う場合に特別な設定は必要ではありません、しかしSeamリソースサーブレットが動作するように設定されていなければなりません。詳細は章 30. Seam の設定と Seam アプリケーションのパッケージングを参照ください。
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);
}
}
The name of the seam component must match the fully qualified name of the GWT client interface (as shown), or the seam resource servlet will not be able to find it when a client makes a GWT call. The methods that are to be made accessible via GWT also need to be annotated with the @WebRemote
annotation.
次のステップは、コンポーネントに非同期インタフェースを返すメソッドを書きます。このメソッドはウィジェットクラスで用意し、非同期クライアントのスタブへの参照を取得するために利用されます。
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
ディレクトリにあります。
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を使うべきではない、とまで言い切ります。それぐらい価値のあるものだからです)