今回取り上げる関数/クラス
- mx.rpc.http.mxml.HTTPService
- mx.rpc.soap.mxml.WebService
今回も前回に引き続き,ブラウザ内で動作するFlexアプリケーションとサーバー・アプリケーションとを連携させるためのAPIを紹介します。今回取り上げるのは,mx.rpc.http.mxmlパッケージの【HTTPService】クラスと,mx.rpc.soap.mxmlパッケージの【WebService】クラスです。
これらはそれぞれ,ブラウザを介してHTTP/HTTPSのリクエストをFlashPlayerに実行させるクラス,およびブラウザを介してFlashPlayerからWebサービスをコールするためのクラスです。本当はmx.rpcパッケージに含まれる【RemoteObject】クラスも一緒に紹介したかったのですが,分量の関係で次回に回します。
【HTTPService】クラス
mx.rpc.http.mxml.HTTPServiceクラス(*1)はブラウザを介してHTTP/HTTPSのリクエストをFlashPlayerに実行させるクラスです。前回のflash.net.URLLoaderクラス(*2)と同様にレスポンスをイベントでハンドリングすることができますが,イベントの種類などが違います。属性やメソッドには,サーバーサイド製品「Flex Data Services」の後継製品である「LiveCycle Data Services」(以後,LCDS)だけで使用するものがいくつか混在していますが,もちろんLCDSがなくても使用できます。今回はシンプルな使用方法について「MXMLだけ」版と「ActionScript使用」版で説明します。
では,実際にサンプルを見てみましょう(図1)。
図1:【HTTPService】サンプル(クリックすると別ウィンドウで表示します。ソースはこちら)
上から順に
1-1.MXMLだけで実行(お手軽実装)
1-2.受信イベントをActionScript化(デバッグをしやすく)
1-3.URL変数を付加してGETメソッドのリクエストを実行(MXMLだけ)
1-4.URL変数を付加してGETメソッドのリクエストを実行(ActionScript使用)
1-5.POSTメソッドのデータ有りリクエストを実行(MXMLだけ)
1-6.POSTメソッドのデータ有りリクエストを実行(ActionScript使用)
1-7.受信データのフォーマット
となります。
「1-1」と「1-2」はどちらも著者のブログのRSS 2.0フォーマットのXMLを受信する処理です。「1-1」はMXMLだけで実現しています。「1-2」は受信イベント処理をActionScriptで実現しています。
結果は同じなので「1-1」のMXMLだけのほうが簡単です。しかし,思ったとおりに行かなかった時,MXMLだけでは「なぜ,うまくいかないのか?」になかなかたどり着けません。では,「エラーハンドラだけActionScript化すれば問題無いか?」と言うと,そうとも言い切れないのが辛いところです。なぜなら,受信したデータ形式が予想していた形式と違った場合でも,この「dataProvider="{srv01.lastResult.rss.channel.item}"」というコードはエラーを出力しません。List上には何も表示されません。困りものです。
実質的にはMXMLだけで実装できるけれども,システム開発における品質を考えると「MXMLだけで実装してはいけない」と著者は思っています(むろん,すべてがうまくいく前提のシステムであれば問題ありませんが…)。
一度,「srv02_onResult」関数をデバッグ実行し,「e.result」にどのようなデータが格納されているのか確認してみてください。Flexでのデータ通信を学習するうえでの"勘所"がつかみやすくなるかもしれません。
「1-3」と「1-4」はURLにパラメータを付加してGETメソッドでリクエストを実行しています。違いは,MXMLでパラメータをコーディングするか(図2),ActionScriptでパラメータをコーディングするかです(図3)。
図2:MXMLでパラメータをコーディング
図3:ActionScriptでパラメータコーディング
MXMLではHTTPServiceタグの子タグとして「mx:request」を追加し,パラメータをXML形式で定義していきます。コードを見比べるとパラメータの"数"が固定の場合はMXMLでも良い気がします。
ここでちょっと紹介しておきたいのが「AsyncToken」クラス(図3)です。これを使用することで,受信イベントでどの送信コードだったかを判断できます。良し悪しもありますが,受信イベントハンドラを複数のHTTPServiceで使用するとします。その場合,受信イベントがどのHTTPService,どのタイミングの送信だったのかをこの「AsyncToken」クラスを使って知ることが可能です。
図3ではHTTPServiceのリクエストを実行する「send」メソッドの戻り値をAsyncTokenタイプのローカル変数に格納しています。「send」メソッドの次の行でAsyncTokenにデータをセットするというのはちょっと奇妙かもしれませんが,慣れてください。「at.sampleId = 4;」と送信実行関数でコーディングし,受信イベントで「ResultEvent.token.sampleId」として取り出しています(図4)。
図4:AsyncTokenの取り出し(クリックすると拡大表示します)
これで受信イベント時にどの送信だったのかを知ることができます。このようにFlashPlayer&ActionScriptはイベントドリブンであり,非同期通信であるということを理解することは,最適な設計をするうえで大変重要なことだと著者は考えます。
こう考えてみてください。
FlashPlayerはシングルスレッドであるが故にイベント,描画の二つの処理をキューイング(待ち行列)化しているが,ActionScriptのコードは関数が終了するまでスレッドを占有してしまいます。そこで,FlashPlayerはイベントキュー処理,描画キュー処理,ASコードをくるくる回ることで処理待ち(=画面が固まる)を回避しているとします。そして,送信コードは送信を直ちに実行するのではなく「後で送信してね」という「送信依頼イベント」をキューするとします。
送信コードが含まれる関数が終了した後,(FlashPlayer内部の)イベント処理が実行され「送信依頼」を処理します。但し,ここで受信を待ってしまうとFlashPlayerが固まってしまうので,受信待ちキューにキーデータを格納し次の他の処理にすぐに移ります。そして,FlashPlayerがデータを受信するとすぐに受信イベントが発生するのではなく,イベントキュー処理で受信倉庫に格納されているデータを取り出し,受信待ちキューのキーデータと照合し,受信待ちデータを取り出し対応する受信イベントハンドラ(ASコード)を実行します。
以上を,参考程度に頭の片隅に置いていただけると幸いです。
「1-5」と「1-6」は,まさに「1-3」と「1-4」の「method」パラメータをPOSTにしただけです。これでPOST処理を実行してくれます。
1-7.はHTTPServiceの良いところです。受信したテキスト・データを「resultFormat」属性に設定した値へ自動変換してくれるのです。このサンプルではサーバーからXML形式のテキスト・データを返しています。
この場合,
- 「object」は型無しオブジェクト(構造体)をラッピングしたObjectProxyクラス(*4)になります。
- 「e4x」(*5)は受信したXMLテキストをドットシンタックスでオブジェクト的に扱うことのできるXMLクラス(*6)になります。
- 「xml」は受信したXMLテキストそのままで,XMLNodeクラス(*7)になります。
- 「text」も受信したXMLテキストそのままですが,こちらは純然たるStringクラスになります。
- 「array」は受信データをArrayと解釈しArrayCollectionクラス(*8)に格納します。
最後の「flashvars」だけちょっと特殊です。これはオーサリングソフトのFlashで使用されているようなデータ形式でURLに付加する変数のように「変数名=値」のように「=」(イコール)で変数名と値を区切り,「変数名1=値1&変数名2=値2」のように変数と変数は「&」(アンパーサンド)で区切られたテキスト・データをObjectクラスに変換してくれます。サンプルではこの「flashvars」の時だけサーバーから返すデータを別にしています。
逆に言えば,その他はすべて同じデータを受信し,対応するデータ形式に変換しています。ソースの「private function srv07_onResult」行にブレークポイントを設定し,デバッグ実行を行うと上記の内容を確認することができます。
最後に受信イベント/エラーイベントについてですが,HTTPService,WebService,RemoteObjectすべてにおいて共通です。ActionScriptでコーディングしてある正常受信イベントはmx.rpc.events.ResultEvent クラス(*9)で,エラーイベントは mx.rpc.events.FaultEvent クラス(*10)になります。
【WebService】クラス
mx.rpc.soap.mxml.WebService クラス(*11)はブラウザを介してFlashPlayerからWebサービスをコールするためのクラスです。ただし,HTTPServiceで説明した内容とほとんど変わりません。こういうところはライブラリ化されたFlexの良いところだと思います。説明もWebサービス特有の内容にフォーカスして説明したいと思います。では,実際にサンプルを見てみましょう(図5)。