Archive

Posts Tagged ‘ActionScript’

Data Access with Flex 3

April 9th, 2009

dataaccesswithflexMy previous article on New features in MySQL 6.0 - Part I I hope you guys liked it. Now I’m writing Article on accessing external data through the Adobe Flex 3.0 which will explain you number of ways to access Java component like Java Server Pages, WebServices and Java classes with Adobe Flex.


Adobe Flex 3 data access components use remote procedure calls to interact with server side environment, such as Java, .NET and PHP, to provode data to Adobe Flex application and send data back to server side resources. In this article we will see how we can use Adobe Flex data access components in our Flex application.

  • HTTPService components
  • WebService components
  • RemoteObject components

Using HTTPService components:

HTTPService components are compatible with any kind of server technologies including Java Server Pages, PHP pages, Ruby on Rails, Java Servlets and ColdFusion Pages. In this article we will see how Adobe Flex HTTPService componet communicates with Java Server Pages

We can use a Flex HTTPService component in conjunction with a JSP page to load the external data in Flex application. We can call a JSP page with GET or POST to perform a quering the data. We can then format the resultant data in an XML structure and return the XML structure to the Flex application in the HTTP response. When the result has been returned to the Flex application, there number of user interface controls are available to display it.

To illustrate how this component is used,  suppose a Flex application calls a JSP page that retrieves data from external source. It formates data into XML format and returns XML to the Flex application, where it is bound to the dataProvider property of a DataGrid and displayed in the DataGrid control.

MXML code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:HTTPService id="httpService" url="catalog.jsp" resultFormat="e4x"
       result="resultHandler(event);" fault="faultHandler(event);"/>

    <mx:Script>
        <![CDATA[

            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;

            [Bindable]
            private var resultantData:XML;

            // Result handler - gets called after data is loaded.
            private function resultHandler(event:ResultEvent):void
            {
                resultantData = event.result as XML;
            }
            // Fault handler - displays the error.
            private function faultHandler(event:FaultEvent):void
            {
                Alert.show(event.fault.message, "Could not load external data");
            }

        ]]>
    </mx:Script>
    <mx:DataGrid dataProvider="{resultantData}" width="100%" height="100%"/>
    <mx:Button label="Fetch Data" click="httpService.send()"/>
</mx:Application>

The HTTPService’s send() method makes the call to the JSP page. This call is made in the click event of the Button in the MXML file.

The resultFormat property of the HTTPService component is set to object, so the data is sent back to the Flex application as a graph of ActionScript objects. This is the default value for the resultFormat property. Alternatively, you can use a result format of e4x to return data as an XMLList object on which you can perform ECMAScript for XML (E4X) operations. Switching the resultFormat property to e4x requires the following minor changes to the MXML code.

JSP code
The following code snippet shows the JSP page used in this example. This JSP page does not call a database directly. It gets its data from a Java class called ProductService, which in turn uses a Java class called Product to represent individual products.

<%@page import=”flex.samples.product.ProductService,
flex.samples.product.Product,
java.util.List”%>
<?xml version=”1.0″ encoding=”utf-8″?>
<catalog>
<%
ProductService srv = new ProductService();
List list = null;
list = srv.getProducts();
Product product;
for (int i=0; i<list.size(); i++)
{
product = (Product) list.get(i);
%>
<product productId=”<%= product.getProductId()%>”>
<name><%= product.getName() %></name>
<description><%= product.getDescription() %></description>
<price><%= product.getPrice() %></price>
<image><%= product.getImage() %></image>
<category><%= product.getCategory() %></category>
<qtyInStock><%= product.getQtyInStock() %></qtyInStock>
</product>
<%
}
%>
</catalog>

Using WebService components:

Flex applications can interact with web services that define their interfaces in a Web Services Description Language 1.1 (WSDL 1.1) document, which is available as a URL. WSDL is a standard format for describing the messages that a web service understands, the format of its responses to those messages, the protocols that the web service supports, and where to send messages. The Flex web service API generally supports Simple Object Access Protocol (SOAP) 1.1, XML Schema 1.0

Flex applications support web service requests and results that are formatted as SOAP messages. SOAP provides the definition of the XML-based format that you can use for exchanging structured and typed information between a web service client, such as a Flex application, and a web service.

In this example Flex application calls web service that queries the user from the database and returns data to Flex application, where it boud to dataProvider property of a DataGrid control and displayed on the screen.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” xmlns=”*” layout=”absolute”
creationComplete=”userRequest.fetchRecords()”>
<mx:Form x=”22″ y=”10″ width=”493″>
<mx:HBox>
<mx:Label text=”Username”/>
<mx:TextInput id=”username”/>
</mx:HBox>
<mx:HBox>
<mx:Label text=”Email Address”/>
<mx:TextInput id=”emailaddress”/>
</mx:HBox>
<mx:Button label=”Submit” click=”clickHandler()”/>
</mx:Form>
<mx:DataGrid id=”userRequest” x=”22″ y=”128″>
<mx:columns>
<mx:DataGridColumn headerText=”User ID” dataField=”USERID”/>
<mx:DataGridColumn headerText=”User Name” dataField=”USERNAME”/>
</mx:columns>
</mx:DataGrid>

<mx:TextInput x=”22″ y=”292″ id=”selectedemailaddress” text=”{userRequest.selectedItem.emailaddress}”/>
<mx:WebService id=”userRequest”
wsdl=”http://localhost:8080/example/getusers.cfc?wsdl”>

<mx:operation name=”fetchRecords” resultFormat=”object”
fault=”mx.controls.Alert.show(event.fault.faultString)”
result=”remotingCFCHandler(event)”/>
<mx:operation name=”insertRecord” result=”insertCFCHandler()”
fault=”mx.controls.Alert.show(event.fault.faultString)”/>
</mx:WebService>

<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;

private function remotingCFCHandler(e:ResultEvent):void
{
userRequest.dataProvider = e.result;
}

private function insertCFCHandler():void
{
webService.fetchRecords();
}
private function clickHandler():void
{
webService.insertRecord(username.text, emailaddress.text);
}
]]>
</mx:Script>
</mx:Application>

When the above MXML is loaded “webService.fetchRecords()” method is invoked, the path WSDL can be seen under <mx:WebService /> tag. In this example “fetchRecords” and “insertRecord” are the two operation which are provided by Web Service, results of operations are handled by function “remotingCFCHandler(event)” and  function “insertCFCHandler()” respectively. And faults are popuped using Alerts.

WSDL Document

<?xml version=”1.0″ encoding=”UTF-8″?>
<wsdl:definitions targetNamespace=”http://example” xmlns:apachesoap=”http://xml.apache.org/xml-soap” xmlns:impl=”http://example” xmlns:intf=”http://example” xmlns:soapenc=”http://schemas.xmlsoap.org/soap/encoding/” xmlns:tns1=”http://rpc.xml.coldfusion” xmlns:wsdl=”http://schemas.xmlsoap.org/wsdl/” xmlns:wsdlsoap=”http://schemas.xmlsoap.org/wsdl/soap/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<!–WSDL created by ColdFusion version 8,0,0,171651–>
<wsdl:types>
<schema targetNamespace=”http://rpc.xml.coldfusion” xmlns=”http://www.w3.org/2001/XMLSchema”>
<import namespace=”http://example”/>
<import namespace=”http://schemas.xmlsoap.org/soap/encoding/”/>
<complexType name=”CFCInvocationException”>
<sequence/>
</complexType>

<complexType name=”QueryBean”>
<sequence>
<element name=”columnList” nillable=”true” type=”impl:ArrayOf_xsd_string”/>
<element name=”data” nillable=”true” type=”impl:ArrayOfArrayOf_xsd_anyType”/>
</sequence>
</complexType>
</schema>
<schema targetNamespace=”http://example” xmlns=”http://www.w3.org/2001/XMLSchema”>
<import namespace=”http://rpc.xml.coldfusion”/>

<import namespace=”http://schemas.xmlsoap.org/soap/encoding/”/>
<complexType name=”ArrayOf_xsd_string”>
<complexContent>
<restriction base=”soapenc:Array”>
<attribute ref=”soapenc:arrayType” wsdl:arrayType=”xsd:string[]“/>
</restriction>
</complexContent>
</complexType>
<complexType name=”ArrayOfArrayOf_xsd_anyType”>

<complexContent>
<restriction base=”soapenc:Array”>
<attribute ref=”soapenc:arrayType” wsdl:arrayType=”xsd:anyType[][]“/>
</restriction>
</complexContent>
</complexType>
</schema>
</wsdl:types>

<wsdl:message name=”CFCInvocationException”>

<wsdl:part name=”fault” type=”tns1:CFCInvocationException”/>
</wsdl:message>
<wsdl:message name=”returnRecordsRequest”>
</wsdl:message>
<wsdl:message name=”insertRecordResponse”>
</wsdl:message>
<wsdl:message name=”returnRecordsResponse”>
<wsdl:part name=”returnRecordsReturn” type=”tns1:QueryBean”/>
</wsdl:message>
<wsdl:message name=”insertRecordRequest”>
<wsdl:part name=”username” type=”xsd:string”/>
<wsdl:part name=”emailaddress” type=”xsd:string”/>
</wsdl:message>
<wsdl:portType name=”returncfxml”>
<wsdl:operation name=”insertRecord” parameterOrder=”username emailaddress”>
<wsdl:input message=”impl:insertRecordRequest” name=”insertRecordRequest”/>
<wsdl:output message=”impl:insertRecordResponse” name=”insertRecordResponse”/>
<wsdl:fault message=”impl:CFCInvocationException” name=”CFCInvocationException”/>
</wsdl:operation>
<wsdl:operation name=”fetchRecords”>
<wsdl:input message=”impl:returnRecordsRequest” name=”returnRecordsRequest”/>
<wsdl:output message=”impl:returnRecordsResponse” name=”returnRecordsResponse”/>
<wsdl:fault message=”impl:CFCInvocationException” name=”CFCInvocationException”/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name=”returncfxml.cfcSoapBinding” type=”impl:returncfxml”>
<wsdlsoap:binding style=”rpc” transport=”http://schemas.xmlsoap.org/soap/http”/>
<wsdl:operation name=”insertRecord”>
<wsdlsoap:operation soapAction=”"/>
<wsdl:input name=”insertRecordRequest”>
<wsdlsoap:body encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”http://example” use=”encoded”/>
</wsdl:input>
<wsdl:output name=”insertRecordResponse”>
<wsdlsoap:body encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”http://example” use=”encoded”/>
</wsdl:output>
<wsdl:fault name=”CFCInvocationException”>
<wsdlsoap:fault encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” name=”CFCInvocationException” namespace=”http://example” use=”encoded”/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name=”fetchRecords”>
<wsdlsoap:operation soapAction=”"/>
<wsdl:input name=”returnRecordsRequest”>
<wsdlsoap:body encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”http://example” use=”encoded”/>
</wsdl:input>
<wsdl:output name=”returnRecordsResponse”>
<wsdlsoap:body encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”http://example” use=”encoded”/>
</wsdl:output>
<wsdl:fault name=”CFCInvocationException”>
<wsdlsoap:fault encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” name=”CFCInvocationException” namespace=”http://example” use=”encoded”/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name=”returncfxmlService”>
<wsdl:port binding=”impl:returncfxml.cfcSoapBinding” name=”returncfxml.cfc”>
<wsdlsoap:address location=”http://localhost:8500/example/getusers.cfc”/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

Using RemoteObject components:

We can use Flex RemoteObject component to call the methods of Java class or PHP and .NET objects by using third-party softweres such as the open source projects BlazeDS or Zend Framework, example in this article uses BlazeDS.

Java Class

package com.test;

import java.util.Date;

public class HelloWorld
{
private String userSaid;

public String repeat( String said )
{
this.userSaid = “Reply from server: ” + said;
return this.userSaid;
}

public String sayHello()
{
Date now = new Date();
return “Hello World ” + now;
}
}

MXML code

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”>
<mx:RemoteObject id=”myservice” fault=”faultHandler(event)” showBusyCursor=”true” destination=”Hello”>
<mx:method name=”sayHello” result=”resultHandler(event)” />
<mx:method name=”repeat” result=”resultHandler(event)” />
</mx:RemoteObject>
<mx:Script>
<![CDATA[
import mx.managers.CursorManager;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
private function faultHandler(fault:FaultEvent):void
{
CursorManager.removeBusyCursor();
result_text.text = "code:\n" + fault.fault.faultCode + "\n\nMessage:\n" + fault.fault.faultString + "\n\nDetail:\n" + fault.fault.faultDetail;
}
private function resultHandler(evt:ResultEvent):void
{
result_text.text = evt.message.body.toString(); // same as: evt.result.toString();
}
]]>
</mx:Script>
<mx:Button x=”250″ y=”157″ label=”sayHello” width=”79″ click=”myservice.getOperation(’sayHello’).send();”/>
<mx:Button x=”250″ y=”187″ label=”Repeat” click=”myservice.getOperation(’repeat’).send(myText.text); “/>
<mx:TextArea x=”10″ y=”36″ width=”319″ height=”113″ id=”result_text”/>
<mx:Label x=”10″ y=”10″ text=”Result:”/>
<mx:TextInput x=”82″ y=”187″ id=”myText” text=”Sent to Server”/>
</mx:Application>

To configure BlaseDS on server side, you need to extend a BlazeDS configuration file to enable the Java service to be accessed later from the Flex client. Open the “remoting-config.xml” file in the project folder “FlexSampleWeb\WebRoot\WEB-INF\flex” and overwrite the content with the following:

<?xml version=”1.0″ encoding=”UTF-8″?>
<service id=”remoting-service”
class=”flex.messaging.services.RemotingService”>

<adapters>
<adapter-definition id=”java-object” class=”flex.messaging.services.remoting.adapters.JavaAdapter” default=”true”/>
</adapters>

<default-channels>
<channel ref=”my-amf”/>
</default-channels>

<!– Flex Demo application –>

<destination id=”Hello”>
<properties>
<source>com.test.HelloWorld</source>
</properties>
</destination>

</service>

The destination block that is identified by the id Hello is linked to Java class HelloWorld.

Summary

I hope you have enjoyed this article. I will be writing many more articles on Adobe Flex 3 and ActionScript comming week. Please check back my online journal for the interesting tips and articles about MySql and other latest technologies like Flex 3.0, Java/J2EE,ect.

Source Adobe Flex Official Site

S.Chandru Adobe Flex, Java , , , , , , ,