Web サービスとの連携

このあたりがきちんと理解できれば rails との連携についても (以下略
昨晩のエントリは全然理解できてないな、という事がぱっと見分かる。色々と整理しながら要点を纏めておいてから動作確認に移りたいな、と。(駄目??

二回目の記事 (Yahoo!のAPIとGWTを使って画像検索アプリ!) の時点で UI の雛形が作成完了、という状態。まだ client と servlet 間での通信等も手が付いていない。
現時点で理解している基本的な事項を以下に列挙してみる。

  • GWT サーバと Web サービス間の通信は HTTP を使用
  • client と GWT サーバ間の通信は GWT が提供する RPC を使用
  • GWT が提供する RPC では「検索結果セット」と呼ばれる java のオブジェクトが GWT サーバから client に転送される
  • client から GWT サーバへのリクエストの詳細については現時点では不明 (RPC を使用)

で、三回目の記事(JavaScript×HTMLとJavaのシームレスな開発環境を体験してみよう)にて記述されている事項を理解しようとしつつ、メモを。

  • GWT サーバは com.google.gwt.user.server.rpc.Remote.ServiceServlet を継承したサーブレット
  • GWT RPC では C-S 間でシリアライズされた java オブジェクトがやりとりできる
  • クライアント側は javascript なので java オブジェクトのやりとりは不可能だが GWT 提供の機能によりオブジェクトのやりとりについてはブラックボックス化されている
  • GWT サーバから client に渡されるレスポンスオブジェクトは検索結果セットと呼ばれる (この連載のみ??

記事一頁目にて検索結果セットのクラスを作成しているが、このクラス (ImageSearchResultSet) の属性の根拠としては、Yahoo! DEVELOPER NETWORK の画像検索 Web サービスのレスポンスフィールドの項を元に作成されている模様。下の方にサンプルレスポンスの例が掲載されており、そこから分かるのは Result が複数件返却されるのだろうな、という事。
ImageSearchResultSet クラスの属性定義においては、ArrayList クラスの results 属性がその下で static な定義の Result クラスの参照 (参照??) を格納するんだろうな、と類推。なんか微妙な感じがしますが現時点ではスルーしますね。

で、この結果セットを定義した後に順に実装をしていっているんですが、順に列挙しておいて記事を再度ざっくり読んでみます。

  • サービスインターフェースの定義
    • com.google.gwt.user.client.rpc.RemoteService を継承
    • 引数は、検索結果の先頭位置、返却結果件数、探索キーワード
    • 戻り値の型は検索結果セットクラス
  • サーバ側サービスメソッドの実装
  • 非同期インターフェースの定義
  • クライアント側 検索機能の実装
  • widget への値設定 (これは検索結果だろうな)

理解したナニを別途追記します。

サーバ側サービスメソド

仕様は以下。

  • com.google.gwt.user.server.rpc.RemoteServiceServlet を継承
  • 先に定義したサービスインターフェース (ここでは ImageSearchService) を実装
  • 実装した execute メソドの実体を定義する

Yahoo の検索 Web サービスは REST と呼ばれる HTTP リクエストを受けて XML をレスポンスとして返却するサービスとの事。ここで execute の引数 (先頭位置、返却結果件数、検索キーワード) をリクエストパラメータとして編集している。

GWT サーバは Web サービスの仕様にもよるが、この例での REST の場合には

  • HTTP リクエストパラメータを作成
  • HTTP リクエストの送信
  • HTTP レスポンスの受信
  • XML の解析
  • 検索結果セットに解析結果を設定し、返却

という処理が必要になる、と見た (ざっくり見て、の類推です。念の為

ソース落として中を覗いてみるに、server パケジ方面にはサービスメソドな部品のみ、に見えます。基本的に結果セット返却した後は GWT と client で面倒を見る (というか GWT がクライアントに返す手続きの面倒を見てるのか) という事か。

問題は次だな。

非同期インターフェース

解説においてもカタカナが飛び交っております。ポイントを列挙しておくと

  • クライアント側ではサービスインターフェース名 (この例で言えば ImageSearchService) に基づいて、リモートメソド (??) 呼び出しで使用する代理オブジェクトを生成
    • 代理オブジェクトについてはブラックボックスの中のナニだから検証は不要??
    • リモートメソドって何かな。servlet 側の execute メソドがそれと仮定
    • ImageSearchClient.java を見るに
      • 属性として非同期インターフェースの参照を保持
      • onModuleLoad メソド内で GWT.create メソドにより代理オブジェクトを生成して参照を属性に格納している
      • onSearch においてこの代理オブジェクトの execute メソドを呼び出している
  • 生成した代理オブジェクトに対してリモートメソド呼び出しを指示
    • 上記の通り、GWT.create で生成したオブジェクトに対して execute を呼び出しているのがこの記述にあたる模様
  • 代理オブジェクト (この例では ImageSearchServiceAsync クラス) のリモートメソド (execute メソド) はAsyncCallback を実装したクラスのオブジェクトを渡す必要がある。
  • このメソドは void (返却値は返さない) として定義
  • サーバの execute は検索結果セットを返すが、代理オブジェクトのソレは何も返さない。何らかの形で検索結果セットを返却する仕組みが必要 (これ、タマゴが先なのかトリが先なのかは微妙かも)。
  • 代理オブジェクトのリモートメソドで渡すオブジェクトを使って結果セットのやりとりを行なう。

上記では代理オブジェクトと書いてあるが、この例で使用されている ImageSearchServiceAsync オブジェクトが代理、という訳ではないな。解説では_非同期処理用インターフェース (ここの例で言えば ImageSearchServiceAsync インターフェース) と本来のサービスインターフェース (このの例で言えば ImageSearchService インターフェース) は同じパケジ内で同一の名前にする必要がある、との事。(非同期処理用インターフェースには接尾辞として Async が付いている)
RoR じゃねぇが名前で区別してるんだな。XML 使っていないあたりに googlerails な手法を何かの形で評価しているようにも感じるんですがダウトですか??

解説だけでは微妙だったんですが、ソースを眺めつつチェキ入れたらなんとなくイメージできてる気がする。ポイントを以下に列挙してみると

  • client パケジで「サービスインターフェース」と「非同期処理用インターフェース」の二つを定義。検索結果セットも client パケジ内で定義
  • client の UI を定義するクラス (ここの例では ImageSearchClient ) において非同期インターフェースの参照をクラス属性として定義
  • onModuleLoad メソドにて GWT.create メソドを使用して代理オブジェクトを生成
  • 検索ボタンクリック時に、上記で生成したオブジェクトの execute メソドを呼び出す
  • この時、検索に必要な値を引数 (サービスインターフェースの execute メソドに渡す引数) に格納すると同時に、AsyncCallback を実装したクラスに this を渡しつつ new したオブジェクトも渡す。
  • リモートメソドの実行の結果により上記クラスにて定義されている onFailure 又は onSuccess メソドが呼び出される
  • onSuccess メソドにおいては、検索結果セット (ここの例では ImageSearchResultSet) オブジェクトを使用してクライアント画面の設定を行なう

ふむふむ。何とかイメージはできるようになったんだけど、微妙な部分がきちんと読めてないなぁ。例えば Web サービス側から受けとった XML なレスポンスを検索結果セットに設定してるあたり。基本的には java の部品を使っているハズなので、という事から解説が略されているはずなんですが、オイカケるのに若干時間がかかりそう。
あと、複数画面に跨がる処理をどう実装するのか、微妙にイメージできないなぁ。でもカレンダ的に言えばタブで切り替えするだけで複数画面跨がり、にはならんか。

とりあえずイメージは正しいはずなので実装してみてもう少し追い掛けてみる、という事に。

追記

試しに実行してみた。

  • メニューバー Run → Run
  • プロジェクトとパケジを指定し、Run
  • 「エスニック」とキーワードにタイプし、「検索」ボタンをクリック
  • 出てきた。左側のテーブルをクリックしたんですが、Document Not Found と。
  • Compile/Browse ボタンクリックしたら firefox が。
  • 今度は「沖縄」で検索
  • 出てきた。凄いな。

やたらに ! なナニが出力されてますが ...

って、試験しながら思ったんですが、本番環境へのデプロイはどうやって??
基本的には GWT サーバなソース群を tomcat なナニにぶち込んで (以下略) で良いのかなぁ。tomcat な環境構築って微妙だぜ。ってか、client パケジも基本的にはサーバ側に配置するはずだな。デプロイ関係な文書を探さねば。(とほほほ