In this article you will learn how to call webservices hosted on asp.net applications from flex.
First rewrite webservice class as CYMService:
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:
<?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.
2013年11月25日 修改
注意: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即可。
2013年12月13日修改
上面封装的CYMService类在工作中使用起来较麻烦,索性再封装以易用。
封装的类还叫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>
运行结果:
源码下载在这。
相关文章
转载请注明:二十画生 » Flex数据交互之WebService