GWT RPC
GWT RPC とは?
GWT RPC (Google Web Toolkit Remote Procedure Call) はクライアントとサーバーが通信する方法のひとつです。
クライアントのコードから、サーバーのメソッドを呼び出すことによって 動的に Java のオブジェクトを通信することが可能となります。 クライアントから呼び出されるサーバーのメソッドは、サービスと呼ばれます。
GWT RPC の実装方法
GWT RPC は Java Servlet を用いて実装されます。
GWT RPC を構成するコンポーネント
- サーバー上のサービス
- サービスを呼出すクライアントコード
- クライアントとサーバー間でやりとりされる Java データオブジェクト
RPC インターフェイスを定義、実装する方法
- RemoteService から派生したインターフェイスを定義し、 RPC メソッドを全てリストする
- RemoteServiceServlet から派生したクラスを作成し、上記のインターフェイスを実装する
- クライアントサイドのコードから呼ばれるサービスへの非同期インターフェイスを定義する
サービスは、要はサーブレットなのですが、 HttpServlet ではなく RemoveServiceServlet から派生するところに注意してください。
RPC サービス・インターフェイスの定義
RPC サービスは RemoteService を継承した interface として定義します。 名前は XXXService という名前にして、GWT の client パッケージにいれます。
またこのインターフェイスには @RemoteServiceRelativePath 表記を付記し、ベース URL からの相対パスを指定します。
RPC サービスの実装
次に、サーバー側のサービスを実装します。
サービスのクラスは com.google.gwt.user.server.rpc.RemoteServiceServlet を継承し、RPC サービスを定義したインターフェイスを実装します。
クラス名は XXXServiceImpl というように、 サービス名 + Impl というサフィックスを付けます。
またパッケージは、 GWT の server パッケージに入れます。
Eclipse でこれを作るとスタブコードが生成されるので、メソッドを実装します。
Web デプロイメント・アプリケーション・デスクリプタ (web.xml) の設定
サーブレットを認識するよう、war/WEB-INF/web.xml に次のエントリを追加します。
<servlet> <servlet-name>XXXServiceImpl</servlet-name> <servlet-class>com.foo.test.server.XXXServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>XXXServiceImpl</servlet-name> <url-pattern>/mytest/xxx</url-pattern> </servlet-mapping>
以上でサーバー側のサービスは設定できたはずです。続いてクライアントから、サーバー・サービスの非同期呼び出しを行うインターフェイスを定義します。
非同期呼び出しのインターフェイス定義
GWT の client パッケージに次の条件を満たすインターフェイスを作成します。
- インターフェイス名は "サービスインターフェイス" + "Async"
例. XXXServiceAsync - GWT client パッケージ内に作成する
- サービスインターフェイスに存在するのと同じ名前のメソッドを定義する
- メソッドの戻り値は void。パラメータは、最後に元のメソッドの戻り値の型の AsyncCallback オブジェクト
文字で書くとややこしいので、具体例を挙げます。
元のサービスインターフェイスが次のように定義されているとします。
package com.foo.test.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; @RemoteServiceRelativePath("xxx") public interface XXXService extends RemoteService { String[] getData(int i); }
この場合、クライアントからの非同期呼び出し用の Async インターフェイスは次のように定義します。
package com.foo.test.client; import com.google.gwt.user.client.rpc.AsyncCallback; public interface XXXServiceAsync { void getData(int i, AsyncCallback<String[]> callback); }
尚、RemoteServiceRelativePath ではこのサービスの呼出し URL を指定します。ここで、"xxx" を指定すれば、 デフォルトで [Web Application プロジェクト名]/xxx という URL が、このサービスの呼出し URL としてクライアントに利用されます。 従って、web.xml で指定する URL パターンもこれにあわせて設定してください。
例えば、Web Application プロジェクト名が "MyTest1" という名前であり、 RemoteServiceRelativePath に "xyz" を指定すれば、 クライアントが RPC 呼出しに利用する URL は http://hostname/mytest1/xyz になります。従って、 サーブレットの URL パターンも /mytest1/xyz になります。
クライアントコードから非同期呼び出しを行う
次のようにサービスのプロキシを利用することで、クライアントのコードからサーバーのサービスを非同期で呼出すことが可能です。
private XXXServiceAsync svc = GWT.create( XXXService.class ); // コールバックオブジェクトの準備 AsyncCallback<String[]> callback = new AsyncCallback<String[]>() { public void onFailure(Throwable caught) { // エラー } public void onSuccess(String[] result) { // 成功 } }; // サービスへの呼び出しを行う svc.getData( i, callback);
具体的な実装例は以下を参照してください。