本文很好的例舉了如何將Flex 和Java一起使用。Java將運行這種服務。Flex將在客戶端上運行。它們兩者之間的協議可以真正的實現你想要的。既然這樣,那麼先使用XML,然後使用Javascript Object Notation (JSON),因為這兩者都是我們最常見的Web 2.0標准
創建服務器區塊
XML實例從表1中一個簡單的JSP文檔開始
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﹥
這個服務器輸出兩個公司(公司A和公司B)三十天的一些任意的庫存數據。第一個公司從$1000開始估價。第二個公司從$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﹥
﹤days﹥標簽是根標簽,包含一組﹤day﹥標簽,每一個﹤day﹥有一個﹤num﹥標簽做日期標志,一個﹤compa﹥函數作為公司A的交易價格,﹤compb﹥標簽作為公司B的交易價格。兩個公司的交易價格可以隨著他們自己的要求改變。
創建界面
現在,我們有一個web服務器輸出交易價格,我們需要一個客戶端應用程序去查看交易價格。第一個我們要創建的是一個可以簡單的顯示數字的網格界面。去創造Flex產品,我們從Flex Builder IDE的新菜單上面挑選Flex產品。這在圖1中展示。
圖1
到這一步,所有我們需要做的就是給這個產品一個名字。因為XML Data Grid的緣故,我將叫它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應用程序代碼有兩個准素分支。第一個是﹤mx:XML﹥標簽,表明Flex這有一個XML數據源顯示在外,以及供給一個URL.我將創造一個本地變量叫做stockData (使用id說明),﹤mx:DataGrid﹥構件可以作為dataProvider使用。
其余的代碼就是界面。這有一個﹤mx:Panel﹥ object給予一個精致的小的環繞網格。然後﹤mx:DataGrid﹥ object顯示數據。在﹤mx:DataGrid﹥之內是一組控制網格什麼數據可以顯示的﹤mx:DataGridColumn﹥規范。
當我們從Flex Builder啟動這個程序,我們將會看到如圖2所示的畫面。
圖2
從這裡我們可以滾動列表,改變窗口的大小,可以看見數據網格格式的改變。
增加一個小的篩選功能,我們將使用﹤mx:HSlider﹥控制來更新代碼,一個橫向滑動將詳細說明網格應該從那個數據開始顯示。
舉例,如果我們設置slider是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﹥控制。Slider在﹤mx:DataGrid﹥dataProvider文件中被使用。
讓我們仔細看一下dataProvider特性。
{stockData..day.(num﹥= daySlider.value )}
這是使用ActionScript's E4X語法來削減數據集的﹤mx:DataGrid﹥控制,僅當這些標簽數據中的﹤num﹥函數大於或者等於slider值時有效。Flex有足夠的能力監測slider自動升級數據網格給我們帶來的事態的變化。
但我們把它從Flex Builder中提出,將如圖3所示。
圖3
到這裡我們可以調節slider,觀察它如何在網格中影響數據。圖4顯示的是我將slider設置為12的結果。
圖4
這只是關於在ActionScript中使用E4X能做的事情中的一個簡單的例子。E4X語法使你處理XML如此簡單,以至於你不會再想使用別的辦法。
數據網格有一些令人厭煩,至少對我來說是這樣的。我是一個被視覺主導的人。所以讓我們在這個上面展開圖表。要實現這個目的,我們要創造一個新的項目替換xmlgph,叫做xmlgph(XML圖表)。使用表4的代碼創建mXML文件。
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﹥控制會使不同顏色的線條來顯示每個公司的狀況。兩個﹤mx:LineSerIEs﹥ objects與﹤mx:DataGridColumn﹥objects對於制圖表有相同的意義。它們讓圖表知道數據應該顯示在數軸的什麼位置是合適的。
當我們從Flex Builder啟動這個程序,我們將會看見如圖5顯示的內容。
圖5
還不壞,不是嗎?而且因為﹤x:HSlider﹥控制仍然在運行,我們可以僅僅通過移動slider來改變圖表開始的day。
事實上,只需要進行一些小的改變,我們就可以允許圖表通過slider裡面的兩個thumbs顯示一個days窗口提供給用戶,他們可以獨立移動。代碼如表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和價值,以及在﹤mx:DataGrid﹥標簽中升級dataProvider。因為這是XML,我不得不在dataProvider中編碼。當我們從Flex Builder中運行它,我們會看見如圖6所示的內容。
圖6
這是XML的部分演示。從這裡,我將向你展示如何建造一個Flex應用程序消耗JSON服務器。
創建JSON服務器
創建一個可讀的JSON應用程序需要以創建一個JSON數據源為前提。再次,我們將求助於可信賴的JSP去創建JSON代碼數據流。服務器的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:expression﹥compb﹤/JSp:expression﹥}﹤JSP:scriptlet﹥
﹤![CDATA[ }
]]﹥
﹤/JSP:scriptlet﹥]
﹤/JSP:root﹥
這看起來很像是XML服務器,但是我們創建一個JSON 代碼數據代替創建一個XML標簽。
當我從命令行運行'curl'有效,會得到如下頁面:
% curl "http://localhost:8080/jsp-examples/flexds/JSon.JSP"
[{"compa":992.2139849199265,"compb":939.89135379532}, ...]
這正是Javascript客戶端想看見的。
消耗JSON服務器
Flex 在ActionScript 3中用Flash player的程序設計語言書寫。這與Javascript相似,但是他缺乏eval 功能。我們如何在ActionScript data中運行JSON text?謝天謝地,免費的ActionScript 3中心實驗室(http://as3corelib.googlecode.com)帶來了JSON decoder 和 a JSON encoder插件。
表7中的代碼顯示的是運行的JSONDecoder object。
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,然後限制結果的格式(i.e.text),當HTTP 服務用數據回復時候ActionScript開始運行。
這種情況下,我為JSONResult代碼設置終函數,然後我可以在﹤mx:Script﹥標簽中列出表。這種方法可以考慮到JSONDecoder object上任何的空白以及JSON 文本。然後在﹤mx:DataGrid﹥控制上設置dataProvider,取得JSONDecoder的返回值。
所有這些操作都是完全安全的,因為ActionScript上沒有eval功能。JSONDecoder類是一個從工作文本中創建objects的簡單的狀態分析器。最壞的情況就是因為JSON 文本過大,導致它為了得到結果需要運行很長時間。