Remote shared objects allow real-time data synchronization across many clients, but they also require server software such as Flash Media Server.. The following code retrieves a referenc
Trang 1Note that the SharedObjectclass also allows you to work with remote
shared objects For this reason, you may notice that the SharedObject
class API includes many properties and methods not discussed in this
chapter Remote shared objects allow real-time data synchronization
across many clients, but they also require server software such as Flash
Media Server In this book, we discuss local shared objects, not remote
shared objects.
Creating Shared Objects
Unlike many ActionScript classes, the SharedObject constructor is never useddirectly, and you cannot meaningfully create a new instance using the constructor.Rather, the SharedObject class defines a static, lazy instantiation factory methodcalledgetLocal( ) The getLocal( )method returns aSharedObjectinstance that acts
as a proxy to a local shared object file on the client computer There can obviously bemany local shared objects on a client computer, so you must specify the specificshared object you want to reference by passing a string parameter togetLocal( ) Ifthe file does not yet exist, Flash Player first creates the file and then opens it for read-ing and writing If the file already exists, Flash Player simply opens it for reading andwriting The following code retrieves a reference to a shared object calledexample: var sharedObject:SharedObject = SharedObject.getLocal("example");
Reading and Writing to Shared Objects
Once you’ve retrieved the reference to the shared object, you can read and write to itusing the data property of the object, which is essentially an associative array Youmust write all data that you want to persist to disk to the data property You can usedot syntax or array-access notation to read and write arbitrary keys and values Ingeneral, dot syntax is marginally optimal because it yields slightly faster perfor-mance The following writes a value of true to the shared object for a key calledhideStartScreen:
sharedObject.data.hideStartScreen = true;
You should use array-access notation when you want to read or write using a keythat uses characters that are not valid for use in variable/property names For exam-ple, if you want to use a key that contains spaces, you can use array-access notation:sharedObject.data["First Name"] = "Bob";
Trang 2Data is not written to disk as you write it to theSharedObjectinstance By default,
Flash Player attempts to write the data to disk when the swf closes However, this
can fail silently for several reasons For example, the user might not have allocatedenough space or the user might have disallowed writing to shared objects entirely Inthese cases, the shared object data will not write to disk, and the Flex applicationwill have no notification For this reason, it is far better to explicitly write the data todisk
You can explicitly write data to disk using theflush( )method Theflush( )methodserializes all the data and writes it to disk If the user has disallowed local data stor-age for Flash Player for the domain,flush( ) throws an error:
Theflush( )method also returns a string value corresponding to either thePENDING
or theFLUSHEDconstants offlash.net.SharedObjectFlushStatus If the return value is FLUSHED, the data was successfully saved to disk If the return value is PENDING, itmeans that the user has not allocated enough disk space for the amount of data theshared object is trying to write to disk, and Flash Player is displaying a settings dia-log to the user, prompting her to allow the necessary allocation When the userselects either to allow or disallow the allocation, the shared object dispatches anetStatusevent You can listen for the event using theflash.events.NetStatusEvent NET_STATUS constant:
sharedObject.addEventListener(NetStatusEvent.NET_STATUS, flushStatusHandler);
The NetStatusEvent type defines a property called info that contains a propertycalledcode The codeproperty will have a string value of eitherSharedObject.Flush SuccessorSharedObject.Flush.Failed Example 15-3 tries to write to disk If the userhas disallowed local data storage or does not allocate the space when prompted, theapplication displays an alert
Example 15-3 Shared object example
Trang 3Persistent Data | 363
By default, Flash Player attempts to allocate enough space for the shared object data Ifthe shared object is likely to grow over time, Flash Player might prompt the user toallocate more space with each incremental increase If you know that a shared objectwill require more disk space in the future, you can preallocate space by callingflush( )with the number of bytes you want to allocate For example, the following attempts toallocate 512,000 bytes:
sharedObject.flush(512000);
The default allocation is 100 KB Unless the user has changed his
Flash Player settings, you can generally assume that you can store up
to 100 KB of data in a local shared object without prompting the user.
private function initializeHandler(event:Event):void {
Trang 4Controlling Scope
By default, every shared object is specific to the swf from which it originates ever, you can allow several swf files to access the same shared object(s) by specify-
How-ing a path when callHow-ing getLocal( ) The default path is the path to the swf For
example, if the swf is at http://www.example.com/flex/client/a.swf, the path is /flex/ client/a.swf, which means only a.swf can access the shared object For this example, we’ll assume that a.swf retrieves a reference to a shared object called example asfollows:
var sharedObject:SharedObject = SharedObject.getLocal("example");
If b.swf is in the same directory as a.swf, and b.swf also tries to retrieve a reference to
a shared object calledexampleusing the exact same code as appears in a.swf, b.swf
will retrieve a reference to a different shared object—one that is scoped specifically
to the path /flex/client/b.swf If you want a.swf and b.swf to be able to access the same
shared object, you must specify a path parameter using a common path that they
both share, such as /flex/client:
var sharedObject:SharedObject = SharedObject.getLocal("example", "/flex/client");
In order for swf files to have access to the same shared objects, they must specify a path that they have in common For example, both a.swf and b.swf have /flex/client
in common They also share the paths /flex and / If http://www.example.com/main swf wants to use the same shared object as a.swf and b.swf, all three swf files must specify a path of / for the shared object because that is the only path they have in
common
Shared objects can be shared by all swf files within a domain
How-ever, swf files in two different domains cannot access the same local
shared object.
Using Local Shared Objects
Thus far we’ve talked about local shared objects in theory In this section, we’ll build
a simple application that uses a shared object in a practical way This example plays a log-in form in a pop up However, the user has the option to set a preference
dis-so that the application will remember her
This example application uses an MXML component that displays the login dow It also uses a User Singleton class that allows the user to authenticate Notethat in this example, the application uses hardcoded values against which it authenti-cates In a real application, the authentication would be against data from a data-base, LDAP, or some similar data store
win-TheUser class looks like Example 15-4.
Trang 5Persistent Data | 365
The login form component looks like Example 15-5 (name the file LogInForm.mxml
and save it in the root directory for the project)
Example 15-4 User class for shared object example
package com.oreilly.programmingflex.lso.data {
import flash.events.EventDispatcher;
import flash.events.Event;
public class User extends EventDispatcher {
// The managed instance.
private static var _instance:User;
// Declare two constants to use for event names.
public static const AUTHENTICATE_SUCCESS:String = "success";
public static const AUTHENTICATE_FAIL:String = "fail";
public function User( ) {}
// The Singleton accessor method.
public static function getInstance( ):User {
public function authenticate(username:String, password:String):void {
if(username == "user" && password == "pass") {
Trang 6The application MXML file itself is shown in Example 15-6.
// This method handles click events from the button.
private function onClick(event:MouseEvent):void {
// If the user selected the remember me check box then save the username // and password to the local shared object.
// Authenticate the user.
User.getInstance( ).authenticate(username.text, password.text);
private var _logInForm:LogInForm;
private function initializeHandler(event:Event):void {
Example 15-5 LogInForm.mxml (continued)
Trang 7}
}
private function displayLogInForm(event:Event = null):void {
if(_logInForm == null) {
_logInForm = new LogInForm( );
PopUpManager.addPopUp(_logInForm, this, true);
Trang 8Customizing Serialization
Many built-in types are automatically serialized and deserialized For example,strings, numbers, Boolean values, Date objects, and arrays are all automaticallyserialized and deserialized That means that even though shared object data is ulti-mately saved to a flat file, when you read a Dateobject or an array from a sharedobject, it is automatically recognized as the correct type Flash Player automaticallyserializes all public properties (including public getters/setters) for custom types aswell However, Flash Player does not automatically store the class type That meansthat when you retrieve data of a custom type from a shared object, it does not deseri-alize to the custom type by default For instance, consider the class shown inExample 15-7
If you try to write an object of this type to a shared object, it correctly serializes thefirstNameandlastNameproperties (getters/setters) That means that when you readthe data back from the shared object, it displays those values properly However, itwill throw an error if you attempt to call getFullName( ) because the deserialized
Example 15-7 Account class
package com.oreilly.programmingflex.serialization {
public class Account {
private var _firstName:String;
private var _lastName:String;
public function get firstName( ):String {
public function Account( ) {}
public function getFullName( ):String {
return _firstName + " " + _lastName;
}
}
}
Trang 9Persistent Data | 369
object will not be of typeUser To test this, we’ll use two MXML applications called
A and B A is defined as shown in Example 15-8, and it sets the shared object data
B, shown in Example 15-9 reads the shared object data, and attempts to display thedata in alert pop ups Note that it will correctly displayfirstNameandlastName, but
it will throw an error ongetFullName( ).
private var _sharedObject:SharedObject;
private function initializeHandler(event:Event):void {
Trang 10If you want to store the type in the serialized data, you can use flash.net registerClassAlias( ) The registerClassAlias( ) function allows you to map theclass to an alias The alias is written to the serialized data When the data is deserial-ized, Flash Player automatically instantiates the object as the specified type The fol-lowing revisions to A and B cause the User data to deserialize as aUser object.Example 15-10 shows the new A, which creates theUserobject and saves it to theshared object Since the code now registers the class to the alias, User, it will storethe alias in the serialized data as well.
private var _sharedObject:SharedObject;
private function initializeHandler(event:Event):void {
Trang 11Persistent Data | 371
Example 15-11 shows the updated B Since this code also registers the class using thealias, User, it automatically deserializes the data from the local shared object as aUser object because it matches the alias.
import mx.controls.Alert;
import com.oreilly.programmingflex.serialization.Account;
import flash.net.registerClassAlias;
private var _sharedObject:SharedObject;
private function initializeHandler(event:Event):void {
Trang 12When you register a class usingregisterClassAlias( ), the class for which you areregistering the alias must not have any required parameters in the constructor If itdoes, Flash Player will throw an error when trying to deserialize the data.
The default serialization and deserialization for custom classes works well for dard value object-style data model types However, if you want to serialize and dese-rialize any nonpublic state settings, you must implement flash.utils IExternalizable When a class implements IExternalizable, Flash Player automati-cally uses the custom serialization and deserialization you define rather than thestandard That allows you much more control over what and how the objects willstore
stan-The IExternalizable interface requires two methods, called writeExternal( ) andreadExternal( ) The writeExternal( ) method requires a flash.utils.IDataOutputparameter, and the readExternal( ) method requires a flash.utils.IDataInputparameter Both IDataInput and IDataOutput provide interfaces for working withbinary data.IDataInputallows you to read data using methods such asreadByte( ), readUTF( ), and readObject( ), and IDataOutputallows you to write data using meth-ods such as writeByte( ), writeUTF( ), and writeObject( ) The writeExternal( )method gets called when the object needs to be serialized You must write all data totheIDataOutputparameter that you want to store The readExternal( )method getscalled when the object is deserialized You must read all the data from theIDataInputparameter The data you read from theIDataInputparameter is in the same order as
import flash.utils.describeType;
import mx.controls.Alert;
import com.oreilly.programmingflex.serialization.Account;
import flash.net.registerClassAlias;
private var _sharedObject:SharedObject;
private function initializeHandler(event:Event):void {
Trang 13Persistent Data | 373
the data you write to the IDataOutput parameter Example 15-12 rewrites Accountusing IExternalizable Note that there is no setter method for either firstNameorlastName, which proves that the data is set via the customized deserialization.
Example 15-12 Account rewritten to implement IExternalizable
package com.oreilly.programmingflex.serialization {
import flash.utils.IExternalizable;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
public class Account implements IExternalizable {
private var _firstName:String;
private var _lastName:String;
public function get firstName( ):String {
public function getFullName( ):String {
return _firstName + " " + _lastName;
public function writeExternal(output:IDataOutput):void {
// Verify that _firstName is not null because this method may get called // when the data is null Only serialize when the object is non-null.
Trang 14Communicating with the Host Application
Flex applications require the Flash Player runtime environment to work For this son, it is common to think of Flex applications as being confined to Flash Player.However, it is entirely possible for a Flex application to communicate with the hostapplication For example, if a Flex application is running within a web browser, theapplication can interact with the browser If a Flex application is running within adesktop executable, it can interact with that executable This allows you to createintegrated applications that span beyond the Flash Player context
rea-Flex application/host application communication takes place via a Flash Player classcalled flash.external.ExternalInterface ExternalInterface allows you to makesynchronous calls to host application methods from the Flex application, and fromthe host application to Flex application methods.ExternalInterfaceis quite simple
to work with, and in most cases, it is quite appropriate
Working with ExternalInterface
The flash.external.ExternalInterface class defines two static methods, namedcall( ) and addCallback( ), enabling Flex-to-host-application communication andhost-application-to-Flex communication, respectively
Thecall( )method allows you to call a method of the host application by passing itthe name of the method If the host application method expects parameters, you canpass those parameters to thecall( )method following the name of the host applica-tion method For example, the following calls thealert( ) JavaScript method whenthe Flex application is run in a web browser:
ExternalInterface.call("alert", "Test message from Flex");
The call( ) method works synchronously For example, the JavaScript confirm( )function creates a new dialog with OK and Cancel buttons The confirm dialogpauses the application until the user clicks on a button, at which time it returnseithertrue (OK) or false (Cancel).
var option:Boolean = ExternalInterface.call("confirm",
"Do you really want to close the application?");
Of course, the host application functions can be custom functions as well
If you want to call a Flex method from the host application, you must register themethod within the Flex application using ExternalInterface.addCallback( ) The addCallback( )method allows you to register a particular function or method with analias by which the method or function may be called from the host application Forexample, the following registersAlert.show as showAlert:
ExternalInterface.addCallback("showAlert", Alert.show);
Trang 15Communicating with the Host Application | 375
You can then call theAlert.showmethod by way of theshowAlertalias from the hostapplication
Within the host application, you must retrieve a reference to the Flash Player
instance that is running the swf You can then call the method by its alias directly
from the reference For example, if getFlexApplicationReference( ) is a functionwithin the host application that returns a reference to the Flash Player instance, thefollowing launches an alert:
getFlexApplicationReference( ).showAlert("Alert message from host application");
In JavaScript, the Flash Player reference is different depending on the type of browser(IE or non-IE) In IE you can retrieve a reference to the Flash Player instance by
window.id, where idis the value of theidparameter of the<object>tag, and in
non-IE browsers, the reference is document.name, where name is the value of the nameattribute of the <embed> tag The following JavaScript function determines thebrowser type and returns the correct reference in which both the idparameter andthename attribute are Example:
Setting the Web Browser Status
ExternalInterfacemight seem a little confusing until you see an example or two Inthis section and the next, we’ll look at a few simple examples that should clarify howExternalInterfaceworks This first application simply allows a Flex application tocall to JavaScript in a hosting web browser so that it sets the status bar message asthe user moves the mouse over Flex buttons
Firefox disables JavaScript access to window.status by default, and
therefore this example might not work with the default Firefox
Trang 16This MXML document creates four buttons Each button has a different label Usingevent handlers for the rollOver event, each button notifies the rollOverHandler( )method when the user has moved the mouse over the button TherollOverHandler( )method usesExternalInterface.call( )to call thesetStatusmethod that is definedusing JavaScript in the HTML page within which the application is to be embedded.The label for the corresponding button gets passed to thesetStatus function.
The HTML page should contain the standard HTML template for embedding Flexcontent In addition, it must define thesetStatus( ) JavaScript function as follows:
<script language="JavaScript" type="text/javascript">
Integrating HTML and Flex Forms
There are cases in which you may want to display the majority of a form in HTML,but you may want to use Flex components for one or more of the form elements Forexample, you may want to use sliders, color pickers, or, as in this example, datechoosers
In this simple example, we’ll create a basic HTML form with a checkbox and a smallembedded Flex application The Flex application consists of one date chooser com-ponent The checkbox simply enables and disables the date chooser Additionally, tohighlight the synchronous nature ofExternalInterface, the Flex application makes a
private function rollOverHandler(event:MouseEvent):void {
<mx:Button label="A" rollOver="rollOverHandler(event)" />
<mx:Button label="B" rollOver="rollOverHandler(event)" />
<mx:Button label="C" rollOver="rollOverHandler(event)" />
<mx:Button label="D" rollOver="rollOverHandler(event)" />
</mx:VBox>
</mx:Application>
Example 15-13 ExternalInterfaceExample.mxml (continued)
Trang 17Communicating with the Host Application | 377
request to the HTML page for an array of disabled dates, which it uses to disablethose dates in the date chooser
For this application, we’ll first create the HTML page as shown in Example 15-14
In the preceding HTML code we’ve highlighted a few of the key things to notice You’llsee that the checkbox uses anonChangehandler to call thesetEnabled( )method of theFlex application, passing it the checked value of the checkbox This means that theFlex application must map a method to the setEnabled( ) name as a valid
Example 15-14 ExternalInterface example HTML page
<param name="movie" value="Flex2.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#FFFFFF" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="Flex2.swf" quality="high" bgcolor="#FFFFFF"
width="175" height="180" name="Flex2" align="middle"
Trang 18ExternalInterface callback You’ll also see that the code defines several JavaScriptmethods called getFlexApplicationReference( ) and getDisallowedDates( ) Theformer simply returns the reference to the Flex application and the latter is callablefrom the Flex application to retrieve an array ofDate objects.
The Flex application consists of just one MXML document, as shown inExample 15-15
In this code, you’ll notice that when the application initializes, it calls thegetDisallowedDates( ) JavaScript function in a synchronous fashion, retrieving thereturned value immediately It then uses that value—an array of Dateobjects—tospecify the disabled ranges for the date chooser instance Since ExternalInterfaceautomatically serializes and deserializes arrays and Date objects, this code workswithout having to further convert the returned values
When the application initializes it also registerssetEnabled( )as anExternalInterfacecallback That is what allows the JavaScript-to-Flex communication
ThesetEnabled( )method takes the parameter and assigns it to the enabled property
of the date chooser Again, since Boolean values are automatically serialized anddeserialized, the code works as is
Example 15-15 ExternalInterface example MXML Flex2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)" width="175" height="180">
<mx:Script>
<![CDATA[
private function initializeHandler(event:Event):void {
var disallowedDates:Array = ExternalInterface.call("getDisallowedDates"); calendar.disabledRanges = disallowedDates;
Trang 19Summary | 379
Summary
In this chapter, we looked at the three basic ways in which you can enable data munication that occurs entirely on the client These mechanisms enable differenttypes of behavior:
com-• Local connections allow communication between two or more swf files running
on the same computer
• Local shared objects allow persistent data storage and retrieval on the clientcomputer
• ExternalInterfaceallows Flash and Flex applications to communicate with theapplication that hosts Flash Player
Trang 20Chapter 16
CHAPTER 16
Remote data communication occurs at runtime It does not reside strictly in theclient, but requires network connections to send and receive data between the clientand the server Flex applications support a variety of remote data communicationtechniques built on standards There are three basic categories of Flex applicationremote data communication:
HTTP request/response-style communication
This category consists of several overlapping techniques Utilizing the FlexframeworkHTTPServicecomponent or the Flash Player APIURLLoaderclass, youcan send and load uncompressed data such as text blocks, URL encoded data,and XML packets You can also send and receive SOAP packets using the Flexframework WebServicecomponent And you can use a technology called FlashRemoting to send and receive AMF packets, which use a binary protocol that issimilar to SOAP (but considerably smaller) Each technique achieves the similargoal of sending requests and receiving responses using HTTP or HTTPS
Real-time communication
This category consists of persistent socket connections Flash Player supportstwo types of socket connections: those that require a specific format for packets(XMLSocket) and those that allow raw socket connections (Socket) In both cases,the socket connection is persistent between the client and the server, allowingthe server to push data to the client—something not possible using standardHTTP request/response-style techniques
File upload/download communication
This category consists of the FileReferenceAPI which is native to Flash Playerand allows file upload and download directly within Flex applications
Of these three generalized categories, it is fairly easy to distinguish between fileupload/download communication and the other two types Clearly file upload/download communication applies only to cases in which the application requires fileuploading and downloading However, the distinction between HTTP request/response and real-time communication is not always as obvious
Trang 21Understanding Strategies for Data Communication | 381
HTTP request/response is far more common than real-time data communication.Although real-time data communication is necessary for some low-latency applica-tions, it adds network overhead to the application because it requires a persistentsocket connection for each user In contrast, HTTP request/response communica-tion is always initiated by the client in the form of a request The server returns aresponse to the client, and then the connection is closed again until the client makesanother request In most cases, the request/response model is more efficient
In this chapter, we’ll focus primarily on two forms of remote data communication:request/response and file upload/download We’ll focus primarily on asynchronous(request/response) communication techniques because they make up the majority ofremote data communication you’ll use for Flex applications We’ll also discuss thebasics of file upload and download
Understanding Strategies for Data Communication
When you build Flex applications that utilize data communication, it’s important tounderstand the strategies available for managing those communications and how toselect the right strategy for an application If you’re new to working with Flash plat-form applications, it’s important that you take the time to learn how data communi-cation works within Flash Player and how that compares and contrasts with whatyou already know about developing for other platforms For example, some of whatyou might know from working with HTML-based applications or Ajax applicationsmay be useful, but you should never assume that Flex applications behave in thesame way as applications built on other platforms
As you already know by this time, all Flex applications run in Flash Player With theexception of some Flex applications created using Flex Data Services, almost all Flex
applications are composed of precompiled swf files that are loaded in Flash Player
on the client The swf files are initially requested from the server, but they run on the client This means dynamic data (any data not statically compiled into the swf) must
be requested at runtime from the client to a server
Because Flex applications are stateful and self-contained, they don’t require newpage requests and wholesale screen refreshes to make data requests and handleresponses This behavior is something Flex applications have in common with AjaxRather than being page-driven, Flex applications are event-driven Even as the viewwithin a Flex application might not change, it can be making requests and receivingresponses Therefore, Flex data communication clearly requires different strategiesfrom those employed by page-driven applications
The Flex framework provides components for working with data communicationusing standard HTTP requests as well as SOAP requests These components arebeneficial when using the first of the common strategies for data communication:placing the code (the component) that makes a request within the class or MXML
Trang 22document that utilizes the data This is often the most obvious strategy, and it isoften the strategy that scales the least This strategy decentralizes data communica-tion, which causes several problems:
• Managing data communication is difficult when the code is decentralized, ply because it makes it difficult to locate the code at times
sim-• When data communication is tightly coupled with a particular view that uses thedata, that data is not readily accessible to other parts of the application Thismay not seem like a problem until you consider that many applications use thesame data in many places, and if you place the data communication code withinthe views that use the data, you make it difficult to synchronize the data and youmay require many requests for the same data
• Decentralizing data communication code makes the application fragile becausechanging anything about the data communication process (protocols, APIs, etc.)can break the application in many places In contrast, when data communica-tion code is centralized, it is relatively easier to adapt the application when some-thing in the data communication process changes
Although the first strategy has these significant pitfalls associated with it, we stillinclude discussions of the components within this chapter because the strategy is notcompletely without merit The components often provide a much faster way toassemble data communication-ready applications This is useful in cases of rapidprototypes, test applications, and small-scale (nonenterprise) applications with lessdemanding technical requirements
The second strategy requires centralizing data communication using remote proxy objects Remote proxies are objects that reside within the client tier where they can
stand in for remote services The remote proxy objects may even have the same APIs
as the remote services Remote proxies provide a centralized location for data munication code, and they hide the details of how data communication takes placesfrom the rest of the application Even if the implementation changes, the rest of theapplication can still continue to make calls on the remote proxy objects
com-The second strategy is much more scalable than the first Furthermore, because datacommunication code is centralized, this strategy is not susceptible to the same prob-lems as the first strategy, such as duplication of data requests, synchronization prob-lems, and adaptability issues For these reasons, we strongly prefer the use of remoteproxies for enterprise applications
Working with Request/Response Data Communication
You can work with request/response data communication in three basic ways: viasimple HTTP services, web services, and Flash Remoting Each achieves the samebasic goal of sending a request and receiving a response, and as such, you can usethem for the same purposes within Flex applications Which method you choose
Trang 23Working with Request/Response Data Communication | 383
depends primarily on what type of service you have available For example, if youwant to load XML data from an XML document, you should use simple HTTP ser-vice communication However, if you want to call a web service method, you shoulduse web services communication
Simple HTTP Services
The most basic type of HTTP request/response communication uses what we call
simple HTTP services These services include things such as text and XML resources,
either in static documents or dynamically generated by something such as a sion page, a servlet, or an ASP.NET page Simple HTTP services might also includepages that run scripts when called in order to do things such as insert data into orupdate databases, or send email You can use simple HTTP services to execute thesesorts of server behaviors, to load data, or to do both
ColdFu-Flex provides two basic ways in which you can call simple HTTP services: usingHTTPService, a Flex framework component; and using the Flash Player class flash net.URLLoader.
HTTPService
HTTPServiceis a component that allows you to make requests to simple HTTP vices such as text files, XML files, or scripts and pages that return dynamic data Youmust always define a value for the urlproperty of an HTTPService object Theurlproperty tells the object where it can find the resource to which it should make therequest The value can be either a relative URL or an absolute URL The followingexample uses MXML to create anHTTPServiceobject that loads text from a file called
ser-data.txt saved in the same directory as the compiled swf file:
<mx:HTTPService id="textService" url="data.txt" />
Now that you know how to create a newHTTPServiceinstance, let’s discuss how tosend requests, handle results, and pass parameters
Sending requests
Creating anHTTPServiceobject does not automatically make the request to load thedata In order to make the request, you must call thesend( )method You can callthesend( ) method in response to any framework or user event For example, if youwant to make the request as soon as the application initializes, you can callsend( )inresponse to the initialize event If you want to load the data when the use clicks abutton, you can call thesend( ) method in response to a click event:
textService.send( );
Trang 24Handling results
The send( )method makes the request, but a response is not likely to be returnedinstantaneously Instead, the application must wait for a result event The resultevent occurs when the entire response has been returned The following example dis-plays an alert when the data loads:
<mx:HTTPService id="textService" url="data.txt"
result="mx.controls.Alert.show('Data loaded')" />
Of course, normally you would want to do something more useful than display analert when the data loads More commonly, you will want to use the data in someway You can retrieve the response data (i.e., the data that has loaded) using thelastResult property Plain text is always loaded as string data However, theHTTPService component is capable of automatically converting serialized data intoassociative arrays For this reason, thelastResultproperty is typed asObject If youwant to treat it as a string, you must cast it Example 16-1 loads text from a file andthen displays it in a text area
Although you can explicitly handle the result event, it is far more common to usedata binding Example 16-2 accomplishes the same thing as Example 16-1, but ituses data binding
Example 16-1 Loading text with HTTPService
Trang 25Working with Request/Response Data Communication | 385
When possible, HTTPService deserializes data it loads in much the same way as itwould interpret data placed in aModel tag For example, consider the following data:
Example 16-2 Using data binding with HTTPService
<mx:HTTPService id="textService" url="data.txt" />
<mx:TextArea id="textArea" text="{textService.lastResult}" />
Trang 26As we’ve already seen, by defaultHTTPServiceresults are interpreted as text if theyare blocks of text, and if the results are XML data, they are parsed into an object.However, that is merely the default behavior You can explicitly dictate the way inwhich the results are handled using the resultFormat property of the HTTPServiceobject The default value isobject, which yields the default behavior you’ve alreadyseen You can optionally specify any of the following values:
When you want to pass parameters to the service, you can use therequestproperty
of the HTTPService instance The request property requires an Object value Bydefault, the name/value pairs of the object are converted to URL-encoded format andare sent to the service using HTTPGET You can assign an object using ActionScript,
Trang 27Working with Request/Response Data Communication | 387
However, when creating anHTTPServiceobject using MXML, it is often convenient
to declare the parameters using MXML as well:
<mx:HTTPService id="service" url="script.php">
param-Example 16-4 Using HTTPService with input parameters
Trang 28In the preceding example, the first combo box is populated with a list of countries.When the user selects a country from the combo box, it sends a request to the sec-ond service, a PHP script, sending the selected country as a parameter The returnvalue is in the following format:
<mx:HTTPService id="service" url="script.php" contentType="application/xml">
Using HTTPService with ActionScript
Although the simplest and quickest way to use anHTTPServiceobject is to primarilyuse MXML, this technique is best-suited to nonenterprise applications in which thedata communication scenarios are quite simple However, for more complex datacommunication requirements, it is advisable to use remote proxies, as discussed ear-lier in this chapter BecauseHTTPServicecomponents provide significant data conver-sion advantages (such as automatic serialization of data), it is still frequently a goodidea to use an HTTPService object within a remote proxy However, it is generallynecessary to then work with theHTTPServicecomponent entirely with ActionScript,including constructing the object and handling the responses
When working with HTTPService objects entirely with ActionScript you’ll want toimport themx.rpc.http.HTTPServiceclass You can then construct an instance with astandardnew statement:
var httpRequest:HTTPRequest = new HTTPRequest( );
You should then set theurl property:
httpRequest.url = "data.txt";