サーバーとの通信
第2回 HTTPService を利用する(1)

HTTPService - データをサーバーから受け取る

HTTPService タグを使ってサーバーと通信をするための考え方、および方法を説明します。今回は、サーバーから情報を取得するまでを見ていきます。

 


目次

HTTPService を利用する

  • send ファンクション
  • result イベント
  • result プロパティー
  • showBusyCursorプロパティー

リクエストのタイミング

プロキシについて

  • useProxy プロパティー、flex-config.xml のホワイトリスト
  • 名前付けされた接続と servieName プロパティー

結果の受け取り方

  • resultFormat プロパティー
  • response イベント

サーバーにデータを送る (第3回)

  • method プロパティー
  • request プロパティー
  • contentType プロパティー

エラーハンドリング (作成中)

  • fault イベント、fault プロパティー

ユーザー認証、SSL通信 (作成中)

様々な問題と解決策 (作成中)

  • 同時リクエストの問題 concurrency プロパティー
  • < > & 記号の送信の問題
  • 日本語文字化けの問題
  • 予期しないデータ型変換の問題
  • キャッシュのなぞ

HTTPService を利用する

HTTPService タグを使えば、Webブラウザーで特定のURL にアクセスし、情報を入手することができます。

例えば次の HTML ページがあるとします。

 page1.htm

<html>
<body>
<font color="#FF0000" size="+1" >Hello Flex!</font><br>
<font color="#00FF00" size="+3" >Hello Flex!</font><br>
<font color="#0000FF" size="+8" >Hello Flex!</font><br>
</body>
</html>

このページにアクセスする Flex アプリケーションは例えば次のようになります。

 http_basic1.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml"> <mx:HTTPService id="srv" url="page1.htm" resultFormat="text" useProxy="false" />
<mx:Button label="サーバーへアクセス" click="srv.send()" />
<mx:TextArea htmlText="{srv.result}" width="100%" height="100%" /> </mx:Application>

このアプリケーションの実行結果は次の通りです。[サーバーへアクセス]ボタンを押すことでサーバーにアクセスし、page1.htm ページを取得、テキストエリアに表示します。

<mx:HTTPService> タグがサーバーにアクセスをするためのMXMLタグです。 id="srv" はこのタグに対する識別名を定義しています。ここで記述された HTTPService タグは "srv" という名前で別の場所からアクセスできます。url プロパティーはアクセス先を指定します。 resultFormat="text" は所得した結果データの扱い方を設定しています。resultFormat について詳しくは 「結果の受け取り方」で説明します。 useProxy プロパティーは Flex プロキシ機能を使うかどうかを設定しています。 プロキシ機能については「プロキシについて」で説明します。 <mx:Button> タグはボタンを表示しています。 click イベントハンドラーでは srv.send() と定義されています。これは "srv" の send ファンクションを呼び出すことを意味しており、これによりサーバーへのアクセスが開始されます。 <mx:TextArea> タグは テキストエリアを表示します。 htmlText プロパティーで表示する文字列を設定しています。ここでは { } による データバインディングが行われていて、 HTTPService タグ (srv) の result プロパティーの値を表示するように実装されています。 HTTPService タグの result プロパティーはサーバーから取得した結果データを保存しています。

<mx:HTTPService> タグはクライアントにアプリケーションがロードされたあとにサーバーにアクセスをするということを確実に理解してください。 mxml はサーバーでコンパイルされ、swf ファイルとしてクライアントに送られます。HTTPSerivceによるサーバーへのアクセスはクライアントで swf の実行が開始された後に行われます。 この動きを図式化すると次のようになるでしょうか。

これまでに出てきた HTTPService タグのプロパティー/ファンクションをまとめます。

  • id プロパティー: 識別名(ほかの場所から参照するための名前、任意に設定します)
  • url プロパティー: アクセス先の URL 。絶対パスでは http://... または https://... から指定します。
  • result プロパティー: サーバーから取得したデータを保存しています。
  • resultFormat プロパティー: 結果データの扱い方。詳しくは 「結果の受け取り方」で説明
  • useProxy プロパティー: Flex プロキシを利用するかどうかを設定。詳しくは「プロキシについて」で説明

これまでの知識をもとにいろいろやってみようと思うといくつかの問題に行き当たるでしょう。

  • HTML ページを変更しても Flex アプリケーションは変更された内容で読み直してくれないかもしれません。この点については、「様々な問題と解決策 - キャッシュのなぞ」で説明します。
  • 日本語文字は化けるかもしれません。この点については「様々な問題と解決策 - 日本語について」で説明します。
  • すべての HTML タグがテキストタグの中で正確に反映されるわけではありません。

リクエストのタイミング

先ほどの例では[サーバーへアクセス]ボタンを押すことでサーバーにアクセスしました。 アプリケーションによっては、起動直後に自動的にサーバーにアクセスして欲しい場合があります。

Flexコンポーネントには初期化に関連するイベントがいくつかあります。 例えば creationComplete イベントがあります。 このイベントはそのコンポーネントの初期化が終了した時点で発生します。 Application タグの creationComplete イベントは内包するコンポーネントの初期化が終了してから発生します。 例えば先ほどの例を次のように書き換えるとアプリケーションの起動直後にサーバーにアクセスし、データを取得します。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" creationComplete="srv.send()"> <mx:HTTPService id="srv" url="page1.htm" resultFormat="text" useProxy="false" />
<mx:TextArea htmlText="{srv.result}" width="100%" height="100%" /> </mx:Application>

プロキシについて

useProxy プロパティー、flex-config.xml のホワイトリスト(<whitelist>)

Flexのプロキシ機能は Flex アプリケーションからのリクエストを受け取り、Flex プレゼンテーションサーバーがクライアントに代わってリクエスト先へのアクセスを行い、レスポンスをクライアントに返すというものです。

プロキシ機能を使うには先ほどの http_basic1.mxml の <mx:HTTPService>タグを次のように書き換えます。

<mx:HTTPService id="srv" url="page1.htm" resultFormat="text" useProxy="true" /> 

なお、 useProxy プロパティーはデフォルトで true です。ですから useProxy 明示的に指定しなかった場合も useProxy="true" として解釈されます。

useProxy="true" のときの通信は図式化すると次のようになるでしょう。

useProxy="true" とすることでサーバーにアクセスすると次のようなエラーが出てくるようになるかもしれません。

Flexのプロキシ機能はにはセキュリティ制限機能があります。Flex プロキシはあらかじめ設定ファイルで通信を許可すると設定された URL でのリクエストだけを受け付けます。この制限機能は運用環境を考えたとき重要です。例えば、ここで正しくリクエストを制限していないと、Flex アプリケーションがファイアーウォールの背後にあるリソースに予期せずアクセスできてしまうかも知れません。 そのリソースに直接アクセスを行うのはクライアント Flexアプリケーションではなく、Flex プレゼンテーションサーバーになるからです。 プロキシがどのURLパターンを許可するかは flex-config.xml ファイルの <whitelist> という要素で設定します。 flex-config..xml ファイルは WEB-INF/flex ディレクトリの下にあります。 <whitelist> 要素は <web-service-proxy>、<http-service-proxy>、<remote-objects> の各要素の中にあります。このうち <mx:HTTPService> タグに関連する <whiltelist> の設定は <http-service-proxy> 要素の中にあるものです。 例えば url プロパティーに設定されたすべての URL を許可する場合、<whilelist> 要素の <unnamed> 要素の中に次のように設定します。(赤字が設定追加部分)

<?xml version="1.0" encoding="UTF-8"?>
<flex-config xmlns="http://www.macromedia.com/2003/flex-config">

                :                                     :

    <web-service-proxy>

                :                                     :

    </web-service-proxy>

                :                                     :

    <http-service-proxy>

                :                                     :

        <whitelist>
            <!-- whitelist config for unnamed services -->
            <unnamed>
                <url>http://*</url>
                <url>https://*</url>
                <!--
                For security, the whitelist is locked down by default.
                Uncomment the first two urls below to enable access to all URLs,
                or the last two urls to enable access to the local server,
                or add above the individual URLs you wish to access.
                <url>http://*</url>
                <url>https://*</url>
                <url>http://{localserver}/*</url>
                <url>https://{localserver}/*</url>
                -->
            </unnamed>
            <!-- whitelist config for named http services -->
            <named>

                :                                     :

            </named>
        </whitelist>
    </http-service-proxy>

    <remote-objects>

                :                                     :

    </remote-objects>

                :                                     :

</flex-config>

ここに示したように unnamed 要素の中に <url> URLパターン </url> を追加すれば、そのURL パターンが許可されることになります。 '*' マークはワイルドカード、'*' マークの部分にはどのような文字が来てもいいということです。 次のように記述したとき、Flex プレゼンテーションサーバーが動作しているサーバーの中だけアクセスが許可されます。{localserver} は Flex プレゼンテーションサーバーをあらわす特別なキーワードです。

<url>http://{localserver}/</url>

次のように記述したとき SSL 通信のみが許可されます

<url>https://{localserver}/</url>

次のように記述したとき、www.geocities.jp/takuji_kawata 配下のリソースにのみ通信が許可されます。

<url>https://www.geocities.jp/takuji_kawata/*</url>

次の例ですと、http で flexプレゼンテーションサーバーの /flex 配下と www.geocities.jp/takuji_kawata にアクセスを許可しています。

<?xml version="1.0" encoding="UTF-8"?>
<flex-config xmlns="http://www.macromedia.com/2003/flex-config">

                :                                     :

    <http-service-proxy>

                :                                     :

        <whitelist>
            <!-- whitelist config for unnamed services -->
            <unnamed>
                <url>http://{localserver}/flex</url>
                <url>http://www.geocities.jp/takuji_kawata</url>
            </unnamed>
            <!-- whitelist config for named http services -->
            <named>
            </named>
        </whitelist>
    </http-service-proxy>

                :                                     :

</flex-config>

(メモ:JRun 統合インストールで Flex をインストールした場合、flex-config.xml ファイルの更新は自動監視されています。 flex-config.xml ファイルを変更保存すると、サーバーは自動的にリロードされます。変更を反映するためにサーバーを再起動する必要はありません。)

名前付けされた接続と servieName プロパティー

<whitelist> の中に設定できる内容はこれだけではありません。<http-service-proxy> の<whitelist> では、さらに

  • 論理名を定義し、論理名 対 実際の URL の管理を設定ファイルの中で行うことができます。
  • 論理名に対しリソースにアクセスをするためのユーザー認証などの条件を設定することができます。

これらは <whitelist> 要素の <named> 要素の中に定義します。<named> 要素の中に定義されたURLは「名前付けされた接続」と呼ばれます。これらを利用するためには <mx:HTTPSerivce> では url プロパティーの代わりに serviceName プロパティーを利用します。例えば 次の定義では /flex/page1.htm へのアクセスを mypage1 という論理名で定義しています。

<?xml version="1.0" encoding="UTF-8"?>
<flex-config xmlns="http://www.macromedia.com/2003/flex-config">

                :                                     :
<http-service-proxy>

                :                                     :

        <whitelist>
            <!-- whitelist config for unnamed services -->
            <unnamed>  
            </unnamed>
            <!-- whitelist config for named http services -->
            <named>
              <service name="mypage1">
<url>http://127.0.0.1:8700/flex/page1.htm</url>
</service>
</named> </whitelist> </http-service-proxy> : : </flex-config>

論理名 mypage1 で page1.htm にアクセスをするためには次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" creationComplete="srv.send()"> <mx:HTTPService id="srv" serviceName="mypage1" resultFormat="text" />
<mx:TextArea htmlText="{srv.result}" width="100%" height="100%" /> </mx:Application>

「名前付けされた接続」ではさらに認証ルールなど、より細かい設定ができます。この点について詳しくは後ほど扱う予定です。まずは、次の URL が参考になるかと思います。http://livedocs.macromedia.com/flex/15/flex_docs_en/00000760.htm

結果の受け取り方

HTTPService のリクエストの結果は result というプロパティーに格納されると同時に result というイベントが発生します。どちらも result なので紛らわしいのですが、 HTTPSerivce において、 result とはリクエスト結果を格納する プロパティーであるという側面と 結果の取得に成功したときに発生する result イベントという2つの側面を持っています。

例えばこれまでに出てきたサンプルプログラムで結果の表示の部分をイベントハンドラーで行うように書き換えると次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" creationComplete="srv.send()">
<mx:Script>
<![CDATA[
function showTheResult(event) {
res.htmlText = srv.result;
}
]]>
</mx:Script>
<mx:HTTPService id="srv" url="page1.htm" resultFormat="text" result="showTheResult(event)" />
<mx:TextArea id="res" width="100%" height="100%" />
</mx:Application>

次に結果がどのような形式で Flex アプリケーションの中に取り込まれるかです。これは resultFormat プロパティーでいくつかのパターンを指定することができます。 これまで出てきたサンプルプログラムではすべて、resultFormat は "text" を 指定してきました。 "text" は「サーバーからの結果をそのまま文字列データとして取り込む」という形式です。 ですから結果の入る result プロパティーのデータ型は文字列型(String) となります。

resultFormat を明示的に指定しなかった場合、resultFormat は "object" であると解釈されます。 resultFormat "object" では、サーバーは XML データをレスポンスすることを前提とし、その XML データの構造を ActionScript オブジェクトのプロパティーの構造に変換します。

次に新しい例を示します。

 サーバーのデータ data1.xml

<?xml version="1.0" encoding="shift_jis"?>
<addressbook>
<person id="1">
<name>Yamada</name>
<age>26</age>
</person>
</addressbook>

 Flex アプリケーション http_basic2.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:Script>
<![CDATA[
function showResult(event) {
dataid.text = "id:" + srv.result.addressbook.person.id;
name.text = "name:" + srv.result.addressbook.person.name;
age.text = "age:" + srv.result.addressbook.person.age;
}
]]>
</mx:Script>
<mx:HTTPService id="srv" url="data1.xml" result="showResult(event)" />
<mx:Button label="サーバーへアクセス" click="srv.send()" />
<mx:Label id="dataid" width="200" />
<mx:Label id="name" width="200" />
<mx:Label id="age" width="200" />
</mx:Application>

実行結果は次の通りです。

HTTPService では resultFormat を定義していないので、 resultFormat はデフォルトの "object" で処理されました。HTTPService の結果は showResult ファンクションが処理しています。 showResult ファンクションでは result プロパティーの各プロパティーにアクセスをし、その結果を Label に表示しています。 result プロパティーにはサーバーから取得した結果が、ActionScript オブジェクトの構造となり格納されています。ここで作られる ActionScript オブジェクトはサーバーレスポンスの XML ツリー構造に従って作られます。ですから <addressbook> 要素の <person> 要素の中の <name> 要素の中の値を取得するためには result.addresspook.person.name というようにプロパティーをアクセスします。

resultFormat が "object" の場合の例をもう一つ示します。

 サーバーデータ data2.xml

<?xml version="1.0" encoding="shift_jis"?>
<addressbook>
<person id="1">
<name>Yamada</name>
<age>26</age>
</person>
<person id="2">
<name>Tanaka</name>
<age>30</age>
</person>
<person id="3">
<name>Hayashi</name>
<age>25</age>
</person>
</addressbook>

 Flex アプリケーション http_basic2_2.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:Script>
<![CDATA[
function showResult(event) {
var tmp:String ="";
var person_array = srv.result.addressbook.person;
for (var i = 0; i < person_array.length ; i++) {
tmp = tmp + "id:" + person_array[i].id
+ " name:" + person_array[i].name
+ " age:" + person_array[i].age + newline;
}
res.text = tmp;
}
]]>
</mx:Script>
<mx:HTTPService id="srv" url="data2.xml" result="showResult(event)" />
<mx:Button label="サーバーへアクセス" click="srv.send()" />
<mx:TextArea id="res" width="400" height="100%" />
</mx:Application>

実行結果は次のようになります。

このように XML データの中に繰り返し要素があった場合、HTTPService はそれを配列とみなし、自動的にその要素を Array 型のプロパティーとします。(ここの例では person 要素が繰り返されているため、このプロパティーが配列(Array)型と解釈されました。)

配列データは Datagrid などのリスト系のコンポーネントの dataProvider に渡すと、これをリスト要素とみなし、表示することができます。ですから、HTTPService と リスト系のコンポーネントとの連携は非常にシンプルに行うことができます。

データグリッドとの連携例 http_basic2_3.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:HTTPService id="srv" url="data2.xml" />
<mx:Button label="サーバーへアクセス" click="srv.send()" />

<mx:DataGrid id="datagrid1" dataProvider="{srv.result.addressbook.person}">
  <mx:columns>
    <mx:Array>
      <mx:DataGridColumn headerText="ID" columnName="id" />
      <mx:DataGridColumn headerText="Name" columnName="name" />
      <mx:DataGridColumn headerText="Age" columnName="age" />
    </mx:Array>
  </mx:columns>
</mx:DataGrid>
</mx:Application>

実行結果

データの型変換は HTTPSerivce が結果データを読み込み自動的に行います。要素の値が数字のみの場合、Number 型と解釈され、数字以外の文字が混入している場合、String 型、また要素の繰り返しは Array 型で展開されます。

resultFormat では、これ以外にも "xml"、"flashvars" という値を設定することもできます。これらについてはここでは説明しませんが。 API ドキュメントなどを参考に機能や使い方を理解いただければと思います。

Flex MXML API ドキュメント HTTPService reslultFormat プロパティー: http://www.macromedia.com/support/documentation/jp/flex/1_5/asdocs_jp/mx/servicetags/HTTPService.html

いくつかの疑問

  • Q1.resultFormat が "object" の場合について、明示的に作られるオブジェクトの構造を指定することはできないのか。
    Answer: 可能です。 xmlDecode プロパティーで XML データを Object に変換するためのロジックを定義します。詳しくは「様々な問題と解決策 - 予期しないデータ型変換の問題」の中で説明する予定です。
  • Q2. resultFormat が"object" の場合について、生成されたオブジェクトの構造を知る方法はないか。
    Answer: FlexBuilder のデバッグ機能やトレースログなどが使えると思います。「AS オブジェクトのトレーステクニック」が参考になると思います。
  • Q3.日本語の扱いについて問題はないか
    Answer: サーバーからの日本語は utf-8 で送ってください。そうすれば問題はないはずです。

 

次回、第3回は HTTPService を使ってサーバーにデータを送るところから見ていきたいと 思っています。

続く


ご意見・ご感想

技術レポート一覧へ

トップページ


作成日:2005年2月17日
更新日:2005年2月20日