EclipseとMavenでGWTアプリケーションを作成する:05 サーバーと通信する
環境など
私は日本語化されたEclipseを使用しているので、英語版とはメニューや項目名が異なります。お使いの環境と異なる場合には、適宜読み替えてください。
この説明で使用しているソフトウェアのバージョンは次の通りです。
■ サーバーとの通信と2つのインターフェイス ↑
Webアプリケーションではブラウザ側で処理が完結するといったことはあまりなく、多くの場合にはサーバーと接続し、何らかの情報のやり取りをします。
GWTではサーバーと通信する方法が複数用意されています。ここではリモート・プロシジャ・コール(RPC)を使ってサーバーと通信するサンプルを作成します。
前回までに作成したアプリケーションで挨拶メッセージを作成する部分をサーバー側のサービスとして独立させ、それをクライアント側から呼び出すことにします。
サービスを作成するためには2つのインターフェースが必要です。ひとつはサービス用インターフェース、もうひとつは呼び出し用インターフェースです。
サービス用インターフェースは次のような特徴を持っています。
- サーバー上のサービスが実装するインターフェースです。
- GWTのRemoteServiceインターフェースをextendsします。
呼び出し用インターフェースは次のような特徴を持っています。
- クライアント側のコードがサーバー上のサービスを呼び出すときに使うインターフェースです。
- サービス用インターフェースと同じ名前のメソッドを持ちますが、最後の引数としてAsyncCallback
型を持ちます。ここでTは元のメソッドの戻り値の型です。メソッド自体の戻り値はvoidになります。 - 慣例として、サービス用インターフェースの後ろに「Async」を付けた名前にします。
■ 呼び出し用インターフェースが自動生成されないようにする ↑
gwt-mavenプラグインで作成されたpom.xmlには、呼び出し用インターフェースを自動生成するための記述があります。ここではインターフェースは自分で作成しますので、以下の手順で自動生成されないようにします。
1. プロジェクト・エクスプローラーからpom.xmlをダブルクリックし、エディタで開きます。「pom.xml」タブに切り替えます。
2. gwt-maven-pluginの設定の
変更前
<goals> <goal>compile</goal> <goal>generateAsync</goal> <goal>test</goal> </goals>
変更後
<goals> <goal>compile</goal> <goal>test</goal> </goals>
■ サービス用インターフェースを作成する ↑
次のようなインターフェースを作成します。
- 名前はGreetingMessageService
- clientパッケージに含める
- RemoteServiceインターフェースをextendsする
GreetingMessageSerivce:
package jp.ne.hatena.paz3.GwtSample.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; @RemoteServiceRelativePath("GreetingMessageService") public interface GreetingMessageService extends RemoteService { public String getGreetingMessage(String name); }
getGreetingMessageは、引数として指定された名前を受け取り、挨拶メッセージを返すメソッドです。
@RemoteServiceRelativePathでサービスを呼び出すときのURL相対パスを指定します。
■ 呼び出し用インターフェースを作成する ↑
次のようなインターフェースを作成します。
- 名前はGreetingMessageServiceAsync
- clientパッケージに含める
GreetingMessageSerivceAsync:
package jp.ne.hatena.paz3.GwtSample.client; import com.google.gwt.user.client.rpc.AsyncCallback; public interface GreetingMessageServiceAsync { void getGreetingMessage(String name, AsyncCallback<String> callback); }
■ サービスの実装を作成する ↑
サービスを実装します。サービスを実装するクラスは次のようにします。
- RemoteServiceServletをextendsする
- サービス用インターフェースを実装する
- serverパッケージに含める
そこで、次のようなクラスを作成します。
- 名前はGreetingMessageServiceImpl
- RemoteServiceServletをextendsする
- GreetingMessageServiceインターフェースをimplementsする
- serverパッケージに含める
GreetingMessageSerivceImpl:
package jp.ne.hatena.paz3.GwtSample.server; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import jp.ne.hatena.paz3.GwtSample.client.GreetingMessageService; public class GreetingMessageServiceImpl extends RemoteServiceServlet implements GreetingMessageService { public String getGreetingMessage(String name) { String message = "Hello " + name + " !"; return message; } }
■ サービスを登録する ↑
作成したサービスをweb.xmlに登録します。
src/main/webapp/WEB-INF/web.xmlの
web.xml(抜粋):
<servlet> <servlet-name>GreetingMessageService</servlet-name> <servlet-class>jp.ne.hatena.paz3.GwtSample.server.GreetingMessageServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>GreetingMessageService</servlet-name> <url-pattern>/jp.ne.hatena.paz3.GwtSample.Application/GreetingMessageService</url-pattern> </servlet-mapping>
■ 呼び出し側コードを作成する ↑
前回までで作成したApplication.javaを、サービスを呼び出すように変更します。
importに次の行を追加します。
import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.AsyncCallback;
showGreetingMessageメソッドを変更します。
変更前:
private void showGreetingMessage() { String name = nameTextBox.getText(); String message = "Hello " + name + " !"; messageLabel.setText(message); }
変更後:
private void showGreetingMessage() { String name = nameTextBox.getText(); GreetingMessageServiceAsync greetingMessageService = GWT.create(GreetingMessageService.class); greetingMessageService.getGreetingMessage(name, new AsyncCallback<String>() { public void onSuccess(String result) { messageLabel.setText(result); } public void onFailure(Throwable caught) { String message = "Error: " + caught.toString(); messageLabel.setText(message); } }); }
■ ホストモードで実行できるようにする ↑
ここまでの設定をして、warファイルを作成しアプリケーションサーバーに配置すれば、リモートサービスを呼び出すアプリケーションは動作します。しかし、Mavenのgwt:runターゲットで動作するホストモードでは実行できません。
ホストモードで実行させるには、以下の2つの設定をします。
■ サービスを.gwt.xmlに登録する ↑
Application.gwt.xmlの
<servlet path="/GreetingMessageService" class="jp.ne.hatena.paz3.GwtSample.server.GreetingMessageServiceImpl" />
■ war/WEB-INF/web.xmlを作成する ↑
war/WEB-INF/web.xmlを作成します。上記で修正したweb.xmlをwar/WEB-INFの下にコピーしても良いでしょう。
src/java/main/WEB-INF/web.xmlを読み込んでくれれば便利だと思うのですが、そうなっておらず、別々のファイルを読み込むようになっています。ファイルを分けている理由について http://mojo.codehaus.org/gwt-maven-plugin/user-guide/hosted.html には「ホストモードはテスト用であり、配備用の設定とは別にすべきである」と書かれています。