BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル FlexでXMLやJSONを扱う

FlexでXMLやJSONを扱う

美貌と頭脳。FlexとJava。それとも逆でしょうか。誰が決められるのでしょうか。私が知っているのはただ、FlexとJavaは協調して驚くほどのリッチ・インターネット・アプリケーション(RIA)を作り出すということです。Flexをご存じないかも知れません。FlexはMXMLというタグ・ベースの言語(とActionScript)を使ってFlashアプリケーションを作ることのできるオープン・ソースのフレームワークです。

参考:Jack氏が提供するFlex for XML and JSONの操作画面

Adobe社のサイト(http://adobe.com/flex)から、Flex Builderと呼ばれる、Flex用のIDEをダウンロードすることから始めましょう。Flex Builderは商用製品ですが、無料トライアル期間が十分に長いので役に立つものかどうか判断することができます。この記事ではFlexとJavaを一緒に使う方法をデモンストレーションします。Javaでサーバ側、Flexでクライアント側を実行することになります。両方の間の通信プロトコルは好きなプロトコルで構いません。今回はまずXMLを使い、次にJavascript Object Notation(JSON)を使います。というのもこの2つが昨今のWeb 2.0の世界でよく見かけるものだからです。

サーバ側の部品の生成

以下のリスト1に示したJSPファイルからXMLの例を説明します。

  Listing 1. xml.jsp
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">
<jsp:directive.page import="java.text.*"/>
<jsp:directive.page import="java.lang.*"/>
<jsp:directive.page contentType="text/xml"/>
<days><jsp:scriptlet>
<![CDATA[
double compa = 1000.0;
double compb = 900.0;
for (int i = 0; i<=30; i++) {
compa += ( Math.random() * 100 ) - 50;
compb += ( Math.random() * 100 ) - 50;
]]>
</jsp:scriptlet>
<day>
<num><jsp:expression>i</jsp:expression></num>
<compa><jsp:expression>compa</jsp:expression></compa>
<compb><jsp:expression>compb</jsp:expression></compb>
</day>
<jsp:scriptlet>
<![CDATA[ }
]]>
</jsp:scriptlet>
</days>
</jsp:root>

このサービスは2つの企業(compaとcompb)の30日間のランダムな株価データを出力します。最初の企業の株価は$1000から始まり、2つ目の企業は$900から始まります。そしてJSPのコードが日々の株価に対してランダムに作用します。

コマンドラインから'curl'のクライアントを使ってこのサービスにアクセスすると以下のような結果を得ました。

 % curl "http://localhost:8080/jsp-examples/flexds/xml.jsp"
<days><day><num>0</num><compa>966.429108587301</compa>
<compb>920.7133933216961</compb>
</day>...</days>

ルート・タグのタグにいくつかのタグが含まれています。さらに、それぞれのタグは何日目かを示すタグと、A社の株価を示す、B社の株価を示すタグを含みます。2つの株価はランダムに生成されるのでリクエストの度に違う値になります。

インタフェースの作成

株価を返すWebサービスが出来たので、それを見るクライアント・アプリケーションが必要です。まず最初に作るのはグリッド(一覧表)形式で数値を表示するだけのインタフェースになります。Flexプロジェクトを作成するため、Flex Builder IDEで新規作成メニューからFlex プロジェクトを選択して下さい。図1のようになります。

図-1. 新規 Flex プロジェクトのダイアログ

さあプロジェクト名を付けましょう。私は'XML Data Grid:XMLデータ・グリッド'を表すxmldgと名付けます。この操作でタグが書かれたxmldg.mxmlファイルが生成されます。この書き込まれた何も機能しないタグをリスト2に書かれた多くの機能を持ったコード置き換えます。

Listing 2. xmldg.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"> <mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData" /> <mx:Panel title="Stock Data" width="100%" height="100%"> <mx:DataGrid dataProvider="{stockData..day}" width="100%" height="100%"> <mx:columns>
<mx:DataGridColumn
dataField="compa" /> <mx:DataGridColumn dataField="compb" /> </mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>

このxmldgアプリケーションのコードには2つの重要なコンポーネントが含まれています。まず<mx:XML>タグはURLを指定することでFlexにXMLデータ・ソースがあることを知らせます。これによって(id属性で指定された)stockDataという名前の変数が宣言され、<mx:DataGrid>コンポーネントがdataProvider(データの提供元)として利用できるようになります。

コードの残りの部分は見た目の問題です。<mx:Panel>オブジェクトはグリッドを見事にラップします。そして<mx:DataGrid>オブジェクトがデータを表示します。<mx:DataGrid>には一連の<mx:DataGridColumn>が含まれていてどのデータを表示したらいいのかをグリッドに知らせます。

このアプリケーションをFlex Builderから起動すると図2のような画面が表示されます。

図-2. xmldgアプリケーションを実行したところ

これで、表のスクロールが出来るようになり、ウィンドウのサイズを変更し、データ・グリッドのサイズが変更することが確認出来るようになりました。

ちょっとした絞り込みの機能を追加するために、コントロールを使ってコードを変更してみます。これは水平方向のスライダで何日目以降のデータを表示したらいいかを指定出来るようになります。

例えば、スライダを6に指定すると6日目以降のデータだけが表示されるようになります。変更後のコードをリスト3に示します。

Listing 3. xmldg2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData" />
<mx:Panel title="Stock Data" width="100%" height="100%" layout="vertical"
paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10">
<mx:HBox>
<mx:Label text=
"Start Day" />
<mx:HSlider minimum="0" maximum="30" id="dayslider" snapInterval="1" />
</mx:HBox>


<mx:DataGrid dataProvider="{stockData..day.(num >= daySlider.value )}"
width="100%" height="100%"> <mx:columns>
<mx:DataGridColumn
dataField="num" headerText="day" /> <mx:DataGridColumn dataField=="compa" headerText="Company A" /> <mx:DataGridColumn dataField=="compb" headerText="Company B" /> </mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>

少しだけタグが増えましたが、大半は元のままです。<mx:Panel>タグに全てが含まれています。その中には<mx:HBox>(水平方向に配置する箱)タグがあって<mx:Label><mx:HSlider>コントロールが含まれています。スライダは<mx:DataGrid>内でdataProviderとして使用されます。

dataProviderの属性をもう少し細かく見てみましょう。

{stockData..day.(num >= daySlider.value )}

これはActionScriptのE4X式を使って<mx:DataGrid>コントロールに表示されるデータセットを<num>の値がスライダの値以上であるものに絞り込んでいます。Flexは賢いのでスライダの変更によるイベントを監視してデータ・グリッドを自動的に更新してくれます。

これをFlex Builderから起動すると図3のようになります。

図-3. 絞り込み機能付きグリッド

ここまででスライダを動かしそれによってグリッド内のデータがどのような影響を受けるのか確認できるようになりました。スライダを12に合わせたときの表示を図4に示します。

図-4. スライダの値を12にしたところ

これはActionScriptでE4Xを使って出来ることのとても簡単な例です。E4X式を使えばXMLととても簡単にやりとりが出来るのでもう他の方法でXMLを扱う気にならないハズです。

グラフ化

データ・グリッドは少々退屈です。少なくても私にとっては。私は見た目を重視する性質です。そこでこのアプリケーションにグラフを追加してみましょう。そのために(XML graph:XMLグラフを意味する)xmlgphというプロジェクトを作成し、xmlgph.mxmlの内容をリスト4にあるコードで置き換えてください。

 Listing 4. xmlgph.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData" />
<mx:Panel title="Stock Data" width="100%" height="100%" layout="vertical"
paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10">

<mx:HBox>
<mx:Label
text="Start Day" />
<mx:HSlider? minimum="0" maximum="30" id="dayslider" snapInterval="1" />
</mx:HBox>

<mx:LineChart id="chart" dataProvider="{stockData..day.(num >= daySlider.value )}"
width="100%" height="100%">
<mx:series>
<mx:LineSeries xField="num" yField="compa" displayName="Company A" />
<mx:LineSeries xField="num" yField="compb" displayName="Company B" />
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider="{chart}" />
</mx:Panel>
</mx:Application>

このコードはほとんどxmldg2と変わりありません。ただ<mx:DataGrid>コントロールが<mx:LineChart>コントロールに置き換わってグリッドの代わりにグラフを表示するようになっています。そして<mx:Legend>コントロールによって会社の凡例が表示されるようになります。2つの<mx:LineSeries>オブジェクトが<mx:DataGridColumn>オブジェクトに相当するものになります。これらによって折れ線グラフにどの軸を表示したらいいのかが決まります。

これをFlex Builderから起動すると図5のように表示されます。

図-5. 折れ線グラフの例

悪くないでしょう?さらに<x:HSlider>コントロールは残してあるので、ここでもスライダを動かすだけでグラフの表示開始日を変更することができます。

実は、独立して動かすことのできる2つのつまみがあるスライダに変更するというほんの少しの変更を加えるだけでグラフを期間で絞り込めるようになります。このコードをリスト5に示します。

 Listing 5. xmlgph2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData " />
<mx:Panel title="Stock Data " width="100% " height="100% " layout="vertical "
paddingBottom="10 " paddingLeft="10 " paddingRight="10 " paddingTop="10 ">

<mx:HBox>
<mx:Label
text="Date Range " />
<mx:HSlider minimum="0 " maximum="30 " id="daySlider " snapInterval="1 "
thumbCount="2 " values="[0,30] " />
</mx:HBox>

<mx:LineChart id="chart"
dataProvider="{stockData..day.(num>=daySlider.values[0] &&
num<=daySlider.values[1])}
"
width="100%" height="100%">
<mx:series>
<mx:LineSeries
xField="num" yField="compa" displayName="Company A" />
<mx:LineSeries xField="num" yField="compb" displayName="Company B" />
</mx:series>
</mx:LineChart>
<mx:Legend
dataProvider="{chart}" />
</mx:Panel>
</mx:Application>

<mx:HSlider>タグにthumbCountとvalues属性を追加し、<mx:DataGrid>タグのdataProviderを修正しただけです。これはXMLファイルなので、dataProviderに含まれるエンティティをいくつかエンコードする必要がありました。これをFlex Builderから起動すると図6のようになります。

図-6. 範囲選択した折れ線グラフ

以上がXMLに関するデモです。ここからはJSONを返すサービスを使うFlexアプリケーションの作り方を見ていきます。

JSONサーバの作成

JSONを読み込むアプリケーションを作成する手始めにJSONデータ・ソースを作成しましょう。ここでもJSONエンコードされたデータ・ストリームを生成するために使い慣れたJSPを使ってみましょう。サーバ側のJSPコードをリスト6に示します。

 Listing 6. json.jsp
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">
<jsp:directive.page import="java.text.*"/>
<jsp:directive.page import="java.lang.*"/>
<jsp:directive.page contentType="text/json"/>
[<jsp:scriptlet>
<![CDATA[
double compa = 1000.0;
double compb = 900.0;
for (int i = 0; i<=30; i++) {
compa += ( Math.random() * 100 ) - 50;
compb += ( Math.random() * 100 ) - 50;
if ( i > 0 ) out.print( "," );
]]> </jsp:scriptlet>{"compa":<jsp:expression>compa</jsp:expression>,"compb":<jsp:expres
sion>compb</jsp:expression>}<jsp:scriptlet>
<![CDATA[ }
]]>
</jsp:scriptlet>]
</jsp:root>

これはほとんどXMLのサービスと同じですが、XMLタグを返す代わりにJSONエンコードされたデータを返します。

コマンド・ラインから'curl'ユーティリティを実行してこのページを取得すると以下のような結果を得ました。

 % curl "http://localhost:8080/jsp-examples/flexds/json.jsp"
[{"compa":992.2139849199265,"compb":939.89135379532}, ...]

これはまさにJavascriptで作られたクライアント向けの結果です。

JSONサービスの利用

Flexは、Flash PlayerのためのActionScript 3で記述されています。ActionScript 3はJavascriptによく似ていますが、eval関数がありません。では、JSONテキストをどうやってActionScriptが対応したデータ形式に変換するのでしょう?幸いにも、フリーのActionScript 3コア・ライブラリ(http://as3corelib.googlecode.com)にJSONデゴーダとJSONエンコーダの両方が含まれています。

リスト7のコードには、JSONDecoderオブジェクトの使い方が示されています。

 Listing 7. jsondg.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
creationComplete="jsonservice.send()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import com.adobe.serialization.json.JSONDecoder;

private function onJSONResult( event:ResultEvent ) : void {
var data:String = event.result.toString();
data = data.replace( /\s/g, '' );
var jd:JSONDecoder = new JSONDecoder( data );
dg.dataProvider = jd.getValue();
}
]]>
</mx:Script>
<mx:HTTPService id="jsonservice"
url="http://localhost:8080/jsp-examples/flexds/json.jsp"
resultFormat="text" result="onJSONResult(event)" />
<mx:Panel title="Stock Data " width="100% " height="100% ">
<mx:DataGrid id="dg" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn
dataField="compa " />
<mx:DataGridColumn dataField=
"compb " /> </mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>

サーバはJSONデータをテキストとして返すので、データの取得に<mx:XML>タグを使うことはできません。そこで代わりに<mx:HTTPService>タグを使います。このタグは<mx:XML>タグのように機能します。サービスのURLを渡し、戻り値の形式(例ではtext)とHTTPサービスがデータを受信した際に呼ばれるActionScriptの関数を指定します。

この例では、<mx:Script>タグで定義したonJSONResult関数をresultイベントのハンドラに指定しました。この関数は全てのホワイトスペース(空白要素)を取り除いた上でJSONテキストをJSONDecoderに渡します。その後、<mx:DataGrid>コントロールにあるdataProviderにJSONDecoderからの戻り値を指定しています。

ActionScriptにはeval関数がないので、これら全てが安全に行われます。JSONDecoderクラスは流れてくるテキストからオブジェクトを生成するための簡単な状態マシン・パーサーの一種です。最悪の場合、JSONテキストが長すぎるととても長い処理時間を要するようになります。

これより先

FlexはFlashの上に成り立っています。そしてFlashは何とでも通信することができます。直接SOAPベースのWebサービスと通信することができます。さらにAdboe Message Format(AMF)のようなバイナリ・プロトコルを扱うこともできるのです。

もし今回初めてFlexを使ってみたのでしたら、あなたのサイト上に視覚効果を追加するためにFlexを使ってFlashウィジェットを構築したいと思うでしょう。Flashアプリケーションが十分早くダウンロード出来るように、新しいFlashプレイヤに搭載されたラインタイム共有ライブラリ(RSL)の機能が使われることを確認しましょう。この機能によってクライアント側で(Flexライブラリのような)大きなライブラリをキャッシュして別のFlashアプリケーションで再利用出来るようになります。

FlexとJavaの組み合わせは強力です。Javaはサーバ側で素晴らしいバックエンドを提供します。そしてFlexとActionScript 3は簡単に記述して利用することが出来るクロス・プラットフォームに対応したGUIレイヤを提供します。

 

原文はこちらです:http://www.infoq.com/articles/flex-xml-json
(このArticleは2008年10月12日に原文が掲載されました)

この記事に星をつける

おすすめ度
スタイル

BT