Tuesday, January 29, 2008

Amazon Online Shopping with Web Service Framework for PHP

I finally managed to submit my first article for WSO2 Oxygen Tank. It is about how to do online shopping with Amazon Web Services using Web Service Framework for PHP.

There I'm demonstrating how to write a simple client library to access Amazon Web Services and how to use that library to write your own application to do online shopping with Amazon.com

There I attached the Client library code and two sample applications, one very simple php command line application and the other much improved web application. Hope this will be useful to people who are interested in working with WSF/PHP.

Monday, January 28, 2008

Select you service operation parameters..

In Web Service Framework for PHP 1.2, when you are writing a service using WSService with a WSDL, you always had to specify the type of the operation parameters to be "MIXED". But it would have been more convenient that the 'MIXED' to be default for ther service operation parameters when WSDL is specified.

So yesterday I took some minitues and change the logic so that,

1. When the WSDL is specified, the opParms would be default to "MIXED"
2. Otherwise, the opParams would be default to 'WSMESSAGE'.

So wsdl-mode code will be simplified to this..

function QueryPurchaseOrderFunction($pro_name, $quantity, $date, $orderNo) {
// the business logic.

}

$operations = array("QueryPurchaseOrder" => "QueryPurchaseOrderFunction");

// The following line is not required

// $opParms = array("QueryPurchaseOrderFunction" => "MIXED")

$svr = new WSService(array("wsdl"=>"sample_wsdl_11.wsdl",
//opParams" => $opParams; // This too not required

"operations" => $operations));

Wednesday, January 23, 2008

Where to set your options?.. in WSClient or in WSMessage?

If you are familiar with WSF/PHP web service API, you may find that you can set your options in different level. For an example in order to set the endpoint you can either use the WSClient constructor like this,

new WSClient("to" => "endpoint",
"other_options" => .. );

or you can use the WSMesasge constructor

new WSMessage("to" => "endpoint",
"other_options" => .. );

It may seems quite unnecessary to have duplicate methods to set something like "endpoint". But there are cases this is really helpful in your application.

If you ever tried calling two web service operations from one WSClient object, you may have already found the importance of having this way.

In such a case you can set the common options in the WSClient and operation specific options in the WSMessage.

Most probably you will use the same WSClient to invoke different operation in a service. There your service endpoint is the same for all the operation. So you can set the service endpoint and additionally some other common configurations like the soap version in the WSClient constructor.

new WSClient("to" => "common_endpoint",
"useSOAP" => 1.1 );

After that you can concentrate on message specific options. One would be "action" which is different from message to message. In addition to that common case, say you have some set of operations which need authentication and others don't need. For that you have to use user-name tokens for that particular set of operations. What you can do is setting that security policy and the security token only to that request messages.

$client->request(new WSMessage( $payload,
array("action" => "http://me.org/authenticating_operation",
"securityToken" => $securityToken,
"policy" => $policy)));

So I think it is clear the flexibility provided by the duplicate methods of doing the same thing. It make your code more organized and most importantly more efficient.

Tuesday, January 22, 2008

PHP Web Services with fopen ..

If you have done little bit of 'C' (at least up to the lesson 'File Handling'), you may have come up with the function 'fopen'.

In PHP you can use 'fopen' not only to open a file in your hard disk, but also to open resource over network, specially from the Internet. Simply you can emulate http, https or ftp client functionality with the fopen.

That is simply you may cheat your friends by writing a your own version of Google like this.

<h1>My Google</h1>

<?php
$fp = fopen("http://www.google.com", "r");

$google_html = fpassthru($fp);
echo $google_html;
?>


You may find out that fopen is just a http client (and load only what it asks to load), it doesn't load images, since they need some additional http request which is automatically done if you instead did this request from a browser.

I think it is clear what 'fopen' can do. Why not we use it to access 'REST' web services. Yea, it is possible. To access 'REST' web services you only need is a Http client and as I mentioned 'fopen' is a Http client.

Let me show you how to access some real web service with fopen. I take amazon web service for an example.


<?php

$query = "TEST";
$catagory = "Books";
/* Use your own amazon key,
You can get it from http://aws.amazon.com */

$amazon_key = "your_amazon_key";


$fp = fopen("http://webservices.amazon.com/onca/xml?".
"SubscriptionId={$amazon_key}&".
"Service=AWSECommerceService&".
"Operation=ItemSearch&".
"Keywords={$query}&".
"SearchIndex={$catagory}&", "r");


$res = fpassthru($fp);

// For now I m just echoing the output as it is
echo $res;

?>
... It is really simple.

Is that only what fopen can do?. Hm! do you believe that we can do simple 'SOAP' webservices with fopen?. If you have seen lot of 'SOAP' messages, that will not be a problem to write a simple SOAP request with 'fopen'.

That is you can have a good control of your HTTP Request associating a stream context with 'fopen'. A simple SOAP request may only need few http headers and request XML wrapped with 'soap' headers as 'POST' data.
you can create a simple stream context with php standard function 'stream_context_create'.

Here is how you may use the 'fopen' with stream_context_create to do a POST http request.


<?php

$data = "Here is my POST data";

$opts = array(
'http'=>array(

'method'=>"POST",
'header'=>"User-Agent: My Own Http Client\r\n".
"Content-length: " . strlen($data)."\r\n",
'content' => $data

)
);

$context = stream_context_create($opts);

$fp = fopen($url, 'r', false, $context);


/* you got the pointer to $fp, use any function like fgets, freed to read the buffer */
?>

So if i use 'fopen' to do a SOAP request to call the same amazon web service, it will be like this..

<?php

$query = "TEST";
$catagory = "Books";
/* Use your own amazon key,
You can get it from http://aws.amazon.com */

$amazon_key = "your_amazon_key";


$soap_msg = <<<XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ItemSearch xmlns="http://webservices.amazon.com/AWSECommerceService/2007-10-29">

<SubscriptionId>${amazon_key}</SubscriptionId>
<Request>
<Keywords>{$query}</Keywords>

<SearchIndex>${catagory}</SearchIndex>
</Request>
</ItemSearch>
</soapenv:Body></soapenv:Envelope>

XML;

$opts = array(
'http'=>array(
'method'=>"POST",
'header'=>"User-Agent: fopen soap engine\r\n".
"Content-Type: text/xml;charset=UTF-8\r\n".
"SOAPAction: \"http://soap.amazon.com\"\r\n".
"Content-length: " . strlen($soap_msg)."\r\n",
'content' => $soap_msg

)
);

$context = stream_context_create($opts);

$fp = fopen("http://soap.amazon.com:80/onca/soap?Service=AWSECommerceService", 'r', false, $context);

$result = fpassthru($fp);

echo $resutl;

fclose($fp);


?>

Sunday, January 20, 2008

Resources for WSF/PHP developers

When you go to the Oxygen Tank you will find they have plenty of resources related to WSF/PHP project. But just to put references to all of them (including resources outside the Oxygen Tank) from one place, I thought to blog a list of resources, mentioning what, when and why you should pick them. Please add here, if I m missing anything.

1. WSF/PHP Manual
If you just now happened to heard about WSF/PHP, then this is the place you should go first. Even if you have some experience working with it, this is surely a place you will be regularly visiting. It will guide you from installing WSF/PHP to testing most of the features in very easy steps.
Some of the cool topics it covers are
  • Quick Start Guide for both providing and consuming web services
  • Using REST and SOAP
  • Attachment with MTOM/XOP
  • WS-Security with policies
2. WSF/PHP Documentation
Actually WSF/PHP Manual is a part of the WSF/PHP Documentation. In addition to the manual it contains Introduction which brief out the feature set and more importantly API Reference for WSF/PHP Classes. You will find this API reference is organized in a very structured manner with examples.

3. Articles, Tutorial & Demonstration
Oxygen Tanks provides many articles and tutorials for beginners of the PHP web Service development. And recently it is planned to add many demonstration that will guide users to do installation with slide shows. See the first one of it which present you how to install WSF/PHP with XAMPP on Windows.

4. User list mail archives
If you can't find the solution in any of above mentioned links, this is the most probable place you will find the answer. If you can not find that in there too, just don't hesitate to post it in the list. You will be able to subscribe for the list sending a mail to wsf-php-user-request@wso2.org with the subject subscribe. And there is no prohibition to check the dev mail archives of the project too.

5. Forum
If you don't like to subscribe to mailing list (in a case where you are not a regular user), then you have this place. You can check through the old forum topic or start a new topic mentioning your problem.

6. Blogs
There are several blogs that would give you new news about the WSF/PHP project. Here is some list of blogs that you may find useful.

7. Search Oxygen Tank
Are you tired of finding what you want from dozens of places, go to wso2.org and search for it. By the way you can reach to an advanced search page too.

8. Search Google
You trust Google more, then go there and search. Most probably you will be directed to the Oxygen Tank, but sometime with some more accuracy.

Ok, They are the places I know, that you can find lot of resources about WSF/PHP and mostly about web services in PHP in general. Hope this post will helpful to somebody to locate these resources.

Saturday, January 19, 2008

Mapping WSDL schema elements to PHP Classes

Since I talked about how you can deal with WSDLs using WSF/PHP in last two days, I thought of blogging a kind of a hidden feature of WSF/PHP related to WSDLs today.

When you are using WSF/PHP wsdl mode API in the client side, you can use classes to hold your data. That is simply you will be filling data in your class like you are creating an XML.

For an example,
<HelloWorld>
<name>Hiro</name>
</HelloWorld>
would map to the following PHP class,
class HelloWorld
{
public $name;
}
I will take the yesterdays (and the same used in day before yesterday) WSDL to explain a full example of use of this feature..


<?php

/*
* Client.php
*/


/* Class HelloWorld maps to the following schema part
* <xsd:element name="HelloWorld">
* <xsd:complexType>
* <xsd:sequence>
* <xsd:element name="name" type="xsd:string"/>
* </xsd:sequence>
* </xsd:complexType>
* </xsd:element>
*/


class HelloWorld
{
public $name;
}

/* Class HelloWordResponse maps to the following schema part
* <xsd:element name="HelloWorldResponse">
* <xsd:complexType>
* <xsd:sequence>
* <xsd:element name="return" type="xsd:string"/>
* </xsd:sequence>
* </xsd:complexType>
* </xsd:element>

*/

class HelloWorldResponse
{
public $return;
}

/*
* Additionally you have to create the class map
* (i.e. Schema element => PHP Class Name
*/



$class_map = array("HelloWorld"=> "HelloWorld",
"HelloWorldResponse"=> "HelloWorldResponse");



/* create the WSClient with the given WSDL and my service endpoint
Note: Here im overwriting the endpoint declared in the WSDL */

$wsclient = new WSClient( array(
"classmap" => $class_map,
"wsdl" => "http://localhost/Service_wsdl.php?wsdl"));


/* we need to take the proxy object to call the wsdl operation */
$proxy = $wsclient->getProxy();

/* prepare the input */

$input = new HelloWorld();


$input->name = "Hiro";

/* Right here I'm calling the HelloWorld function with
* argument as the HelloWorld instance
* Remeber in the WSDL we had "HelloWorld"
* operation with name argument */

$ret_val = $proxy->HelloWorld($input);


/* Retrive the response. Just to recall,
* our response is an instance of HelloWorldResponse */

echo $ret_val->return."\n";

?>

Friday, January 18, 2008

Tutorial2 - Hello World Using Web Service Framework for PHP with WSDL Generation

Yesterday I blogged a tutorial on how to write a Hello World Web Service Client and Service starting from a WSDL. So in order to follow that approach (Contract first, That is starting from a WSDL. I have described these terms in details here) you have to have a WSDL. Yes there are many tools which will help you generating WSDLs. But how if you can generate the WSDL from your PHP service itself.

In fact with WSF/PHP you can get it done easily. For the simplicity I will get the example service (the HelloWorld Service) I took yesterday.

First I write the service like following.

<?php
/**
* Service.php
*/



/* See how we put doc comment for the HelloWorld function */
/**
* First whatever your introduction to the function
* @param string $name
* @return string $return
*/

function HelloWorld($name)

{
/* Remember in the response we had 'return' element */
return array("return"=> "welcome ".$name."!");

}

/* Map of the service opertion "HelloWorld" to php functions "HelloWorld" */
$operations = array("HelloWorld" => "HelloWorld");


/* just tell your function parameters should be in mixed format,
that is here parameter will be the string with the name in it*/

$opParams = array("HelloWorld" => "MIXED");

/* Created the WSService */

$svr = new WSService(array(/* "wsdl" => "HelloWorld.wsdl", */ // we removed this line.
"bindingStyle"=>"doclit", // we added this line

"operations" => $operations,
"opParams" => $opParams));

/* Reply the client */

$svr->reply();

?>


Just note the doc comment in the service operation "HelloWorld"..
/**
* First whatever your introduction to the function
* @param string $name - Whatever the name mean
* @return string $return - Something to return
*/

It explain the set of input parameters and the return value with its type. In fact this give a human reader an idea how should somebody should use this operation. But here in this particular case we have put it there just to give the WSF/PHP WSDL Generator a hint about this function (like what are the input and return types)

So put this in a Apache web root and go the following url in the localhost from a browser,

http://localhost/Service.php?wsdl
and
http://localhost/Service.php?wsdl2

You will be able to retrieve the WSDL v 1.1 and WSDL v 2 for our service. Isn't that easy.


If you followed the yesterday my blog get the same client and just change the wsdl location to the new wsdl. (That is the one just typed in the browser)


<?php

/*
* Client.php
*/


/* create the WSClient with the given WSDL and my service endpoint
Note: Here im overwriting the endpoint declared in the WSDL */

$wsclient = new WSClient( array(
/* Here is my WSDL */
"wsdl" => "http://localhost/Service.php?wsdl2"));

/* we need to take the proxy object to call the wsdl operation */

$proxy = $wsclient->getProxy();

/* Right here I'm calling the HelloWorld function with argument "Hiro"
Remeber in the WSDL we had "HelloWorld" operation with name argument */

$ret_val = $proxy->HelloWorld(array("name" => "Hiro"));


/* Retrive the response. Just to recall, response had the element 'return' */
echo $ret_val["return"]."\n";

?>

So you are done. You don't need any explanation of what are in the WSDL to do this tutorial. Since in this case you know what you should call since the service is designed by you and you know PHP.

But some one else (some even you don't know) who want to consume your service may not understand PHP (Say he is a really Java fan), and even though he is PHP guy you should not show your PHP service code to the unknown consumers.

That is where WSDL comes in to the play. You can give the WSDL (in fact just generated from the PHP) and let them consume the service. Surely there are many libraries and tools in Java (or any other language) which understand the WSDL and interpret it that language, so the consumer will find very easy to consume your service.

Thursday, January 17, 2008

Tutorial - Hello World with WSDL Mode Using Web Service Framework for PHP

Web Service Framework for PHP (WSF/PHP) allows you to write web services and clients using WSDL. In there you are not writing the XML message manually, rather you only need to provide parameters and the framework generate the xml message for you. So this is a simple tutorial which allow you to write a Hellow World service and client from a WSDL.

Here is my WSDL.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:ns0="http://MyTest"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap
="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace="http://MyTest">


<wsdl:types>
<xs:schema xmlns:ns="http://MyTest"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://MyTest">


<xs:element name="HelloWorld">
<xs:complexType>
<xs:sequence>
<xs:element name="greet" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="HelloWorldResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="HelloWorldRequest">

<wsdl:part name="parameters" element="ns0:HelloWorld"/>
</wsdl:message>
<wsdl:message name="HelloWorldResponse">

<wsdl:part name="parameters" element="ns0:HelloWorldResponse"/>
</wsdl:message>
<wsdl:portType name="HelloWorldPortType">

<wsdl:operation name="HelloWorld">
<wsdl:input message="ns0:HelloWorldRequest"
wsaw:Action
="urn:HelloWorld"/>


<wsdl:output message="ns0:HelloWorldResponse"
wsaw:Action="urn:HelloWorldResponse"/>

</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="HelloWorldSOAP12Binding"
type
="ns0:HelloWorldPortType">

<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"
style
="document"/>


<wsdl:operation name="HelloWorld">
<soap12:operation
soapAction="urn:HelloWorld" style="document"/>


<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>

<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="HelloWorld">
<wsdl:port name="HelloWorldSOAP12port_http"
binding="ns0:HelloWorldSOAP12Binding">

<soap12:address
location
="http://localhost:8080/axis2/services/HelloWorld"/>

</wsdl:port>
</wsdl:service>
</wsdl:definitions>



Just don't worry about what it means, But to use this you may need a little knowledge of finding the operation name and finding the arguments that we have to set in order to generate the request XML.

First to understand what are the operations and arguments, just check the 'wsdl:portType' element.
  <wsdl:portType name="HelloWorldPortType">

<wsdl:operation name="HelloWorld">
<wsdl:input message="ns0:HelloWorldRequest" wsaw:Action="urn:HelloWorld"/>

<wsdl:output message="ns0:HelloWorldResponse" wsaw:Action="urn:HelloWorldResponse"/>
</wsdl:operation>
</wsdl:portType>


So you can see this has one operation with the name "HelloWorld" and it contains both input and output messages. Anyway this doesn't reveal the format of the message. In order to have a clue on that, you have to go one level up in the WSDL.

 <wsdl:message name="HelloWorldRequest">

<wsdl:part name="parameters" element="ns0:HelloWorld"/>
</wsdl:message>
<wsdl:message name="HelloWorldResponse">

<wsdl:part name="parameters" element="ns0:HelloWorldResponse"/>
</wsdl:message>


Oops!, you will see this again point to another upper level through the 'element' attribute. Actually It is where the schema of your message is shown. First we will check 'HelloWorld' element.
        <xs:element name="HelloWorld">
<xs:complexType>
<xs:sequence>
<xs:element name="greet" type="xs:string"/>

</xs:sequence>
</xs:complexType>
</xs:element>


Here is the schema of your "HelloWorld" XML, I can see it validate an XML like this..

<HelloWorld xmlns="the namespace">
<greet>Hiro</greet>
</HelloWorld>

Don't worry, here you dont' need to understand the XML. just keeping in mind that we have to provide the argument 'greet' when calling HelloWorld.

The same way we will can expect the response message.
<HelloWorldResponse xmlns="the namespace">
<return>Welcome Hiro!</return>
</HelloWorldReponse>
So it is all about the explanation of the WSDL. We will go to the real steps of the tutorial

Building the Provider of the Web Service.. Here I have done explanation inline in each line.

<?php
/**
* Service.php
*/


/* This is where your logic is
Remeber in the WSDL we had "HelloWorld" operation with name argument */

function HelloWorld($name)
{

/* Remember in the response we had 'return' element */
return array("return"=> "welcome ".$name."!");

}

/* Map of the service opertion "HelloWorld" to php functions "HelloWorld" */
$operations = array("HelloWorld" => "HelloWorld");


/* just tell your function parameters should be in mixed format,
that is here parameter will be the string with the name in it*/

$opParams = array("HelloWorld" => "MIXED");

/* Created the WSService */

$svr = new WSService(array("wsdl" => "HelloWorld.wsdl",
"operations" => $operations,
"opParams" => $opParams));


/* Reply the client */
$svr->reply();

?>


Then you may put that in the htdocs directory to deploy with the Apache Server. I put it that directly in the htdocs directory. So my service endpoint is
http://localhost/Service.php.

Remember you restart the Apache server after you did this..

Just go to the browser and type "http://localhost/Service.php". This will give you the list of deployed services and their operations. Confirm your service is in there.

Then start writing the PHP web service client ..


<?php

/*
* Client.php
*/


/* create the WSClient with the given WSDL and my service endpoint
Note: Here im overwriting the endpoint declared in the WSDL */

$wsclient = new WSClient( array(

"wsdl" => "HelloWorld.wsdl",
"to" => "http://localhost/Service.php"));

/* we need to take the proxy object to call the wsdl operation */

$proxy = $wsclient->getProxy();

/* Right here I'm calling the HelloWorld function with argument "Hiro"
Remeber in the WSDL we had "HelloWorld" operation with name argument */

$ret_val = $proxy->HelloWorld(array("name" => "Hiro"));


/* Retrive the response. Just to recall, response had the element 'return' */
echo $ret_val["return"]."\n";

?>

It is all coding you should do. Now just go to a command line and run

php Client.php

or go to the browser and type

http://localhost/Client.php

If you retrieve exactly what the server set, You are done.

Wednesday, January 16, 2008

Amazon Search with WSF/PHP Helper classes

You can do amazon search with the help of WSF/PHP helper classes which are bundled with Web service framework for PHP 1.2 release.

Here is a little demonstration how can you use this,,

<?php

require_once("wso2/amazon/AmazonClient.php");
$amazon_client = new AmazonClient("my amazon key");


$results = $amazon_client->itemSearch("My Book", "Books", 1);

foreach ($res["results"] as $result) {

echo $result["ItemAttributes"]["Author"]. "-";
echo $result["ItemAttributes"]["Title"]. "\n";

}

?>

Monday, January 14, 2008

PHP Helper classes bundled with Web Service Framework for PHP

In the new release of Web Service Framework for PHP, it bundles a set of PHP helper classes which allow you to access some of the popular public web service like Flickr, Yahoo and Amazon.

You can use this helper classes to access those services from your PHP applications
very easily.

The following is a set of code that I wrote for demonstrate the use of the Yahoo class with Yahoo NewsSearch Service operation.


require_once("wso2/yahoo/YahooClient.php");

$yahoo_client = new YahooClient("your_yahoo_id");


/* Search news for Presidential election */
$res = $yahoo_client->newsSearch("presidential election");


foreach ($res["results"] as $result) {

echo $result["Title"]." - ";
echo $result["Summary"]."\n";

}


Sunday, January 13, 2008

PHP Webservice consume from Flex

Yesterday I happened to write a very simple flex web service client which calls a PHP web services, while answering a post on WSO2 Oxygen Tanks Forum on Web service Framework for PHP. I thought I better share my little experience here. Please note I copied most of the code from Buddhika's and Colinrotherham's posts. Hope they will excuse me for publishing them here..

Our service is a greet service which just greet when you call it with your name. The final look of our simple application like this..












Well first forget the clientside, rather move to the server side. It will be written with Web Service Framework for PHP like following block.

  1 <?php
2
3 /** greet function
4 * @param string $name
5 * (map to xs:string)
6 * @return string $greetReturn
7 * (map to xs:string)
8 */

9
10
11 function greet($name)
12 {
13 $result = array ('greetReturn' => "Greetings, ".$name);
14
15 return $result;
16 }
17
18 $operations = array('greet' => 'greet');
19 $parameters = array('greet' => 'MIXED');
20
21 $service = new WSService(array
22 (
23 'operations' => $operations,
24 'opParams' => $parameters
25 ));
26
27 $service->reply();
28 ?>
29
As you can see we are putting doc comments on top of the service function inorder to generate the WSDL from it.. Then publish it with the web server in your computer.

And next we will go to the client. Here is my flex code.. Just make sure you have changed the url of the WSDL to the where actually you have hosted the PHP Service.

  1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
3 paddingBottom="0" paddingTop="0"
4 paddingLeft="0" paddingRight="0"
5 layout="vertical"
6 pageTitle="My Greeting Client">
7
8 <mx:Script>
9 <![CDATA[
10
11 import test.MyResponder;
12 import mx.rpc.soap.mxml.WebService;
13 import mx.rpc.AsyncToken;
14 import mx.rpc.events.FaultEvent;
15 import mx.rpc.AbstractService;
16 import mx.rpc.AsyncToken;
17 import mx.rpc.Responder;
18 import mx.utils.ArrayUtil;
19 import mx.rpc.IResponder;
20
21
22 private function callService():void
23 {
24 var webService:WebService;
25 webService = new WebService();
26 webService.wsdl = 'http://localhost/mytests/mails/greetService.php?wsdl';
27 webService.useProxy = false;
28 webService.showBusyCursor = true;
29
30 webService.loadWSDL();
31 var token:AsyncToken = AsyncToken(webService.greet(input.htmlText));
32
33 token.addResponder(new MyResponder(
34 function responseHanlder(data:Object):void
35 {
36 result.htmlText = data.result.toString();
37 }
38 ));
39
40 }
41 ]]>
42 </mx:Script>
43
44 <mx:Panel id="pnlMain" x="10" y="10" width="450" height="250"
45 layout="absolute" title="My Greeting Client">
46 <mx:TextArea x = "10" y="15" id="input" editable="true" width="400" height="50" />
47 <mx:TextArea x = "10" y="100" id="result" editable="false" width="400" height="50" />
48 <mx:Button x="10" y="170" label="Call WebService"
49 id="butJSDisplay" click="callService()"/>
50 </mx:Panel>
51
52 </mx:Application>

As you can see we are using class called MyResponder in order to handle the asynchronous call.
That willl be in the Test Package, so you will create a directory call 'Test' and put the MyResponder.as with the following content.

  1 package test
2 {
3
4 import mx.rpc.IResponder;
5
6 public class MyResponder implements IResponder
7 {
8 private var handler:Function;
9
10 public function MyResponder(ahandler:Function)
11 {
12 super();
13 this.handler = ahandler;
14 }
15 public function result(data:Object):void
16 {
17 handler(data);
18 }
19 public function fault(data:Object):void
20 {
21 handler(data);
22 }
23 }
24
25 }


Then you will need to compile this file (my_consumer.mxml) using mxml compiler in the Flex SDK.

mxmlc -use-network=true my_consumer.mxml

If this works, you will see a file my_consumer.swf which is a compiled flash file and you are done. But just one small thing, you have to embed this flash file inside some html code. Here is the conventional code for that.


  1 <!-- saved from url=(0014)about:internet -->
2 <html lang="en">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>My Project</title>
6 <style>
7 body { margin: 0px; overflow:hidden }
8 </style>
9 </head>
10
11 <body scroll='no'>
12 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
13 id="myproject" width="100%" height="100%"
14 codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">

15 <param name="movie" value="myproject.swf" />
16 <param name="quality" value="high" />
17 <param name="bgcolor" value="#869ca7" />
18 <!--<param name="allowScriptAccess" value="sameDomain" />
-->
19 <embed src="my_consumer.swf" quality="high" bgcolor="#869ca7"
20 width="100%" height="100%" name="myproject" align="middle"
21 play="true"
22 loop="false"
23 quality="high"
24 allowScriptAccess="sameDomain"
25 type="application/x-shockwave-flash"
26 pluginspage="http://www.adobe.com/go/getflashplayer">

27 </embed>
28 </object>
29 </body>
30 </html>


Looks like you can open the HTML from the browser and you are done. Yea but remember that your server has the crossdomain.xml and favicon.ico in the web server root directory. There are essential when you access a remote service from flex.

So that is all. Infact if you go to the forum thread, you may find attachments which actually contain the files describe here.