RPC
参考
RPCの設定と動作の全体像の確認
サンプルプロジェクトの作成
Eclipseのツールバー上の「g」マークボタンから「New Web Application Project」を選択し、プロジェクト名「Hello」、パッケージ「com.example.sample」とする。 「Use Google App Engine」のチェックははずし、「Generate project sample code」をチェックする。
自動生成されるファイルのうち、Hello.javaは余計なコードが多いので、次のように変更してしまう。
package com.example.sample.client; import com.google.gwt.core.client.*; import com.google.gwt.event.dom.client.*; import com.google.gwt.user.client.rpc.*; import com.google.gwt.user.client.ui.*; public class Hello implements EntryPoint { private final GreetingServiceAsync greetingService = GWT .create(GreetingService.class); public void onModuleLoad() { final Button sendButton = new Button("Send"); RootPanel.get("sendButtonContainer").add(sendButton); sendButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent e) { greetingService.greetServer("foobar", new AsyncCallback<String>() { public void onFailure(Throwable caught) { caught.printStackTrace(); } public void onSuccess(String result) { System.out.println("result:" + result); } }); } }); } }
GreetingServiceImpl.javaも簡単のために以下のように変更する。
package com.example.sample.server; import com.example.sample.client.*; import com.google.gwt.user.server.rpc.*; public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService { public String greetServer(String input) throws IllegalArgumentException { return "Hello! " + input; } }
GreetingServiceとGreetingServiceAsync
GreetingServiceがRPCインターフェースであり、サーバとのRPC仕様を決めるものであると言える。 ここで、@RemoteServiceRelativePath("greet")というアノテーションで、このインターフェースを実装するサーブレットのURLの一部を決定している。詳細は後述。
GWTのRPCでは同期呼び出しができず、クライアント側で直接GreetingServiceインターフェースを使うことはできない。必ず、インターフェース名称+Asyncという名前のインターフェースを作成する必要がある。つまり、GreetingServiceAsyncのメソッドは、GreetingServiceのメソッドと名前は同じで、引数も同じだが、その返り値と同じ方の引数を持つAsyncCallbackが最後の引数として追加された形になる。
GreetingServiceAsyncインターフェースは、このように引数の仕様が異なるので、当然GreetingServiceを継承していない。ところが、EclipseのGWTプラグインは、この二つのファイルの定義が一致しているかどうかをチェックしてくれるようで、わざと引数と異なるものにしたりするとエラーが表示される。
GreetingServiceAsyncの呼び出し
Hello.javaの方では、
private final GreetingServiceAsync greetingService = GWT .create(GreetingService.class);
としてGreetingServiceAsyncオブジェクトを取得しているが、これは当然遅延バインディングの機能による。
つまり、GWT.createはGreetingServiceが与えられると、それに対応するGreetingServiceAsyncというインターフェースを継承するクラスを自動生成してそのオブジェクトを返すものと思われる。この自動生成されるクラスが、いわゆるスタブというわけだ。
あとは、ボタンが押されたら、greetServerメソッドを適当な引数(ここでは"foobar")で呼び出し、結果を取得するか、あるいはエラーを表示する。
サーバ側の動作
サーバの作成は先に変更したGreetingServiceImpl.javaのように非常に簡単なものである。 単にRemoteServiceServletを継承して、GreetingServiceを実装すればよい。