Monday, January 7, 2008

Webservices

The web service can be easily used in the Flex 2. The web service may be in any language. The client can be made to consume the web service. There are two main ways to do that.


First method

<mx:WebService id="WShello" wsdl="http://localhost:2091/CreditCard/CreditCard.asmx?wsdl">

<mx:operation

name="HelloWorld" result="typeRPCResult(event)">

</mx:operation>

<mx:operation

name="ListFiles" result="showFiles(event)">

</mx:operation>

</mx:WebService>

In this case we make use of mx:webservice Tag. We need to specify the location of the WSDL file.

Then we specify the various operations we want to perform. My advice is mention only the functions that don’t want any parameter to be passed.

Result specify the function to be called once the data has arrived.

The event is of resultEvent type

Now in order to get the data we need to call the webservice. This is done by

WShello.HelloWorld.send();

i.e. Webservice_object. Operation_name. Send();

Once the result has arrived the general prototype of the function called is

Private function function_name(evt:resultEvent):void

{
//here you should typecast the event.result into the expected type

var s:string=(event.result as String);

}

Second Method

This method uses more of a programmatic approach. The main use of this method is to call the webmethods that require paramters to be passed to them

The various steps to be followed are:

1. declare an object of type websevice

public var webse:WebService = new WebService();

2. Call a function that will initialize the object

public function callWebMethod():void{

3. Inside the function you need to specify the wsdl file

webse.wsdl="http://localhost:2091/CreditCard/CreditCard.asmx?wsdl";

4. load the wsdl

webse.loadWSDL();

5. Once loaded wsdl file will generate a LoadEvent. We need to call a function on that event so that the necessary webmethod can be called

webse.addEventListener(LoadEvent.LOAD, onWSDL);

onWSDL is the method to be called

6. private function onWSDL(event:LoadEvent):void{

is the prototype for the function. Note that the event type is LoadEvent. The firast parameter in the eventListener call will specify the kind of event that will happen.

7. Before actually calling the webmethod register an helper method that will handle the results arrived from the webmethod

webse.GetFile.addEventListener(ResultEvent.RESULT, onGetFile);

specify the webmethod_name.addEventListener

Note that the event type is ResultEvent

8. Call the webmethod passing the correct parameter

Webse.GetFile(parm1.parma2…)

9. Handle the result in the onGetFile() function

Private function onGetFile(event:ResultEvent):void{

}

10. type cast the event.result to the type you require

var s:string=(event.result as String);

In my sample code I have typecasted it to an object, since the webservice will be returning a complex data type

var ob:Object=(event.result as Object);


The object is then used to populate WebFileData object.





The following is the code snippet that make use of both of the methods.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.soap.LoadEvent;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
import valueObject.*;
[Bindable]
private var arc:ArrayCollection = new ArrayCollection();

private var theWF:WebFileData;

public var webse:WebService = new WebService();
//convert the result into the type that is returned.
public function typeRPCResult(evt:ResultEvent):void{
hell.text=(evt.result as String);
}
// what ever is returned convert the result into that.
public function showFiles(evt:ResultEvent):void{
arc=(evt.result as ArrayCollection);
}

//function to initialise the webservice (THE SECOND METHOD)

public function callWebMethod():void{
webse.wsdl="http://localhost:2091/CreditCard/CreditCard.asmx?wsdl";
webse.loadWSDL();
// the eventhandler that will be called when the loadevent happebns
webse.addEventListener(LoadEvent.LOAD, onWSDL);
}

/**
* function to display the results from the web service
**/
private function onWSDL(event:LoadEvent):void{
Alert.show("wsdl loaded");
// register the eventhandler that will be called once the result is back
webse.GetFile.addEventListener(ResultEvent.RESULT, onGetFile);
var tempString:String=txtFile.text;
var tempFileName:String;
//fileName = fileName.substr(fileName.lastIndexOf(“/”) + 1);
tempFileName=tempString.substr(tempString.lastIndexOf("\")+1);
hell.text=tempFileName;
//Alert.show(hell.text);
webse.GetFile(tempFileName);
}

// this function will be responsible to render the result on the panel
private function onGetFile(event:ResultEvent):void
{
var ob:Object=(event.result as Object);
//you dont need to specify new here , since the createWF function will take care of it
theWF=WebFileData.createWF(ob);
//hell.text=theWF.CreationTime.date.toString();
resName.text=theWF.Name;
resContent.text=theWF.Contents.toString();
resCD.text=theWF.CreationTime.toDateString()+" "+theWF.CreationTime.toTimeString();
resLAT.text=theWF.LastAccessTime.toDateString()+" "+theWF.LastAccessTime.toTimeString();
resLWT.text=theWF.LastWriteTime.toDateString()+" "+theWF.LastWriteTime.toTimeString();


}

// to invoke the web methods
private function init():void{
WShello.HelloWorld.send();
WShello.ListFiles.send();
}



]]>
</mx:Script>
<!-- this is one of the ways to define the web services (THE FIRST METHOD) -->

<mx:WebService id="WShello" wsdl="http://localhost:2091/CreditCard/CreditCard.asmx?wsdl">
<mx:operation name="HelloWorld" result="typeRPCResult(event)">
</mx:operation>
<mx:operation name="ListFiles" result="showFiles(event)">
</mx:operation>
</mx:WebService>

<mx:HBox>

<mx:VBox>
<mx:Label id="hell" />
<mx:List id="ls" dataProvider="{arc}" rowCount="{arc.length}" />
</mx:VBox>
</mx:HBox>
<mx:Panel x="221" y="10" width="500">

<mx:Label text="You have selected:"/>

<mx:Text id="txtFile" width="400" text="{ls.selectedItem.toString()}"/>

<mx:Button name="btnGet" label="Copy" click="callWebMethod()" />



</mx:Panel>
<mx:Panel x="221" y="114" width="500" height="268" layout="absolute" title="The Result">
<mx:Canvas x="10" y="0" width="100%" height="100%">
<mx:Label x="10" y="26" text="Name:"/>
<mx:Text x="60" y="26" width="213" height="18" id="resName" text="xx"/>
<mx:Label x="10" y="52" text="Content"/>
<mx:TextArea x="67" y="51" width="248" height="43" id="resContent"/>
<mx:Label x="10" y="117" text="Creation Date"/>
<mx:Text x="109" y="117" width="206" id="resCD" height="18"/>
<mx:Label x="10" y="143" text="LastAccessTime" width="93"/>
<mx:Text x="121" y="141" width="180" id="resLAT" height="20"/>
<mx:Label x="10" y="169" text="LastWriteAccess" width="93"/>
<mx:Text x="131" y="169" width="170" id="resLWT" height="18"/>
</mx:Canvas>
</mx:Panel>

</mx:Application>


/*****************************/
The WebFileData class


import flash.utils.ByteArray;
import mx.rpc.soap.*;
import mx.charts.chartClasses.DataDescription;
[Bindable]
public class WebFileData
{
public var Name:String;
public var Contents:ByteArray;
public var CreationTime:Date;
public var LastAccessTime:Date;
public var LastWriteTime:Date;
public function WebFileData(_Name:String,_Contents:ByteArray,_CreationTime:Date,_LastAccessTime:Date,_LastWriteTime:Date){
this.Name=_Name;
this.Contents=_Contents;
this.CreationTime=_CreationTime;
this.LastAccessTime=_LastAccessTime;
this.LastWriteTime=_LastWriteTime;
}
/**
* The function will accept the parameter of type object and then it will fill the datastructure and
* return back the object
**/
public static function createWF(o:Object):WebFileData{
var WF:WebFileData=new WebFileData(o.Name,o.Contents,o.CreationTime,o.LastAccessTime,o.LastWriteTime);
return WF;
}

}

No comments: