In this article you will learn how to call webservices hosted on asp.net applications from flex.html
First rewrite webservice class as CYMService:web
package Services { import mx.controls.Alert; import mx.managers.CursorManager; import mx.rpc.AbstractOperation; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.rpc.soap.SOAPHeader; import mx.rpc.soap.WebService; public class CYMService extends WebService { private var _callBackHandler:Function; //成功時的回調函數 private var _faultHandler:Function; //失敗時的回調函數 private var _args:Array; //傳入的參數 //構造函數 @wsdl:WebService地址 public function CYMService(wsdl:String) { super(); this.wsdl = wsdl; this.loadWSDL(); CursorManager.setBusyCursor(); } //設置成功時回調函數 @callBackHandler:回調函數 public function set callBackHandler(callBackHandler:Function):void { CursorManager.removeBusyCursor(); this._callBackHandler = callBackHandler; } //得到回調函數 public function get callBackHandler():Function { return this._callBackHandler; } //設置傳入參數 public function set args(args:Array):void { this._args = args; } //得到傳入參數 public function get args():Array { return this._args; } //設置失敗時回調函數 public function set faultHandler(faultHandler:Function):void { this._faultHandler = faultHandler; } //得到失敗時回調函數 public function get faultHandler():Function { return this._faultHandler; } //設置SOAP頭 public function initHeader(header:SOAPHeader):void { this.clearHeaders(); this.addHeader(header); } //調用WebService中的函數 @functionName:要調用的函數 @args:傳入的參數 public function sendOperation(functionName:String,args:Array):void { //根據方法名動態調用WebService服務器的方法 var operation:AbstractOperation = this.getOperation(functionName); //爲調用的方法添加監聽器,回調函數由外部動態傳入 operation.addEventListener(ResultEvent.RESULT,this.callBackHandler); //爲調用的方法添加錯誤監聽器,若是傳入的錯誤處理方法爲空,則調用默認的處理方法 if(this.faultHandler != null) { operation.addEventListener(FaultEvent.FAULT,this.faultHandler); } else { operation.addEventListener(FaultEvent.FAULT,defaultFaultHandler); } //爲調用的方法傳參數,參數類型爲Array operation.arguments = args; //執行調用的方法 operation.send(); } //沒有設置失敗時回調函數時的默認回調函數 private function defaultFaultHandler(event:FaultEvent):void { CursorManager.removeBusyCursor(); } } }
Second, create class ServiceLocation to store webservice url:服務器
package Services { public class ServiceLocation { //WebService地址 public static var webServiceURL:String="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl"; public function ServiceLocation() { } } }
Third,call webservice's function,here is demo to call CYMService:app
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="application1_initializeHandler(event)" applicationComplete="application1_applicationCompleteHandler(event)"> <fx:Script> <![CDATA[ import Services.CYMService; import Services.ServiceLocation; import mx.controls.Alert; import mx.events.FlexEvent; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; private var m_WebService:CYMService=null; protected function application1_initializeHandler(event:FlexEvent):void { // 初始WebService m_WebService=new CYMService(ServiceLocation.webServiceURL); m_WebService.callBackHandler = getResult; m_WebService.faultHandler = faultHandlerFun; } // 調用成功時,處理webservice結果 private function getResult(event:ResultEvent):void { if(event.result != null) { // doing something } } // 失敗時處理函數 protected function faultHandlerFun(event:FaultEvent):void { Alert.show(event.toString()); } protected function application1_applicationCompleteHandler(event:FlexEvent):void { // 加載杭州的天氣狀況 var cityName:String = "杭州"; var arr:Array = new Array(); arr.push(cityName); // 調用webservice中的getWeatherbyCityName函數,arr爲參數列 m_WebService.sendOperation("getWeatherbyCityName",arr); } ]]> </fx:Script> </s:Application>
Final, see the result of event.result that can be rendered on the screen and manipulated by you.asp.net
注意:Flex中WebService是異步的,因此不要期望在循環在調用WebService以得到不一樣的結果。函數
for(var i:int=0; i < MAX_CHILDREN; i++) { // 圖片 var Simgid:String = AppData.GetValue(arr[i],"事件編號"); getPicURL(Simgid); }
//經過圖片編號得到圖片地址 public function getPicURL(Simgid:String):void { var styleName:String = "PicList"; //模型名字:圖片列表 var arr:Array = new Array(); arr.push(styleName); arr.push("Simgid='" + Simgid + "'"); //調用webservice中的GetData函數,arr爲參數列 m_WebService3.sendOperation("GetData",arr); }
//調用成功時,處理webservice3結果(得到圖片地址)
private function getResult3(event:ResultEvent):void
{
......
}
本想經過上面代碼得到每張圖片地址,但調試發現圖片地址均相同,且getResult3函數沒有調試進去(起碼沒有立刻調試進去),顯然是異步在做怪。測試
解決上面問題有兩個:一是將異步以鎖的形式來達到同步效果,但查閱資料不推薦使用;二是圖片在一開始就所有查出放到Dictionary中,在循環中只需根據key查詢value便可。flex
上面封裝的CYMService類在工做中使用起來較麻煩,索性再封裝以易用。this
封裝的類還叫CYMService,回調函數以參數形式傳入。
package Services { /** * @author chenyuming */ import mx.controls.Alert; import mx.managers.CursorManager; import mx.rpc.AbstractOperation; import mx.rpc.AsyncToken; import mx.rpc.IResponder; import mx.rpc.Responder; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.rpc.soap.SOAPHeader; import mx.rpc.soap.WebService; public class CYMService extends WebService { //構造函數 @wsdl:WebService地址 public function CYMService(wsdl:String) { super(); this.wsdl = wsdl; this.loadWSDL(); } //調用WebService中的函數 public function call(methodName:String,callback:Function,...args):void { var method:AbstractOperation = this.getOperation(methodName); method.arguments = args; var call:AsyncToken = method.send(); call.userDefinedCallback = callback; call.addResponder(new Responder(resultCallback, faultCallback)); } //設置成功時回調函數 public function resultCallback(event:ResultEvent):void { var callback:Function = event.token.userDefinedCallback as Function; if (callback != null) { var result:CYMServiceResult = new CYMServiceResult(); result.error = false; result.result = event.result; callback(result); } } //設置失敗時回調函數 public function faultCallback(event:FaultEvent):void { var callback:Function = event.token.userDefinedCallback as Function; if (callback != null) { var result:CYMServiceResult = new CYMServiceResult(); result.error = true; result.errorMessage = event.fault.toString(); callback(result); } } } }
其中CYMServiceResult定義以下:
package Services { /** * @author chenyuming */ public class CYMServiceResult { public function CYMServiceResult() { } public var error:Boolean = false; public var errorMessage:String = null; public var result:Object = null; } }
使用起來就變得簡易了:
protected function btnGetData_clickHandler(event:MouseEvent):void { // 加載城市的天氣狀況 var cityName:String = StringUtil.trim(txtInput.text); var arr:Array = new Array(); arr.push(cityName); var service:CYMService = new CYMService(ServiceLocation.webServiceURL); service.call("getWeatherbyCityName",getResult,arr); } private function getResult(event:CYMServiceResult):void { if(event.error) //調用錯誤 { Alert.show(event.errorMessage); } else //調用正確 { txtOutput.text = ""; var obj:Object= event.result; for each(var content:String in obj) { txtOutput.text += content + "\n"; } } }
測試代碼:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Script> <![CDATA[ import Services.CYMService; import Services.CYMServiceResult; import Services.ServiceLocation; import mx.controls.Alert; import mx.events.FlexEvent; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.utils.StringUtil; private function getResult(event:CYMServiceResult):void { if(event.error) { Alert.show(event.errorMessage); } else { txtOutput.text = ""; var obj:Object= event.result; for each(var content:String in obj) { txtOutput.text += content + "\n"; } } } protected function btnGetData_clickHandler(event:MouseEvent):void { // 加載城市的天氣狀況 var cityName:String = StringUtil.trim(txtInput.text); var arr:Array = new Array(); arr.push(cityName); var service:CYMService = new CYMService(ServiceLocation.webServiceURL); service.call("getWeatherbyCityName",getResult,arr); } ]]> </fx:Script> <s:TextArea id="txtOutput" x="28" y="69" width="917" height="498" fontFamily="宋體" fontSize="14"/> <s:TextInput id="txtInput" x="216" y="30" fontFamily="宋體" fontSize="14"/> <s:Button id="btnGetData" click="btnGetData_clickHandler(event)" x="374" y="30.5" label="獲取城市天氣數據" fontFamily="宋體" fontSize="14"/> <s:Label x="28" y="35" text="請輸出城市名稱,好比:杭州" fontFamily="宋體" fontSize="14"/> </s:Application>
運行結果:
源碼下載在這。