GWTのRPCに注目する
図3は、AJAX With EaseアプリケーションがGWTのRPCをどのように利用しているかを示しています。
では、それぞれのRPCについて説明しましょう。
- Remote Serviceインターフェイス
- Remote Service実装クラス
- 非同期コールバックインターフェイス
- シリアライズ可能な型オブジェクト
- HelloConstants
- HelloRPC
RemoteServiceを拡張しており、GWTのRPC基盤によって有効にする必要があるインターフェイスを表しています。RemoteServiceServletを拡張しています。さらにRemoteServiceServletはHttpServletを拡張したものです。つまり、HelloServiceImplはクライアントの要求(ブラウザ+HTML/JavaScript)に応答するサーブレットです。またHelloServiceImplはモジュール設定ファイルhello.gwt.xmlでも参照されており、その中でサーブレットパス「/hello」にマッピングされています。HelloServiceAsyncは非同期のコールバックインターフェイスです。このクラスの名前は「Async」で始まるサービスインターフェイスのクラス名でなければなりません。ただし、このインターフェイスを実装する必要はありません。GWT側で実装されるためです。hello()関数によってパラメータとして渡されます。クライアントとサーバーとの間でやりとりされるこの値オブジェクトを使うために、何か特別なことを行う必要はありません。GWTはこのパラメータのシリアライズ化およびデシリアライズ化の処理を行い、基本データ型の値および所与のカスタムJavaオブジェクトの値を返します。これらのカスタムオブジェクトはGWTのIsSerialiazableインターフェイスを実装しているので、これらのオブジェクトを定義するときにはGoogleのGWTドキュメントに記されたいくつかのルールに従います。このPersonオブジェクトが変わっているのは、クライアント側のJavaScriptとサーバー側のJavaバイトコードで使われている点です。HELLO_SERVICE_URLを定義します。アプリケーションのデバッグ時には、GWT対応環境が想定しているようにHELLO_SERVICE_URLを/helloに設定する行を使う(非コメント化する)必要があります。ただし、WebサーバーにデプロイするWARファイルをビルドする準備ができたときは、実行時にHELLO_SERVICE_URLの設定行を、Webサーバーにデプロイしたときのhttp://localhost:8080/ajaxwithease-0.1/helloと等しい値に設定する(非コメント化する)必要があります。... <servlet> <servlet-name>hello</servlet-name> <servlet-class> com.techyatra.awe.server.HelloServiceImpl </servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> ...
HelloServiceを利用するコンポジットウィジェットです。このウィジェットはまずHelloServiceのサービスエンドポイントを取得し、続いてエンドポイントのエントリポイントがHelloServiceImplのサーブレットパスURLに設定されます。AsyncCallbackのインスタンスが作成され、helloService.hello()関数の呼び出し時にパラメータとして渡されます。AsyncCallbackのonSuccessおよびonFailureはAJAX With Easeアプリケーション特有の処理を行うため、次のようにオーバライドされています。package com.techyatra.awe.client; ... public class HelloRPC extends Composite { ... HelloServiceAsync helloService = (HelloServiceAsync) GWT.create(HelloService.class); ServiceDefTarget endpoint = (ServiceDefTarget) helloService; public HelloRPC() { endpoint.setServiceEntryPoint (HelloConstants.HELLO_SERVICE_URL); ... AsyncCallback callback = new AsyncCallback() { public void onSuccess(Object result) { labelRPC.setText((String) result); } public void onFailure(Throwable caught) { errorMessage.setHTML(caught.getMessage()); } }; helloService.hello( new Person(textTitle.getText(), textName.getText()), callback); } ... } }
AsyncCallbackに頼ってクライアントへのコールバックとonSuccess()メソッドの呼び出しを行います。サーバーによって投げられた例外はonFailure()メソッドが受けます。これでアプリケーションには立派なインターフェイスと高速なデータ検索機能が備わりましたが、履歴機能についてはどうでしょうか? GWTを使えば、履歴に対応させることができます。
あるべき履歴機能
AJAXベースのアプリケーションを利用したときに出る大きな不満の1つは、ブラウザの戻るボタンが持っている機能が失われがちなことです。GWTの場合、履歴の機能が失われることはありません。GWTにはアプリケーションがブラウザの「戻る」および「進む」イベントに応答するためのフックが用意されています。
次の「HelloHistory.java」のコードは、GWTのHistoryListenerインターフェイスを実装しているHelloHistoryというコンポジットウィジェットを示しています。
package com.techyatra.awe.client; ... public class HelloHistory extends Composite implements HistoryListener { public HelloHistory() { ... History.newItem(textHistory.getText()); ... History.addHistoryListener(this); } public void onHistoryChanged(String historyToken) { String token = History.getToken(); if (token != null) { textHistory.setText(token); } } }
アプリケーションのユーザーによってブラウザの[戻る]および[進む]ボタンが押された場合は、onHistoryChanged()メソッドの中でそれらの操作に応答できます。履歴の追跡にはトークンを用います。適当なところで履歴にトークンを追加し、これらのトークンを頼ってonHistoryChanged()関数内で適切な処理を実行します。
新たなアプリケーションプラットフォーム?
GoogleがGWTで成し得た成果により、Windowsオペレーティングシステムに頼らずに、ファットクライアントと同等の機能を持つWebアプリケーションを開発することが可能になりました。プラットフォームの新たな領域が開拓されたと言えるのではないでしょうか。

