Simple Soap Example


To demonstrate many of the new features of E4X, we'll create a simple example that uses SOAP-formatted XML to send and receive data from a remote Web service. The service accepts an IP address and returns the geographical location it resolves to.

Note

For more information on sending and loading XML, see Chapter 14.


The following example sends and loads data using a public Web service whose WSDL document is located at http://ws.cdyne.com/ip2geo/ip2geo.asmx. You can read more about the Web service at http://ws.cdyne.com/ip2geo/ip2geo.asmx?op=ResolveIP.

Before we create the example, we'll first look at the format of the request and response packets. The request packet is a standard SOAP-formatted request. The heart of the request is inside the <m:ResolveIP> tags. It has two child elements: the first is the IP address value, and the second is the license key. Here's an example of what the packet might look like:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www. w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">    <SOAP-ENV:Body>       <m:ResolveIP xmlns:m="http://ws.cdyne.com/">          <m:IPaddress>24.118.19.171</m:IPaddress>          <m:LicenseKey>0</m:LicenseKey>       </m:ResolveIP>    </SOAP-ENV:Body> </SOAP-ENV:Envelope>


In this example, notice that the license key is 0. This particular Web service allows us to test the service by using a license key of 0.

The response packet is a SOAP-formatted response. Inside the <ResolveIPResult> tag are the values for the response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns: xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/ XMLSchema">    <soap:Body>       <ResolveIPResponse xmlns="http://ws.cdyne.com/">          <ResolveIPResult>             <City>Chicago</City>             <StateProvince>IL</StateProvince>             <Country>USA</Country>             <Latitude>41.5000000</Latitude>             <Longitude>-87.4100000</Longitude>             <HasDaylightSavings>false</HasDaylightSavings>             <Certainty>16</Certainty>          </ResolveIPResult>       </ResolveIPResponse>    </soap:Body> </soap:Envelope>


You can see that the response includes information such as the city, state, and country to which the IP address resolves. This example contains specific data such as Chicago, IL, and USA. The actual Web service responses will contain data specific to the IP address passed in using the request.

Now that we've looked at the structure of the request and response packets, we can build the sample application.

Building the Custom Event

The very first thing we'll need to build in this example is a custom event type. Because our event has data associated with it, we will create a custom event class called LocationEvent. This class extends the built-in Event class and simply adds five public properties. These properties are later populated from the data returned by the Web service.

package com.peachpit.aas3wdp.e4xexample {    import flash.events.Event;    public class LocationEvent extends Event {       private var _city:String;       private var _stateProvince:String;       private var _country:String;       private var _latitude:String;       private var _longitude:String;              public function get city():String {          return _city;       }       public function set city(value:String):void {          _city = value;       }       public function get stateProvince():String {          return _stateProvince;       }       public function set stateProvince(value:String):void {          _stateProvince = value;       }       public function get country():String {          return _country;       }       public function set country(value:String):void {          _country = value;       }           public function get latitude():String {          return _latitude;       }           public function set latitude(value:String):void {          _latitude = value;       }           public function get longitude():String {          return _longitude;       }       public function set longitude(value:String):void {          _longitude = value;       }       public function LocationEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false) {          super(type, bubbles, cancelable);       }    } }


This class requires a fair amount of code, but it is quite simple. It merely extends Event and adds additional properties specific to location. We'll see how to use this event type in the next few sections.

Building the Web Service Class

The ResolveIP class does all the heavy lifting in this example. It is responsible for making the request and listening for the response. All the SOAP communication is encapsulated in this class.

The first thing our class does in the constructor is to create the URLRequest object. This object is where we define the request data (the request SOAP packet), headers, URL, methods, and content type. Notice the use of curly braces to populate the request data with the IP address that is passed into the constructor. The URLLoader object is used to execute this request.

The onComplete() event handler is where we respond to the URLLoader.COMPLETE event. Here we create a custom event object using our LocationEvent class.

package com.peachpit.aas3wdp.e4xexample {    import com.peachpit.aas3wdp.e4xexample.LocationEvent;    import flash.events.Event;    import flash.events.EventDispatcher;    import flash.net.URLLoader;    import flash.net.URLRequest;    import flash.net.URLRequestHeader;    public class ResolveIP extends EventDispatcher {       private var urlLoader:URLLoader;       public function ResolveIP(ipAddress:String) {          var urlRequest:URLRequest = new URLRequest();          urlRequest.contentType = "text/xml; charset=utf-8";          urlRequest.method = "POST";          urlRequest.url = "http://ws.cdyne.com/ip2geo/ip2geo.asmx";          var soapAction:URLRequestHeader = new URLRequestHeader("SOAPAction",             "http://ws.cdyne.com/ResolveIP");          urlRequest.requestHeaders.push(soapAction);          urlRequest.data = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.             org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/             encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:             xsd="http://www.w3.org/2001/XMLSchema">             <SOAP-ENV:Body>                <m:ResolveIP xmlns:m="http://ws.cdyne.com/">                   <m:IPaddress>{ipAddress}</m:IPaddress>                   <m:LicenseKey>0</m:LicenseKey>                </m:ResolveIP>             </SOAP-ENV:Body>          </SOAP-ENV:Envelope>;          urlLoader = new URLLoader();          urlLoader.addEventListener(Event.COMPLETE, onComplete);          urlLoader.load(urlRequest);       }       private function onComplete(event:Event):void {          var envelope:XML = XML(urlLoader.data);          var soap:Namespace = envelope.namespace("soap");          var response:Namespace = new Namespace("http://ws.cdyne.com/");          var result:XMLList = envelope.soap::Body.response::ResolveIPResponse.             response::ResolveIPResult;          var locationEvent:LocationEvent = new LocationEvent(Event.COMPLETE, true, true);          locationEvent.city = result.response::City.toString();          locationEvent.stateProvince = result.response::StateProvince.toString();          locationEvent.country = result.response::Country.toString();          locationEvent.latitude = result.response::Latitude.toString();          locationEvent.longitude = result.response::Longitude.toString();          dispatchEvent(locationEvent);       }    } }


Creating the Main Class

Invoking the ResolveIP class is simple. Just create a new instance of the class and pass an IP address into the constructor during creation. Then register for the complete event and the error event. The complete event returns a LocationEvent object. The error events are not actually thrown by ResolveIP, but instead are thrown by the URLLoader object inside the ResolveIP object. Because the error events aren't caught by the ResolveIP object, they bubble up to our WebServiceExample object.

Here's the main class for our SOAP-parsing Web service example:

package {    import com.peachpit.aas3wdp.e4xexample.LocationEvent;    import com.peachpit.aas3wdp.e4xexample.ResolveIP;    import flash.events.Event;    import flash.events.IOErrorEvent;    import flash.events.SecurityErrorEvent;    import flash.events.KeyboardEvent;    import flash.ui.Keyboard;    import flash.display.Sprite;    import flash.text.TextField;    import flash.text.TextFieldType;    public class WebServiceExample extends Sprite {       private var _resolveIP:ResolveIP;       private var _text:TextField;       public function WebServiceExample() {          // Create a text field to accept user input and           // display the response.          _text = new TextField();          _text.type = TextFieldType.INPUT;          _text.width = 200;          _text.height = 22;          _text.background = true;          _text.border = true;          // Initially populate the text field with a valid          // IP address. This makes it easy to test the          // application. You can also change this at runtime          // if you want to test a different IP address.          _text.text = "24.118.19.171";          // Listen for keyboard events.          _text.addEventListener(KeyboardEvent.KEY_UP, onKey);          addChild(_text);       }       private function onKey(event:KeyboardEvent):void {          // If the user presses the Enter key then createa a          // new ResolveIP object, passing it the text from          // the text field. Then listen for events.          if(event.keyCode == Keyboard.ENTER) {             _resolveIP = new ResolveIP(_text.text);             _resolveIP.addEventListener(Event.COMPLETE, onComplete);             _resolveIP.addEventListener(IOErrorEvent.IO_ERROR, onError);             _resolveIP.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);          }       }       // When the response is returned, display the location       // to which the IP address resolves.       private function onComplete(locationEvent:LocationEvent):void {          _text.text = locationEvent.city + ", " + locationEvent.stateProvince;       }       private function onError(event:Event):void {          _text.text = "error: " + event.type;       }    } }


You can test this example by entering a valid IP address in the text field and pressing the Enter key. The Web service will respond shortly, and the result will be displayed in the text field.

Classic XML API

The old way of working with XML still exists in ActionScript 3.0 in the form of the XMLDocument and XMLNode classes. These classes are included in ActionScript 3.0 mainly for backwards compatibility. All new projects should use E4X because it is the new standard for working with XML in ActionScript.





Advanced ActionScript 3 with Design Patterns
Advanced ActionScript 3 with Design Patterns
ISBN: 0321426568
EAN: 2147483647
Year: 2004
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net