Flex 4 Creatingdatadrivenapps
Flex 4 Creatingdatadrivenapps
ADOBE FLEX 4
® ®
Contents
Chapter 1: Accessing data services overview
Accessing remote data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Compare data access in Flex to other methodologies ................................................................... 2
Access data services with Flash Builder ................................................................................. 4
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
REST-style services
Another common name for an HTTP service is a REST-style web service. REST stands for Representational State
Transfer, an architectural style for distributed hypermedia systems.
For REST-style services, you use a server resource such as a PHP page, JavaServer Page (JSP) or servlet, or ColdFusion
page that receives a POST or GET request from an application using the HTTPService component. That server
resource then accesses a database using whatever means are traditional to the particular server technology.
The results of data access can be formatted as XML instead of HTML, as might be typical with the server technology,
and returned as the response to the application. Flex, Adobe Flash Player, and Adobe AIR have excellent XML-
handling capabilities that let you manipulate the data for display in the application’s user interface. REST-style services
provide an easy way to access a server resource without a more formalized API such as those provided by web services
or remote object services. These services can be implemented using any number of server technologies that can get an
HTTP request and return XML as the response.
For more information about REST, see Representational State Transfer (REST) chapter of Architectural Styles and the
Design of Network-based Software Architectures by Roy Thomas Fielding.
Web services
SOAP-compliant web services are a standardized type of REST-style service. Rather than accessing a PHP, JSP, or
ColdFusion page specifically, an application accesses a web service endpoint. Based on published specifications, a web
service knows the format in which the data was sent and how to format a response.
Many server technologies provide the ability to interact with applications as web services. Because web services comply
with a standard, you don't need to know the implementation details of the code with which an application interacts.
This is useful for applications, such as business-to-business applications, that require a high degree of abstraction.
However, SOAP is often verbose and heavy across the wire, which can result in higher client-side memory
requirements and processing time than working with informal REST-style services.
<?xml version="1.0"?>
<!-- fds\rpc\RPCIntroExample2.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<!-- Declare a WebService component (the specified WSDL URL is not functional). -->
<mx:WebService id="WeatherService"
destination="wsDest"/>
<mx:TextInput id="input"/>
</mx:Application>
Compare this Flex example to the following example, which shows JSP code for calling a web service using a JSP
custom tag. When a user requests the JSP, the web service request is made on the server instead of on the client. The
result is used to generate content in the HTML page. The application server regenerates the entire HTML page before
sending it back to the user's web browser.
<%@ taglib prefix="web" uri="webservicetag" %>
To get similar functionality in Flex, you use an HTTPService, a web service, or a RemoteObject component to call a
server-side object that returns results from a data source.
For applications that updates several records, you can implement data management features. Data management
allows you to update all changed records simultaneously. Data management also provides undo operations to revert
changes.
4 Run the application and monitor the data flow.
Once the application is complete you run the application to view it in operation. Use the Flash Builder Network
Monitor to view data passed between the application and the service. The Network Monitor is useful for diagnosing
errors and analyzing performance.
Flash Builder also provides robust debugging and profiling environments.
See “Building data-centric applications with Flash Builder” on page 9 for more information.
Note: Although Flash Builder uses the Zend AMF framework, you are not required to use Zend components when
creating PHP services. Although Zend components work well with Flash Builder, you can also use any PHP development
environment for creating services.
Network Monitor
The Network Monitor is available in Flash Builder from the Flex Debugging Perspective. The monitor must be enabled
before it can be used to monitor data. Refer to Network Monitor for details about enabling and using the Network
Monitor.
ColdFusion Scripts
Use the following script, tester.cfm, to dump a call to a function.
<!--- tester.cfm --->
<cfobject component="EmployeeService" name="o"/>
<cfdump var="#o.getAllItems()#">
In tester2.cfm, you specify the method and arguments to call in the URL.
<p>Result:
<cfif isDefined("r")>
<cfdump var="#r#">
<cfelse>
(no result)
</cfif>
For example, call the getItemID method in EmployeeService with the following URL:
http://localhost/tester2.cfm?EmployeeService&method=getItemId&id=12
tester3.cfm writes a log that records calls to operations and dumps the input arguments using cfdump.
<!--- tester3.cfm --->
<cfsavecontent variable="d"><cfdump var="#arguments#"></cfsavecontent>
<cffile action="append"
file="#getDirectoryFromPath(getCurrentTemplatePath())#MyServiceLog.htm"
output="<p>#now()# operationName #d#">
PHP Scripts
Use the following script, tester.php, to dump a call to a function.
<pre>
<?php
include('MyService.php');
$o = new MyService();
var_dump($o->getAllItems());
?>
</pre>
Add the following code to your PHP service to log messages during code execution.
$message = 'updateItem: '.$item["id"];
$log_file = '/Users/me/Desktop/myservice.log';
error_log(date('d/m/Y H:i:s').' '.$message.PHP_EOL, 3, $log_file);
Add the following code to your PHP service to enable dumping to a log file:
ob_start();
var_dump($item);
$result = ob_get_contents();
ob_end_clean();
• Web services
• HTTP services
• BlazeDS
• Web services
• HTTP services
• HTTP services
ASP.NET
• HTTP services
For more information about creating Flex projects, see Working with Projects.
Note: You are not required to use Zend components when creating PHP services. Although Zend components work well
with Flash Builder, you can use any PHP development environment for creating services.
Before connecting to a PHP data service, you must first create a server project for PHP and make that the active project.
The data service must be available under the web root you specified when creating the project. All applications in the
project have access to the remote service.
Note: When specifying parameters, include values for the parameters. You can modify the values for the
parameters when configuring service operations.
7 Specify POST operations for the service:
• Specify a name for the POST operation.
• Specify POST for the method.
• Specify the Content Type for the POST operation.
• Add parameters for the POST operation.
8 (Optional) Modify the generated package name for the service.
9 Click Finish.
Flash Builder adds the HTTP service to the Data/Services view.
Expand the service to view the available operations.
After connecting to the HTTP service, configure the return type for the operation. See “Configuring return types for
a data service operation” on page 17 for details.
Controls
Flex provides a rich set of user-interface components such as Button, TextArea, and ComboBox controls. You place
controls in containers. Containers are user-interface components that provide a hierarchical structure for controls and
other containers.
Flex provides various data-driven controls that are ideal for displaying sets of data in lists, tables, or trees.
Data Controls
DataGrid
AdvancedDataGrid
OLAPDataGrid
List
TileList
Tree
2 Drag an operation from the Data/Services View onto the DataGrid component.
The DataGrid component changes to show the fields retrieved from the database.
3 Customize the display of the DataGrid.
4 Save and run the application.
Form Description
When generating Forms, specify which fields to include and whether to make the Form editable. You can also specify
the type of user interface control to represent the Form items.
This procedure shows how to generate a Form for a service call. The procedure for generating other types of Forms are
similar.
1 There are several ways to run the Generate Form wizard:
• From the Data/Service View, select an operation from the context menu. Select Generate Form.
• From the Flash Builder Data menu, select Generate Form or Generate Details Form
• Select a Data Control in Design View. From the context menu, select Generate Details Form
2 In the Generate Form wizard, select Generate Form for Service Call.
3 Select New Service Call, then specify the Service and Service Operation.
4 Configure the return type (or change the return type) for the selected operation.
The return type for the operation must be configured before you can generate the Form. If you previously
configured a return type, you have the option to change the return type.
See “Configuring return types for a data service operation” on page 17.
5 Specify whether to include Forms for input parameters and return type.
6 Specify whether to make the Form editable. Click Next.
7 In the Property control Mapping dialog, select which fields to include in the Form and the type of control to
represent the data.
8 Click Finish.
When you run the application, once the DataGrid has been created it populates itself with data retrieved from the
service.
You can accept the generated event handlers or replace them with others according to your needs. For example, you
can replace the creationComplete event handler on the DataGrid with a creationComplete handler on the Application.
You can also generate or create event handlers for Controls that accept user input, such as Buttons or Text. Do either
of the following to generate event handlers:
• From the Data/Services view, drag an operation onto the Control.
Flash Builder generates an event handler for the default event for the component. For example, for a Button, the
event handler would be the Click event.
• In Design View, select the Control and then in the Property Inspector, click the generate event icon.
Flash Builder opens the Source View of the editor and generates a stub for the event handler.
Fill in the remaining code for the event handler. Flash Builder provides Content Assist to help you code the event
handler.
Boolean[]
Date
Date[]
int
int[]
Number
Number[]
String
String[]
CustomType[]
Typically, you define custom data types for service operations that return complex data. For example, if you are
retrieving records from an employee database, then you would define the return type as Employee. In this case, the
custom data type for Employee would contain entries for each field in the record, as listed in the following table:
Employee Custom Data Type
emp_no Number
first_name String
last_name String
hire_date Date
birth_date Date
Configuring the return type for data from a PHP or ColdFusion service
To configure the return type, Flash Builder samples the data returned by an operation. Then you define or specify a
data type.
This procedure assumes that you have already connected to a remote data service.
1 In the Data/Services view, from the context menu for an operation, select Configure Return Type.
2 In the Configure Operation Return Type dialog, specify either a name for a new custom type or select an existing type.
You can select a data type from the drop-down list, or define a custom data type for the returned data.
For example, if you are returning a list of employees with associated data, then you might define the return type as
Employee.
3 If you select an existing data type or a previously defined data type that does not need to be updated, click Finish.
4 If you are defining a new data type, or are updating a previously defined data type, click Next.
If the data returned is not what you expect, or you encounter errors, click Cancel. Modify the implementation of
the service. If you modified the signature or return type, refresh the service. Then try again.
Note: When troubleshooting the implementation of the service, it is often easier to write test scripts that access the
service from a web browser. Analyze the results of those scripts to troubleshoot the service implementation. For
information on test scripts, see Debugging applications for remote services.
5 View and edit the properties of the returned data and click Finish.
For example, suppose you want to access a database that has 10,000 records and then display the data in a DataGrid
that has 20 rows. You can implement a paging operation to fetch the rows in 20 set increments. When the user requests
additional data (scrolling in the DataGrid), the next page of records is fetched and displayed.
Data management In Flash Builder, data management is the synchronization of updates to data on the server from
the client application. Using data management, you can modify one or more items in a client application without
making any updates to the server. You then commit all the changes to the server with one operation. You can also
revert the modifications without updating any data.
Data management involves coordinating several operations (create, get, update, delete) to respond to events from the
client application, such as updating an Employee record.
Enabling paging
To enable paging your data service must implement a function with the following signature:
getItems_paged(startIndex:Number, numItems:Number): myDataType
function name You can use any valid name for the function.
The data type for startIndex should be defined as Number in the client
operation.
The data type for numItems should be defined as Number in the client
operation.
When implementing paging from a service, you can also implement a count() operation. A count() operation returns
the number of items returned from the service. The count operation must implement the following signature:
count(): Number
function name You can use any valid name for the function.
Flex uses the count operation to properly display user interface components that retrieve large data sets. For example,
the count operation helps determine the thumb size for a scroll bar of a DataGrid.
Some remote services do not provide a count operation. Paging still works without a count operation, but the control
displaying the paged data might not properly represent the size of the data set.
countFiltered(filterParam1:String, filterParam2:String)
Here is a code snippet of a getItems_pagedFiltered() function that is implemented in PHP. The code snippet shows
how to use the optional filter parameter.
get_Items_paged($expression, $startIndex, $numItems) {
. . .
SELECT * from employees where name LIKE $expression LIMIT $startIndex, $numItems;
. . .
}
2 If you have not previously identified a unique key for your data type, specify the attributes that uniquely identify an
instance of this data type. Click Next.
Typically, this attribute is the primary key.
3 Specify the count() operation. Click Finish.
Paging is now enabled for that operation.
In Data/Services View, the signature of the function that implements paging no longer includes the startIndex and
numItems parameters. These values are now dynamically added based on the user interface component that
displays the paged data.
function name You can use any valid name for the function.
itemID A unique identifier for the item, usually the primary key in the database.
myDataType The data type of the item available from the data service. Typically, you define a
custom data type when retrieving data from a service.
Service classes
Use the Service Wizard to connect to a data service. When you connect to a service, Flash Builder generates an
ActionScript class file that provides access to the service operations. The generated class extends the
RemoteObjectServiceWrapper class.
Flash Builder bases the name of the generated class file on the name you provided for the service in the Service Wizard.
By default, Flash Builder places this class in a package under src. The name of the package is based on the service name.
For example, Flash Builder generates the following ActionScript classes for an EmployeeService class.
- project
|
- src
|
+ (default package)
|
- services.employeeservice
|
- _Super_EmployeeService.as
|
- EmployeeService.as
The super class contains the implementation for the EmployeeService class.
Never edit the super class, which is a generated class. Modifications you make to the super class can be overwritten.
Any changes you make to the implementation might result in undefined behavior.
In this example, use EmployeeService.as to extend the generated super class and add your implementation.
- project
|
- src
|
+ (default package)
|
- services.employeeservice
|
- _Super_Employee.as
|
- Employee.as
The super class contains the implementation for the Employee custom data type.
Never edit the super class, which is a generated class. Modifications you make to the super class can be overwritten.
Any changes you make to the implementation might result in undefined behavior.
In this example, use Employee.as to extend the generated super class and add your implementation.
Declarations tag
A Declarations tag is an MXML element that declares non-default, non-visual properties of the current class. When
binding a service operation to a user interface, Flash Builder generates a Declarations tag containing a CallResponder
and a service tag. The CallResponder and generated service class are properties of the container element, which is
usually the Application tag.
The following example shows a Declarations tag providing access to a remote EmployeeService:
<fx:Declarations>
<s:CallResponder id="getAllItemsResult"/>
<employeesvc:EmployeeSvc id="employeeSvc" destination="ColdFusion"
endpoint="http://localhost:8500/flex2gateway/"
fault="Alert.show(event.fault.faultString)" showBusyCursor="true"
source="EmployeeService.EmployeeSvc"/>
</fx:Declarations>
Call Responder
A CallResponder manages results for calls made to a service. It contains a token property that is set to the Async token
returned by a service call. The CallResponder also contains a lastResult property, which is set to the last successful
result from the service call. You add event handlers to the CallResponder to provide access to the data returned
through the lastResult property.
When Flash Builder generates a CallResponder, it generates an id property based on the name of the service operation
to which it is bound. The following code sample shows CallResponders for two operations of an EmployeeService. The
getAllItems operation is bound to the creationComplete event handler for a DataGrid. The delete operation is bound
to the selected item in the DataGrid. The DataGrid displays the items retrieved from the getAllItems service call
immediately after is created. The Delete Item Button control removes the selected record in the DataGrid from the
database.
<fx:Declarations>
<s:CallResponder id="getAllItemsResult"/>
<employeeservice:EmployeeService id="employeeService" destination="ColdFusion"
endpoint="http://localhost:8500/flex2gateway/"
fault="Alert.show(event.fault.faultString)"
showBusyCursor="true" source="CodeGenCF.CodeGenSvc"/>
<s:CallResponder id="deleteItemResult"/>
</fx:Declarations>
<mx:DataGrid id="dg" editable="true"
creationComplete="getAllItemsResult.token =
employeeService.getAllItems()"dataProvider="{getAllItemsResult.lastResult}">
<mx:columns>
<mx:DataGridColumn headerText="emp_no" dataField="emp_no"/>
<mx:DataGridColumn headerText="last_name" dataField="last_name"/>
<mx:DataGridColumn headerText="hire_date" dataField="hire_date"/>
</mx:columns>
</mx:DataGrid>
<s:Button label="Delete Item"
click="deleteItemResult.token = employeeService.deleteItem(dg.selectedItem.emp_no)"/>
Event handlers
When you bind a service operation to a user interface component, Flash Builder generates an inline event handler for
the CallResponder. The event handler manages the results of the operation. You can also create an event handler in an
ActionScript code block, and reference that event handler from a property of a user interface component.
Typically, you populate controls such as Lists and DataGrids with data returned from a service. Flash Builder, by
default, generates a creationComplete event handler for the control that fires immediately after the control is created.
For other controls, Flash Builder generates a handler for the control’s default event. For example, for a Button, Flash
Builder generates an event for the Button’s click event.
Flash Builder generates inline event handlers. The ActionScript code for the event handler is set directly in the event
property of the control. The following example shows the generated creation complete event handler for a DataGrid:
<mx:DataGrid id="dg" editable="true"
creationComplete="getAllItemsResult.token = employeeService.getAllItems()"
dataProvider="{getAllItemsResult.lastResult}">
<mx:columns>
<mx:DataGridColumn headerText="emp_no" dataField="emp_no"/>
<mx:DataGridColumn headerText="last_name" dataField="last_name"/>
<mx:DataGridColumn headerText="hire_date" dataField="hire_date"/>
</mx:columns>
</mx:DataGrid>
You can also create event handlers in ActionScript blocks and reference the event handler from the event property of
the control. The following example shows the same event handler for a DataGrid implemented in an ActionScript
block.
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.Alert;
]]>
</fx:Script>
. . .
<mx:DataGrid id="dg"
creationComplete="dg_creationCompleteHandler(event)"
dataProvider="{getAllItemsResult.lastResult}">
<mx:columns>
<mx:DataGridColumn headerText="emp_no" dataField="emp_no"/>
<mx:DataGridColumn headerText="last_name" dataField="last_name"/>
<mx:DataGridColumn headerText="hire_date" dataField="hire_date"/>
</mx:columns>
</mx:DataGrid>
You can also generate event handlers for controls that respond to user events, such as Buttons. The following example
shows a generated event handler for a Button that populates a DataGrid:
<s:Button label="Delete Item" click="deleteItemResult.token =
employeeService.deleteItem(dg.selectedItem.emp_no)"/>
You can also implement the event handler for the Button in an ActionScript block:
<fx:Script>
<![CDATA[
import mx.controls.Alert;
]]>
</fx:Script>
. . .
Data binding
Flash Builder generates code that binds the data returned from a service operation to the user interface control that
displays the data. The following example code that Flash Builder generates to populate a DataGrid control. The
getAllItems operation returns a set of employee records for the custom data type, Employee.
The dataProvider property of the DataGrid is bound to the results stored in the CallResponder, getAllItemsResult.
Flash Builder automatically updates the DataGrid with DataGridColumns corresponding to each field returned for an
Employee record. The headerText and dataField properties of each column are set according to the data returned in
an Employee record.
<mx:DataGrid creationComplete="datagrid1_creationCompleteHandler(event)"
dataProvider="{getAllItemsResult.lastResult}" editable="true">
<mx:columns>
<mx:DataGridColumn headerText="gender" dataField="gender"/>
<mx:DataGridColumn headerText="emp_no" dataField="emp_no"/>
<mx:DataGridColumn headerText="birth_date" dataField="birth_date"/>
<mx:DataGridColumn headerText="last_name" dataField="last_name"/>
<mx:DataGridColumn headerText="hire_date" dataField="hire_date"/>
<mx:DataGridColumn headerText="first_name" dataField="first_name"/>
</mx:columns>
</mx:DataGrid>
You can also call the commit method directly from the employeeService instance. Calling the commit method directly
from the service instance commits all changes for all managed data types.
employeeService.commit();
Note: You cannot call revertChanges directly from the service instance.
Deploying applications
XXXXXXXXXXXXXXXXXXXXXXXXX
MXML code
The Flex application in the following example calls a PHP page with the POST method. The PHP page queries a
MySQL database table called users. It formats the query results as XML and returns the XML to the Flex application,
where it is bound to the dataProvider property of a DataGrid control and displayed in the DataGrid control. The
Flex application also sends the user name and e-mail address of new users to the PHP page, which performs an insert
into the user database table.
The HTTPService’s send() method makes the call to the PHP page. This call is made in the send_data() method in
the Script block of 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 resultFormat 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.
Note: If the result format is e4x, you do not include the root node of the XML structure in the dot notation when binding
to the DataGrid.
The XML returned in this example contains no namespace information. For information about working with XML
that does contain namespaces, see “Handling results as XML with the E4X result format” on page 84.
...
<mx:DataGrid id="dgUserRequest" x="22" y="128" dataProvider="{userRequest.lastResult.user}">
...
<mx:HTTPService id="userRequest" url="http://server/myproj/request_post2.php"
useProxy="false" method="POST" resultFormat="e4x">
...
When using the e4x result format, you can optionally bind the lastResult property to an XMLListCollection object
and then bind that object to the DataGrid.dataProvider property, as the following code snippet shows:
...
<mx:XMLListCollection id="xc"
source="{userRequest.lastResult.user}"/>
PHP code
This application calls the following PHP page. This PHP code performs SQL database inserts and queries, and returns
query results to the Flex application in an XML structure.
<?php
define( "DATABASE_SERVER", "servername" );
define( "DATABASE_USERNAME", "username" );
define( "DATABASE_PASSWORD", "password" );
define( "DATABASE_NAME", "sample" );
mysql_select_db( DATABASE_NAME );
$Return = "<users>";
MXML code
The Flex application in the following example calls a ColdFusion page with the POST method. The ColdFusion page
queries a MySQL database table called users. It formats the query results as XML and returns the XML to the Flex
application, where it is bound to the dataProvider property of a DataGrid control and displayed in the DataGrid
control. The Flex application also sends the user name and e-mail address of new users to the ColdFusion page, which
performs an insert into the user database table.
The HTTPService’s send() method makes the call to the ColdFusion page. This call is made in the send_data()
method in the Script block of 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.
Note: If the result format is e4x, you do not include the root node of the XML structure in the dot notation when binding
to the DataGrid.
The XML returned in this example contains no namespace information. For information about working with XML
that does contain namespaces, see “Handling results as XML with the E4X result format” on page 84.
...
<mx:DataGrid id="dgUserRequest" x="22" y="128" dataProvider="{userRequest.lastResult.user}">
...
<mx:HTTPService id="userRequest" url="http://server:8500/flexapp/returncfxml.cfm"
useProxy="false" method="POST" resultFormat="e4x">
...
When using the e4x result format, you can optionally bind the lastResult property to an XMLListCollection object
and then bind that object to the DataGrid dataProvider property, as the following code snippet shows:
...
<mx:XMLListCollection id="xc"
source="{userRequest.lastResult.user}"/>
<mx:DataGrid id="dgUserRequest" x="22" y="128" dataProvider="{xc}">
...
SQL script
The ColdFusion code for this application uses a database table called users in a MySQL database called sample. The
following MySQL script creates the table:
CREATE TABLE `users` (
`userid` int(10) unsigned NOT NULL auto_increment,
`username` varchar(255) collate latin1_general_ci NOT NULL,
`emailaddress` varchar(255) collate latin1_general_ci NOT NULL,
PRIMARY KEY (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=3 ;
ColdFusion code
This application calls the following ColdFusion page. This ColdFusion code performs SQL database inserts and
queries, and returns query results to the Flex application. The ColdFusion page uses the cfquery tag to insert data into
the database and query the database, and it uses the cfxml tag to format the query results in an XML structure.
<cfprocessingdirective pageencoding = "utf-8" suppressWhiteSpace = "Yes">
<cfif isDefined("username") and isDefined("emailaddress") and username NEQ "">
<cfquery name="addempinfo" datasource="sample">
INSERT INTO users (username, emailaddress) VALUES (
<cfqueryparam value="#username#" cfsqltype="CF_SQL_VARCHAR" maxlength="255">,
<cfqueryparam value="#emailaddress#" cfsqltype="CF_SQL_VARCHAR" maxlength="255"> )
</cfquery>
</cfif>
<cfquery name="alluserinfo" datasource="sample">
SELECT userid, username, emailaddress FROM users
</cfquery>
<cfxml variable="userXML">
<users>
<cfloop query="alluserinfo">
<cfoutput>
<user>
<userid>#toString(userid)#</userid>
<username>#username#</username>
<emailaddress>#emailaddress#</emailaddress>
</user>
</cfoutput>
</cfloop>
</users>
</cfxml>
<cfoutput>#userXML#</cfoutput>
</cfprocessingdirective>
MXML code
The Flex application in the following example calls a JSP page that retrieves data from a SQL database. It formats
database query results as XML and returns the XML to the Flex application, where it is bound to the dataProvider
property of a DataGrid control and displayed in the DataGrid control.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
</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.
Note: If the result format is e4x, you do not include the root node of the XML structure in the dot notation when binding
to the DataGrid.
The XML returned in this example contains no namespace information. For information about working with XML
that does contain namespaces, see “Handling results as XML with the E4X result format” on page 84.
...
<mx:HTTPService id="srv" url="catalog.jsp" resultFormat="e4x"/>
...
<mx:DataGrid dataProvider="{srv.lastResult.product}" width="100%" height="100%"/>
When using the e4x result format, you can optionally bind the lastResult property to an XMLListCollection object
and then bind that object to the DataGrid.dataProvider property:
...
<mx:XMLListCollection id="xc"
source="{userRequest.lastResult.product}"/>
JSP code
The following example shows the JSP page used in this application. 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>
<?xml version="1.0"?>
<!-- fds\rpc\HttpServiceInAS.mxml. Compiles -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="10">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.http.HTTPService;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
If you are not using LiveCycle Data Services ES or BlazeDS, you can access web services in the same domain as your
Flex application or use a crossdomain.xml (cross-domain policy) file that allows access from your application's domain
must be installed on the web server hosting the RPC service.
For API reference information about the WebService component, see mx.rpc.soap.mxml.WebService. For
information about data type mapping between Flex and web services, see
http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=kb401841.
MXML code
The Flex application in the following example calls a web service that queries a SQL database table called users and
returns data to the Flex application, where it is bound to the dataProvider property of a DataGrid control and
displayed in the DataGrid control. The Flex application also sends the user name and e-mail address of new users to
the web service, which performs an insert into the user database table. The back-end implementation of the web service
is a ColdFusion component; the same ColdFusion component is accessed as a remote object in “Using RemoteObject
components” on page 53.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute"
creationComplete="userRequest.returnRecords()">
<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="dgUserRequest" 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:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
WSDL document
The following example shows the WSDL document that defines the API of the web service:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://flexapp"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://flexapp" xmlns:intf="http://flexapp"
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://flexapp"/>
<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://flexapp" 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">
<?xml version="1.0"?>
<!-- fds\rpc\WebServiceInAS.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.rpc.soap.WebService;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
private var ws:WebService;
public function useWebService(intArg:int, strArg:String):void {
ws = new WebService();
ws.wsdl="http://myserver:8500/flexapp/app1.cfc?wsdl";
ws.echoArgs.addEventListener("result", echoResultHandler);
ws.addEventListener("fault", faultHandler);
ws.loadWSDL();
ws.echoArgs(intArg, strArg);
}
Tag Description
<binding> Specifies the protocol that clients, such as Flex applications, use to communicate with a web service. Bindings exist for
SOAP, HTTP GET, HTTP POST, and MIME. Flex supports the SOAP binding only.
<fault> Specifies an error value that is returned as a result of a problem processing a message.
<input> Specifies a message that a client, such as a Flex application, sends to a web service.
Tag Description
<output> Specifies a message that the web service sends to a web service client, such as a Flex application.
<port> Specifies a web service endpoint, which specifies an association between a binding and a network address.
<service> Defines a collection of <port> tags. Each service maps to one <portType> tag and specifies different ways to access
the operations in that <portType> tag.
The style property of the associated <soap:binding> tag determines the operation style. In this example, the style
is document.
Any operation in a service can specify the same style or override the style that is specified for the port associated with
the service, as the following example shows:
<operation name="SendMSN">
<soap:operation soapAction="http://www.bindingpoint.com/ws/imalert/
SendMSN"style="document"/>
addHeader(header:mx.rpc.soap.SOAPHeader):void
To create the QName object in the first parameter of the SOAPHeader() method, use the following constructor:
QName(uri:String, localName:String)
The content parameter of the SOAPHeader() constructor is a set of name-value pairs based on the following format:
{name1:value1, name2:value2}
The addSimpleHeader() method is a shortcut for a single name-value SOAP header. When you use the
addSimpleHeader() method, you create SOAPHeader and QName objects in parameters of the method. The
addSimpleHeader() method has the following signature:
• headerValue is the value of the header. This can be a string if it is a simple value, an object that will undergo basic
XML encoding, or XML if you want to specify the header XML yourself.
The code in the following example shows how to use the addHeader() method and the addSimpleHeader()
method to add a SOAP header. The methods are called in an event listener function called headers, and the event
listener is assigned in the load property of an <mx:WebService> tag:
<?xml version="1.0"?>
<!-- fds\rpc\WebServiceAddHeader.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" height="600">
<mx:WebService id="ws" wsdl="http://myserver:8500/flexapp/app1.cfc?wsdl"
load="headers();"/>
<mx:Script>
<![CDATA[
import mx.rpc.soap.SOAPHeader;
private var header1:SOAPHeader;
private var header2:SOAPHeader;
public function headers():void {
<?xml version="1.0"?>
<!-- fds\rpc\WebServiceClearHeader.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" height="600" >
<!-- The value of the destination property is for demonstration only and is not a real
destination. -->
<mx:WebService id="ws" wsdl="http://myserver:8500/flexapp/app1.cfc?wsdl"
load="headers();"/>
<mx:Script>
<![CDATA[
import mx.rpc.*;
import mx.rpc.soap.SOAPHeader;
<mx:HBox>
<mx:Button label="Clear headers and run again" click="clear();"/>
</mx:HBox>
</mx:Application>
...
public function onLoginResult(event:ResultEvent):void {
// Redirect all service operations to the URL received in the login result.
serviceName.endpointURI=newServiceURL;
}
...
A web service that requires you to pass security credentials might also return an identifier that you must attach in a
SOAP header for subsequent requests. For more information, see “Working with SOAP headers” on page 41.
Top-level elements
Local elements
The following table shows the default encoding mappings from ActionScript 3 types to XML schema built-in types.
xsd:unsignedByte String
xsd:negativeInteger
xsd:nonNegativeInteger
xsd:positiveInteger
xsd:nonPositiveInteger
xsd:unsignedInt String
xsd:unsignedLong String
xsd:unsignedShort String
and derivatives:
xsd:ID
xsd:IDREF
xsd:IDREFS
xsd:ENTITY
xsd:ENTITIES
xsd:language
xsd:Name
xsd:NCName
xsd:NMTOKEN
xsd:NMTOKENS
xsd:normalizedString
xsd:token
The following table shows the default mapping from ActionScript 3 types to SOAP-encoded types.
soapenc:Array Array SOAP-encoded arrays are special cases and are supported only
with RPC-encoded web services.
mx.collections.IList
xsd:int
xsd:long
xsd:negativeInteger
xsd:nonNegativeInteger
xsd:nonPositiveInteger
xsd:positiveInteger
xsd:short
xsd:unsignedByte
xsd:unsignedInt
xsd:unsignedLong
xsd:unsignedShort
and derivatives:
xsd:ID
xsd:IDREF
xsd:IDREFS
xsd:ENTITY
xsd:ENTITIES
xsd:language
xsd:Name
xsd:NCName
xsd:NMTOKEN
xsd:NMTOKENS
xsd:normalizedString
xsd:token
xsi:nil null
The following table shows the default decoding mappings from SOAP-encoded types to ActionScript 3 types.
The following table shows the default decoding mappings from custom data types to ActionScript 3 data types.
http://xml.apache.o
rg/xml-soap:Rowset
The following XML Schema structures or structure attributes are ignored and are not supported in Flex 3:
<attribute use="required"/>
<element
substitutionGroup="..."
unique="..."
key="..."
keyref="..."
field="..."
selector="..."/>
<simpleType>
<restriction>
<minExclusive>
<minInclusive>
<maxExclusiv>
<maxInclusive>
<totalDigits>
<fractionDigits>
<length>
<minLength>
<maxLength>
<enumeration>
<whiteSpace>
<pattern>
</restriction>
</simpleType>
<complexType
final="..."
block="..."
mixed="..."
abstract="..."/>
<any
processContents="..."/>
<annotation>
Next, you want to invoke a getUser operation on a web service that returns the following XML:
<tns:getUserResponse xmlns:tns="http://example.uri">
<tns:firstName>Ivan</tns:firstName>
<tns:lastName>Petrov</tns:lastName>
</tns:getUserResponse>
To make sure you get an instance of your User class instead of a generic Object when you invoke the getUser operation,
you need the following ActionScript code inside a method in your Flex application:
SchemaTypeRegistry.getInstance().registerClass(new QName("http://example.uri",
"getUserResponse"), User);
SchemaTypeRegistry.getInstance() is a static method that returns the default instance of the type registry. In
most cases, that is all you need. However, this registers a given QName with the same ActionScript class across all web
service operations in your application. If you want to register different classes for different operations, you need the
following code in a method in your application:
var qn:QName = new QName("http://the.same", "qname");
var typeReg1:SchemaTypeRegistry = new SchemaTypeRegistry();
var typeReg2:SchemaTypeRegistry = new SchemaTypeRegistry();
typeReg1.registerClass(qn, someClass);
myWS.someOperation.decoder.typeRegistry = typeReg1;
typeReg2.registerClass(qn, anotherClass);
myWS.anotherOperation.decoder.typeRegistry = typeReg2;
When invoking someOperation, Flex calls the decodeResponse() method of the MyDecoder class. From that point
on it is up to the custom implementation to handle the full SOAP message and produce the expected ActionScript
objects.
• SabreAMF http://www.osflash.org/sabreamf
• Midnight Coders WebORB http://www.themidnightcoders.com/
As with HTTPService and WebService components, you can use a RemoteObject component to display the result
of a database query in a Flex application and insert data into a database. When the result has been returned to the
Flex application, you can display it in one or more user interface controls.
For API reference information about the RemoteObject component, see mx.rpc.remoting.mxml.RemoteObject.
MXML code
The Flex application in the following example uses a RemoteObject component to call a ColdFusion component. The
ColdFusion component queries a MySQL database table called users. It returns the query result to the Flex application
where it is bound to the dataProvider property of a DataGrid control and displayed in the DataGrid control. The
Flex application also sends the user name and e-mail address of new users to the ColdFusion component, which
performs an insert into the user database table.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute"
creationComplete="userRequest.returnRecords()">
<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="dgUserRequest" 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="{dgUserRequest.selectedItem.emailaddress}"/>
<mx:RemoteObject
id="userRequest"
destination="ColdFusion"
source="flexapp.returnusers">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
In this application, the RemoteObject component’s destination property is set to Coldfusion and the source
property is set to the fully qualified name of the ColdFusion component.
In contrast, when working with LiveCycle Data Services ES or BlazeDS, you specify a fully qualified class name in the
source property of a remoting service destination in a configuration file, which by default is the remoting-config.xml
file. You specify the name of the destination in the RemoteObject component’s destination property. The
destination class also must have a no-args constructor. You can optionally configure a destination this way when
working with ColdFusion instead of by using the source property on the RemoteObject component.
ColdFusion component
The Flex application calls the following ColdFusion component. This ColdFusion code performs SQL database inserts
and queries and returns query results to the Flex application. The ColdFusion page uses the cfquery tag to insert data
into the database and query the database, and it uses the cfreturn tag to format the query results as a ColdFusion
query object.
<cfcomponent name="returnusers">
<cffunction name="returnRecords" access="remote" returnType="query">
<?xml version="1.0"?>
<!-- fds\rpc\ROInAS.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.remoting.RemoteObject;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
[Bindable]
public var empList:Object;
public var employeeRO:RemoteObject;
When you configure a remote object destination to access stateful objects, Flex creates the object once on the server
and maintains state between method calls. If storing the object in the application or session scope causes memory
problems, you should use the request scope.
On the Java side, the getHelloData() method could encapsulate everything necessary to call a business method on
an EJB. The Java method in the following example performs the following actions:
• Creates new initial context for calling the EJB
• Performs a JNDI lookup that gets an EJB home object
• Calls the EJB home object's create() method
• Calls the EJB's sayHello() method
...
public void getHelloData() {
try{
InitialContext ctx = new InitialContext();
Object obj = ctx.lookup("/Hello");
HelloHome ejbHome = (HelloHome)
PortableRemoteObject.narrow(obj, HelloHome.class);
HelloObject ejbObject = ejbHome.create();
String message = ejbObject.sayHello();
}
catch (Exception e);
}
...
addHeader()
addProperty()
deleteHeader()
hasOwnProperty()
isPropertyEnumerable()
isPrototypeOf()
registerClass()
toLocaleString()
toString()
unwatch()
valueOf()
watch()
Also, you should not begin method names with an underscore (_) character.
RemoteObject methods (operations) are usually accessible by simply naming them after the service variable. However,
naming conflicts can occur if an operation name happens to match a defined method on the service. You can use the
following method in ActionScript on a RemoteObject component to return the operation of the given name:
public function getOperation(name:String):Operation
String of "true" or
"false"
flash.utils.ByteArray byte []
flash.utils.IExternalizable java.io.Externalizable
(legacy XML type) You can enable legacy XML support for the
XMLDocument type on any channel defined in the
services-config.xml file. This setting is only important for
sending data from the server back to the client; it controls
how org.w3c.dom.Document instances are sent to
ActionScript. For more information, see Configuring AMF
serialization on a channel.
Primitive values cannot be set to null in Java. When passing Boolean and Number values from the client to a Java
object, Flex interprets null values as the default values for primitive types; for example, 0 for double, float, long, int,
short, byte, \u0000 for char, and false for boolean. Only primitive Java types get default values.
LiveCycle Data Services ES handles java.lang.Throwable objects like any other typed object. They are processed with
rules that look for public fields and bean properties, and typed objects are returned to the client. The rules are like
normal bean rules except they look for getters for read-only properties. This lets you get more information from a Java
exception. If you require legacy behavior for Throwable objects, you can set the legacy-throwable property to true
on a channel; for more information, see Configuring AMF serialization on a channel.
You can pass strict Arrays as parameters to methods that expect an implementation of the java.util.Collection or native
Java Array APIs.
A Java Collection can contain any number of Object types, whereas a Java Array requires that entries are the same type
(for example, java.lang.Object[ ], and int[ ]).
LiveCycle Data Services ES also converts ActionScript strict Arrays to appropriate implementations for common
Collection API interfaces. For example, if an ActionScript strict Array is sent to the Java object method public void
addProducts(java.util.Set products), LiveCycle Data Services ES converts it to a java.util.HashSet instance
before passing it as a parameter, because HashSet is a suitable implementation of the java.util.Set interface. Similarly,
LiveCycle Data Services ES passes an instance of java.util.TreeSet to parameters typed with the java.util.SortedSet
interface.
LiveCycle Data Services ES passes an instance of java.util.ArrayList to parameters typed with the java.util.List interface
and any other interface that extends java.util.Collection. Then these types are sent back to the client as
mx.collections.ArrayCollection instances. If you require normal ActionScript Arrays sent back to the client, you must
set the legacy-collection element to true in the serialization section of a channel-definition's properties; for
more information, see Configuring AMF serialization on a channel.
In the ActionScript class, you use the [RemoteClass(alias=" ")] metadata tag to create an ActionScript object that
maps directly to the Java object. The ActionScript class to which data is converted must be used or referenced in the
MXML file for it to be linked into the SWF file and available at run time. A good way to do this is by casting the result
object, as the following example shows:
var result:MyClass = MyClass(event.result);
The class itself should use strongly typed references so that its dependencies are also linked.
The following example shows the source code for an ActionScript class that uses the [RemoteClass(alias=" ")]
metadata tag:
package samples.contact {
[Bindable]
[RemoteClass(alias="samples.contact.Contact")]
public class Contact {
public var contactId:int;
You can use the [RemoteClass] metadata tag without an alias if you do not map to a Java object on the server, but
you do send back your object type from the server. Your ActionScript object is serialized to a special Map object when
it is sent to the server, but the object returned from the server to the clients is your original ActionScript type.
To restrict a specific property from being sent to the server from an ActionScript class, use the [Transient] metadata
tag above the declaration of that property in the ActionScript class.
java.lang.String String
java.lang.Byte[] flash.utils.ByteArray
java.math.BigDecimal String
java.util.Calendar Date
Dates are sent in the Coordinated Universal Time (UTC) time zone. Clients
and servers must adjust time accordingly for time zones.
java.util.Date Date
Dates are sent in the UTC time zone. Clients and servers must adjust time
accordingly for time zones.
java.lang.Object[] Array
null null
Note: You can enable legacy XML support for the flash.xml.XMLDocument type on any channel that is defined in the
services-config.xml file.
Note: In Flex 1.5, java.util.Map was sent as an associative or ECMA Array. This is no longer a recommended practice.
You can enable legacy Map support to associative Arrays, but Adobe recommends against doing this.
Property Description
enable-small-messages Default value is true. If enabled, messages are sent using an alternative
smaller form if one is available and the endpoint supports it.
ignore-property-errors Default value is true. Determines if the endpoint should throw an error when
an incoming client object has unexpected properties that cannot be set on
the server object.
log-property-errors Default value is false. When true, unexpected property errors are logged.
legacy-map Default value is false. When true, java.util.Map instances are serialized as an
ECMA Array or associative array instead of an anonymous Object.
legacy-externalizable Default value is false. When true, java.io.Externalizable types (that extend
standard Java classes like Date, Number, String) are not serialized as custom
objects (for example, MyDate is serialized as Date instead of MyDate). Note
that this setting overwrites any other legacy settings. For example, if
legacy-collection is true but the collection implements
java.io.Externalizable, the collection is returned as custom object without
taking the legacy-collection value into account.
restore-references Default value is false. An advanced switch to make the deserializer keep
track of object references when a type translation has to be made; for
example, when an anonymous Object is sent for a property of type
java.util.SortedMap, the Object is first deserialized to a java.util.Map as
normal, and then translated to a suitable implementation of SortedMap
(such as java.util.TreeMap). If other objects pointed to the same anonymous
Object in an object graph, this setting restores those references instead of
creating SortedMap implementations everywhere. Notice that setting this
property to true can slow down performance significantly for large
amounts of data.
instantiate-types Default value is true. Advanced switch that when set to false stops the
deserializer from creating instances of strongly typed objects and instead
retains the type information and deserializes the raw properties in a Map
implementation, specifically flex.messaging.io.ASObject. Notice that any
classes under flex.* package are always instantiated.
sequence Array
boolean Boolean
string String
normalizedString String
date Date
dateTime Date
time Date
Base64Binary flash.utils.ByteArray
hexBinary
flash.utils.ByteArray
anyType (in WSDL) Converts the ActionScript types to the following Schema
types:
• uint to unsignedInt
• int to int
• Number to double
• Boolean to boolean
• String to string
• XMLDocument to schema
• Date to dateTime
base64 flash.utils.ByteArray
boolean Boolean
Array Array
string String
Map Object
Element flash.xml.XMLNode
// Product.as
package samples.externalizable {
import flash.utils.IExternalizable;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
[RemoteClass(alias="samples.externalizable.Product")]
public class Product implements IExternalizable {
public function Product(name:String=null) {
this.name = name;
}
The client Product uses two kinds of serialization. It uses the standard serialization that is compatible with the
java.io.Externalizable interface and AMF 3 serialization. The following example shows the writeExternal() method
of the client Product, which uses both types of serialization:
public function writeExternal(output:IDataOutput):void {
output.writeObject(name);
output.writeObject(properties);
output.writeFloat(price);
}
As the following example shows, the writeExternal() method of the server Product is almost identical to the client
version of this method:
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
out.writeObject(properties);
out.writeFloat(price);
}
The examples of AMF 3 serialization in the client Product's writeExternal() method is the call to the
flash.utils.IDataOutput.writeObject() method, which maps to the java.io.ObjectInput.readObject()
method call in the server Product's readExternal() method. The flash.utils.IDataOutput.writeObject()
method sends the properties property, which is an Object, and the name property, which is a String, to the server
Product. This is possible because the AMFChannel endpoint has an implementation of the java.io.ObjectInput
interface that expects data sent from the writeObject() method to be formatted as AMF 3.
In turn, when the readObject() method is called in the server Product's readExternal() method, it uses AMF 3
deserialization; this is why the ActionScript version of the properties value is assumed to be of type Map and name
is assumed to be of type String.
The following example shows the complete source of the server Product class:
// Product.java
package samples.externalizable;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Map;
/**
* This Externalizable class requires that clients sending and
* receiving instances of this type adhere to the data format
* required for serialization.
*/
public class Product implements Externalizable {
private String inventoryId;
public String name;
public Map properties;
public float price;
public Product()
{
}
/**
* Local identity used to track third party inventory. This property is
* not sent to the client because it is server-specific.
* The identity must start with an 'X'.
*/
public String getInventoryId() {
return inventoryId;
}
/**
* Deserializes the client state of an instance of ThirdPartyProxy
* by reading in String for the name, a Map of properties
* for the description, and
* a floating point integer (single precision) for the price.
*/
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
// Read in the server properties from the client representation.
name = (String)in.readObject();
properties = (Map)in.readObject();
price = in.readFloat();
setInventoryId(lookupInventoryId(name, price));
}
/**
* Serializes the server state of an instance of ThirdPartyProxy
* by sending a String for the name, a Map of properties
* String for the description, and a floating point
* integer (single precision) for the price. Notice that the inventory
* identifier is not sent to external clients.
*/
public void writeExternal(ObjectOutput out) throws IOException {
// Write out the client properties from the server representation
out.writeObject(name);
out.writeObject(properties);
out.writeFloat(price);
}
The client Product's writeExternal() method does not send the id property to the server during serialization
because it is not useful to the server version of the Product object. Similarly, the server Product's writeExternal()
method does not send the inventoryId property to the client because it is a server-specific property.
Notice that the names of a Product's properties are not sent during serialization in either direction. Because the state
of the class is fixed and manageable, the properties are sent in a well-defined order without their names, and the
readExternal() method reads them in the appropriate order.
<?xml version="1.0"?>
<!-- fds\rpc\RPCParamPassing.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
verticalGap="10">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
[Bindable]
public var empList:Object;
]]>
</mx:Script>
<mx:RemoteObject
id="employeeRO"
destination="SalaryManager"
result="empList=event.result"
fault="Alert.show(event.fault.faultString, 'Error');"/>
<?xml version="1.0"?>
<!-- fds\rpc\RPCSend.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
public function callService():void {
// Cancel all previous pending calls.
myService.cancel();
<mx:HTTPService
id="myService"
destination="Dest"
useProxy="true"/>
<!-- HTTP service call with a send() method that takes a variable as its parameter. The value
of the variable is an Object. -->
<mx:Button click="myService.send({param1: 'val1'});"/>
<!-- HTTP service call with an object as a send() method parameter that provides query
parameters. -->
<mx:Button click="callService();"/>
</mx:Application>
<?xml version="1.0"?>
<!-- fds\rpc\ROParamBind1.mxml. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:RemoteObject
id="ro"
destination="roDest">
<mx:method name="setData">
<mx:arguments>
<arg1>{text1.text}</arg1>
<arg2>{text2.text}</arg2>
</mx:arguments>
</mx:method>
</mx:RemoteObject>
<mx:TextInput id="text1"/>
<mx:TextInput id="text2"/>
Flex sends the argument tag values to the method in the order that the MXML tags specify.
The following example uses parameter binding in a RemoteObject component’s <mx:method> tag to bind the data of
a selected ComboBox item to the employeeRO.getList operation when the user clicks a Button control. When you
use parameter binding, you call a service by using the send() method with no parameters.
<?xml version="1.0"?>
<!-- fds\rpc\ROParamBind2.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="10">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.utils.ArrayUtil;
]]>
</mx:Script>
<mx:RemoteObject
id="employeeRO"
destination="roDest"
showBusyCursor="true"
fault="Alert.show(event.fault.faultString, 'Error');">
<mx:method name="getList">
<mx:arguments>
<deptId>{dept.selectedItem.data}</deptId>
</mx:arguments>
</mx:method>
</mx:RemoteObject>
<mx:ArrayCollection id="employeeAC"
source="{ArrayUtil.toArray(employeeRO.getList.lastResult)}"/>
<mx:HBox>
<mx:Label text="Select a department:"/>
<mx:ComboBox id="dept" width="150">
<mx:dataProvider>
<mx:ArrayCollection>
<mx:source>
<mx:Object label="Engineering" data="ENG"/>
<mx:Object label="Product Management" data="PM"/>
<mx:Object label="Marketing" data="MKT"/>
</mx:source>
</mx:ArrayCollection>
</mx:dataProvider>
</mx:ComboBox>
<mx:Button label="Get Employee List"
click="employeeRO.getList.send()"/>
</mx:HBox>
<mx:DataGrid dataProvider="{employeeAC}" width="100%">
<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="phone" headerText="Phone"/>
<mx:DataGridColumn dataField="email" headerText="Email"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
If you are unsure whether the result of a service call contains an array or an individual object, you can use the
toArray() method of the mx.utils.ArrayUtil class to convert the result to an array, as this example shows. If you pass
the toArray() method to an individual object, it returns an array with that object as the only Array element. If you
pass an array to the method, it returns the same array. For information about working with ArrayCollection objects,
see Data providers and collections.
<?xml version="1.0"?>
<!-- fds\rpc\HttpServiceParamBind.mxml. Compiles -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="20">
<mx:Script>
<![CDATA[
import mx.utils.ArrayUtil;
]]>
</mx:Script>
<mx:HTTPService
id="employeeSrv"
url="employees.jsp">
<mx:request>
<deptId>{dept.selectedItem.data}</deptId>
</mx:request>
</mx:HTTPService>
<mx:ArrayCollection
id="employeeAC"
source=
"{ArrayUtil.toArray(employeeSrv.lastResult.employees.employee)}"/>
<mx:HBox>
<mx:Label text="Select a department:"/>
<mx:ComboBox id="dept" width="150">
<mx:dataProvider>
<mx:ArrayCollection>
<mx:source>
<mx:Object label="Engineering" data="ENG"/>
<mx:Object label="Product Management" data="PM"/>
<mx:Object label="Marketing" data="MKT"/>
</mx:source>
</mx:ArrayCollection>
</mx:dataProvider>
</mx:ComboBox>
<mx:Button label="Get Employee List" click="employeeSrv.send();"/>
</mx:HBox>
<mx:DataGrid dataProvider="{employeeAC}"
width="100%">
<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="phone" headerText="Phone"/>
<mx:DataGridColumn dataField="email" headerText="Email"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
If you are unsure whether the result of a service call contains an array or an individual object, you can use the
toArray() method of the mx.utils.ArrayUtil class to convert it to an array, as the previous example shows. If you pass
the toArray() method to an individual object, it returns an array with that object as the only Array element. If you
pass an array to the method, it returns the same array. For information about working with ArrayCollection objects,
see Data providers and collections.
<mx:WebService
id="employeeWS"
destination="wsDest"
showBusyCursor="true"
fault="Alert.show(event.fault.faultString)">
<mx:operation name="getList">
<mx:request>
<deptId>{dept.selectedItem.data}</deptId>
</mx:request>
</mx:operation>
</mx:WebService>
<mx:ArrayCollection
id="employeeAC"
source="{ArrayUtil.toArray(employeeWS.getList.lastResult)}"/>
<mx:HBox>
<mx:Label text="Select a department:"/>
<mx:ComboBox id="dept" width="150">
<mx:dataProvider>
<mx:ArrayCollection>
<mx:source>
<mx:Object label="Engineering" data="ENG"/>
<mx:Object label="Product Management" data="PM"/>
<mx:Object label="Marketing" data="MKT"/>
</mx:source>
</mx:ArrayCollection>
</mx:dataProvider>
</mx:ComboBox>
<mx:Button label="Get Employee List"
click="employeeWS.getList.send()"/>
</mx:HBox>
<mx:DataGrid dataProvider="{employeeAC}" width="100%">
<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="phone" headerText="Phone"/>
<mx:DataGridColumn dataField=" to email" headerText="Email"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
You can also manually specify an entire SOAP request body in XML with all of the correct namespace information
defined in an <mx:request> tag. To do this, you must set the value of the format attribute of the <mx:request> tag
to xml, as the following example shows:
<?xml version="1.0"?>
<!-- fds\rpc\WebServiceSOAPRequest.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="10">
<mx:WebService id="ws" wsdl="http://api.google.com/GoogleSearch.wsdl"
useProxy="true">
<mx:operation name="doGoogleSearch" resultFormat="xml">
<mx:request format="xml">
<ns1:doGoogleSearch xmlns:ns1="urn:GoogleSearch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<key xsi:type="xsd:string">XYZ123</key>
<q xsi:type="xsd:string">Balloons</q>
<start xsi:type="xsd:int">0</start>
<maxResults xsi:type="xsd:int">10</maxResults>
<filter xsi:type="xsd:boolean">true</filter>
<restrict xsi:type="xsd:string"/>
<safeSearch xsi:type="xsd:boolean">false</safeSearch>
<lr xsi:type="xsd:string" />
<ie xsi:type="xsd:string">latin1</ie>
<oe xsi:type="xsd:string">latin1</oe>
</ns1:doGoogleSearch>
</mx:request>
</mx:operation>
</mx:WebService>
</mx:Application>
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
<mx:WebService
id="adbe_news"
useProxy="true"
destination="ws-catalog"
result="handleResult(event);"
fault="handleFault(event);"/>
<!-- Define a DataGrid control to diplay the results of the web service. -->
<mx:DataGrid id="myDG" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="productId" headerText="Product Id"/>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="price" headerText="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
In this example, all operations that you invoke through the WebService component use the same event handlers.
<mx:Script>
<![CDATA[
import mx.rpc.soap.SOAPFault;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
<mx:WebService id="WeatherService"
destination="ws-catalog"
result="defaultResult(event);"
fault="defaultFault(event);">
<mx:operation name="getProducts"
fault="getProductsFault(event);"
result="getProductsResult(event);">
</mx:operation>
</mx:WebService>
<mx:Button click="WeatherService.getProducts.send();"/>
</mx:Application>
<mx:Script>
<![CDATA[
import mx.rpc.soap.SOAPFault;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
<mx:WebService id="WeatherService"
destination="ws-catalog"
result="defaultResult(event);"
fault="defaultFault(event);">
<mx:operation name="getProducts"/>
</mx:WebService>
<!-- Call the service using the default event handlers. -->
<mx:Button label="Use Default Handlers" click="WeatherService.getProducts.send();"/>
<!-- Call the service using the custom event handlers. -->
<mx:Button label="Use Custom Handlers" click="setCustomHandlers();"/>
</mx:Application>
Notice that some properties are assigned to the token after the call to the remote service is made. In a multi-threaded
language, there would be a race condition where the result comes back before the token is assigned. This situation is
not a problem in ActionScript because the remote call cannot be initiated until the currently executing code finishes.
<?xml version="1.0"?>
<!-- ds\rpc\RPCResultEvent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
<!-- Define a DataGrid control to diplay the reults of the web service. -->
<mx:DataGrid id="myDG" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="productId" headerText="Product Id"/>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="price" headerText="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
The data type of the ResultEvent.result property is Object. Therefore, the event handler inspects the
ResultEvent.result property to make sure that it can be cast to the required type. In this example, you want to cast
it to ArrayCollection so that you can use it as the data provider for the DataGrid control. If the result cannot be cast to
the ArrayCollection, set the data provider to null.
This soap:Body tag contains namespace information. Therefore, if you set the resultFormat property of the
WebService operation to e4x, create a namespace object for the http://ws.invesbot.com/namespace. The following
example shows an application that does that:
<?xml version="1.0"?>
<!-- ds\rpc\WebServiceE4XResult1.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
<mx:WebService
id="WS"
destination="stockservice" useProxy="true"
fault="Alert.show(event.fault.faultString, 'Error');">
<mx:operation name="GetQuote" resultFormat="e4x">
<mx:request>
<symbol>ADBE</symbol>
</mx:request>
</mx:operation>
</mx:WebService>
<mx:HBox>
<mx:Button label="Get Quote" click="WS.GetQuote.send();"/>
<mx:Text text="{WS.GetQuote.lastResult.GetQuoteResult.StockQuote.Price}"/>
</mx:HBox>
</mx:Application>
Optionally, you can create a variable for a namespace and access it in a binding to the service result, as the following
example shows:
<?xml version="1.0"?>
<!-- ds\rpc\WebServiceE4XResult2.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
<mx:WebService
id="WS"
destination="stockservice" useProxy="true"
fault="Alert.show(event.fault.faultString, 'Error');">
<mx:operation name="GetQuote" resultFormat="e4x">
<mx:request>
<symbol>ADBE</symbol>
</mx:request>
</mx:operation>
</mx:WebService>
<mx:HBox>
<mx:Button label="Get Quote" click="WS.GetQuote.send()"/>
<mx:Text text="{WS.GetQuote.lastResult.invesbot::GetQuoteResult.StockQuote.Price}"/>
</mx:HBox>
</mx:Application>
You use E4X syntax to access elements and attributes of the XML that is returned in a lastResult object. You use
different syntax, depending on whether there is a namespace or namespaces declared in the XML.
No namespace specified
The following example shows how to get an element or attribute value when no namespace is specified on the element
or attribute:
var attributes:XMLList = XML(event.result).Description.value;
The previous code returns xxx for the following XML document:
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Description>
<value>xxx</value>
</Description>
</RDF>
The previous code returns xxx for either one of the following XML documents:
XML document one:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description>
<rdf:value>xxx</rdf:value>
</rdf:Description>
</rdf:RDF>
The previous code returns xxx for the following XML document:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description>
<rdf:value>xxx</rdf:value>
<nsX:value>yyy</nsX:value>
</rdf:Description>
</rdf:RDF>
The following example shows an alternate way to get an element or attribute value when the declared rdf namespace
is specified on the element or attribute:
namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
use namespace rdf;
var attributes:XMLList = XML(event.result).rdf::Description.rdf::value;
The previous code also returns xxx for the following XML document:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description>
<rdf:value>xxx</rdf:value>
</rdf:Description>
</rdf:RDF>
When you set the resultFormat property of a Flex WebService operation to object, a DataTable or DataSet returned
from a .NET webservice is automatically converted to an object with a Tables property, which contains a map of one
or more dataTable objects. Each dataTable object from the Tables map contains two properties: Columns and Rows.
The Rows property contains the data. The event.result object gets the following properties corresponding to DataSet
and DataTable properties in .NET. Arrays of DataSets or DataTables have the same structures described here, but are
nested in a top-level Array on the result object.
Property Description
result.Tables["someTable"].Rows Array of objects that represent the data of each table row. For
example, {columnName1:value, columnName2:value,
columnName3:value}.
The following MXML application populates a DataGrid control with DataTable data returned from a .NET web
service.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:WebService
id="nwCL"
wsdl="http://localhost/data/CustomerList.asmx?wsdl"
result="onResult(event)"
fault="onFault(event)" />
<mx:Button label="Get Single DataTable" click="nwCL.getSingleDataTable()"/>
<mx:Button label="Get MultiTable DataSet" click="nwCL.getMultiTableDataSet()"/>
<mx:Panel id="dataPanel" width="100%" height="100%" title="Data Tables"/>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.DataGrid;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
//displayTable(namedTable);
}
}
</mx:Application>
The following example shows the .NET C# class that is the backend web service implementation called by the Flex
application; this class uses the Microsoft SQL Server Northwind sample database:
:
<%@ WebService Language="C#" Class="CustomerList" %>
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Services.Description;
using System.Data;
using System.Data.SqlClient;
using System;
adpt.Fill(dt);
return dt;
}
[WebMethod]
public DataSet getMultiTableDataSet() {
string cnStr = "[Your_Database_Connection_String]";
string query1 = "SELECT TOP 10 CustomerID, CompanyName FROM Customers";
string query2 = "SELECT TOP 10 OrderID, CustomerID, ShipCity,
ShipCountry FROM Orders";
SqlConnection cn = new SqlConnection(cnStr);
cn.Open();
return ds;
}
}
Index
A W
argument binding 70 web services
RPC-oriented, document-oriented 41
B SOAP headers 41
binding WSDL 40
RPC components, parameter 70 WebService components
additional features 35
C
crossdomain.xml file 36
D
data
results, data service 82
types, converting 59, 62
E
Enterprise JavaBeans 58
J
Java Naming and Directory Interface 58
JNDI, accessing 58
M
mx.rpc.events.InvokeEvent event 27, 36, 54
N
namespaces
handling in RPC components 84
P
parameter binding 70
R
RemoteObject components
stateful objects 58
S
serialization
ActionScript to Java 59
Java to ActionScript 62
legacy AMF type serialization 63
SOAP 35