Interested in Flex graphics?
Check out the new bookFlex 4 Fun by Chet Haase,
available as a PrePrint™
from Artima Press.

Summary
The second part of a two-part series on progressively enhancing an enterprise
Web application with Flex, this article describes Flex's ability to interact
with a variety of server-side data sources, including fetching JSON and XML via
HTTP, and invoking server-side Java objects from a Flex client.

The first part of this article showed how Flex components can progressively
enhance a Web application: The open-source SWFObject library simplifies
embedding the Flash Player—a Flex application's execution
environment—into HTML[1]. Flash Player, in turn,
allows you to delegate UI-related logic to a Flex component[2]. Flex's UI-specific domain
language not only makes UI coding simpler, but your application will benefit
from Flash Player's just-in-time compiler, UI effects, animation, support for
multimedia, and so forth. In addition, because Flex supports CSS-based styling,
your Flex component will also blend nicely in the surrounding HTML page.

A crucial aspect of progressive enhancement with Flex rests on the
ability to pass data to a Flex component. In Part I, a server-generated
JSON array represented the application's data, which was then passed
as a FlashVar to the Flex component.

While FlashVars allow you to incorporate Flex into an existing
enterprise Web app with minimal changes to the application, FlashVars
have a major limitation: Because FlashVars are name/value strings, you
are limited to the maximum length of String object allowed in the
browser. For most browsers, that's about 65KB.

Try the examples in this article

The examples in this article can be compiled and run either with Flex Builder 3, Adobe's Eclipse-based development environment, or with the open-source Flex SDK.

A 60-day free trial version of Flex Builder 3 can be downloaded from Adobe. If you already have Eclipse installed, you can download the Eclipse plug-in version of Flex Builder 3; otherwise, choose the full Eclipse install.

Two-Phase Loading

You can remove that limitation by arranging for the Flex component to
perform its own data loading. This entails two loading phases for the
page:

Responding to the browser's request, the first phase loads the HTML
page and the embedded SWF (Flex) object[3];

Once the Flex application's rendering completes in the browser, Flex
fetches the application's data used to populate the component.

The two-phase loading pattern is common to many rich-client
applications, and can enhance user experience by reducing response
time: As long as the user stays on the same HTML page, phase I is
performed only once. All subsequent data access occurs through the
second phase, alleviating the need for the browser to retrieve and
render the UI anew with each subsequent request to the server. The
performance benefits of this pattern are fully exploited in
page-per-application type rich UIs, such as Google's GMail and Maps
applications.

The rest of this article presents three ways in which Flex optimizes data
loading from remote network resources: loading JSON data via HTTP, loading XML
via HTTP, and directly invoking server-side Java objects through a
high-performance serialization protocol. The first two techniques are a good
choice for RESTful data access, while remote object invocation suits the RPC
communication style[4]. An
advantage of the latter approach is that client and server can communicate
through strongly typed objects.

JSON over HTTP

Flex's HTTPService class simplifies the task of delegating JSON
data loading to the Flex client[5]. The following ActionScript
code fetches the specified URL's contents as part of the Flex client's
completion event handler:

HTTPService, part of the Flex SDK, provides analogous
functionality to the Ajax XMLHttpRequest object: Given a
URL, it enables you to asynchronously fetch data from that HTTP data
source. The call to send() returns immediately. A call-back
mechanism invokes a function when the result arrives or, alternatively,
when an error is detected.

The example's result and failure handler functions are referenced by
name: The compiler will locate methods matching the name and required
parameters and return types, and assign those functions as handlers to
process the result or failure of the HTTP request.

Since the example's result and failure handler functions each consists of a
single line, you can make the code a bit more concise by using
ActionScript function literals[6]:

ResultEvent's result property is an untyped
object, and we must cast it to a String before converting it into a
JSON array. The as cast expression ensures that the data is
either cast into the specified data type, or null is
returned. In this example, the error handler merely shows a somewhat
unfriendly box, indicating the cause of the communication error.

With this change, we can now remove the FlashVar from the Flex
component's surrounding HTML page. Because the Flex component performs
its own data loading, the amount of data the client can load is limited
only by the available memory.XML over HTTP

While JSON is quickly emerging as the de facto standard format for
HTTP-based data access, XML, although more verbose, sometimes offers
advantages over JSON. Among the most important XML benefits is strong
client-side API support for XML processing. Although all the recent
browsers provide high-performance XSLT processing APIs, ActionScript
and, by extension Flex, goes a step further: In ActionScript, XML is a
native data type.

You can declare an XML literal in ActionScript thus. The type
parameter indicates that x is of type XML:

var x:XML =
<aTag>
<anotherTag>Some text</anotherTag>
</aTag>

ActionScript uses E4X for XML processing. E4X is an XML processing
DSL developed as part of the EcmaScript standard[7]. E4X is a superset of
XPath, but is not as powerful&8212;nor as complex—as XQuery[8][9]. If
you're comfortable writing XPath expressions, the E4X syntax will be
very familiar.

In addition to the XML type and E4X, XML support in Flex
includes a special-purpose XML collections API, data binding inside XML
data, and numerous XML processing methods on literal XML values as well
as variables.

Flex's deep XML support allows us to further reduce the amount of
client code if we access XML data over HTTP. We will fetch following
XML document from the server:

Loading the above XML document into our Flex application requires
only two minor changes: First, we specify e4x as the
request's result data type, and then we assign the array of XML
book elements as the data grid's data provider:

The expression event.result.book is an E4X XML path
expression that returns an array of XML book objects.

Because XML nodes become properties of the XML object, no changes are
needed for the table column specification in the example. The following
still works:

<mx:DataGridColumn dataField="Title"/>

(Notice, however, that we had to change the Author(s)
property to Authors, as parenthesis cannot form parts of XML
element names.)

Client-Side Data Filters and Data Binding

With typed XML elements populating the data grid, you
can take advantage of various XML-related facilities in Flex, such as an
XML-specific collection object, XMLListCollection.
XMLListCollection, and its non-XML sibling,
ArrayCollection, expose rich list interfaces, providing
filtering and sorting, among features.

To illustrate the concept of client-side data filtering, we implement
the table filter based on the author's name: As a user types, for
example, the letter O into the "Find by author" box, the table
displays only Programming in Scala, whose author's last name,
Odersky, starts with the letter "O":

Figure 1. Client-side data filtering

The following code shows the implementation of the filter UI
panel in MXML (this code goes in the MXML section of the source):

The panel is defined inside an HBox container that lays
out its children horizontally. Note that we assign a
change event listener to the text box with the ID value of
authorName. This handler function, which is defined here
inline, is invoked by the Flex runtime whenever the user types some text
in the box. Note also that both the event handler and the data grid's
data source now refer to an xmlData variable.

That variable is an XMLListCollection that we declare and
populate with XML data (this code goes between the Script
tags in the source file):

Note that xmlData sports a [Bindable]
annotation, and that the grid's data source refers to
xmlData inside curly braces:

<mx:DataGrid dataSource="{xmlData}" ...

Referring to a variable inside curly braces in MXML indicates that
the variable is a source for data binding. When the Flex
compiler sees this notation, it generates appropriate data binding code.
As a result, any changes made to the xmlData variable,
including to the contents of the collection, notify the binding
targets—the data grid, in this case—of those changes.

The collection's filterFunction property is assigned a
function that does the actually filtering. Each collection element is
passed to this function, which must return a boolean value. This
example matches each collection element's Authors
property—remember that the collection element is an XML
object—against what the user entered in the author name text
box.

Remote Object Access

The examples thus far fetched untyped objects from the server: the
property data types of the JSON and XML objects were not specified. Flex
follows some heuristics when dealing with untyped data, and many Flex
applications can get away with relying on duck typing.

More sophisticated client-side data, however, is easier to work with
when strongly-typed data is fetched from the server. That is especially
the case when the server-side data source already defines a
strongly-typed object model with, for example, Java classes.

Similar to Java, ActionScript also supports strongly typed objects.
In such objects, every property, or field, has a well-defined type at
compile time. Several frameworks allow a Flex application to exchange
strongly-typed objects with a server. One popular tool
for that task is BlazeDS[10].

BlazeDS is developed as an open-source project, but it also forms the
foundation of Adobe's Flex Data Services product. BlazeDS consists of
two main components: a serialization framework between Java and
ActionScript objects, and a messaging framework between Flex and
enterprise Java applications.

Java-to-ActionScript Serialization

BlazeDS's serialization framework is an implementation of the Action
Message Format (AMF) protocol, a binary, on-the-wire serialization
protocol for Flash Player[11]. AMF is rather intelligent about dealing with
circular references, as well as with resolving object types. Being a
binary protocol also means that AMF minimizes network overhead.

Although many BlazeDS serialization aspects can be customized,
BlazeDS's defaults are reasonable for most applications. Serialization
between ActionScript and Java classes requires just four steps:

Define identical property names in the Java and ActionScript
classes. For instance, if a Java class has an publisher
field, the corresponding ActionScript class should also have a similarly
named property of the same type (Publisher).

The ActionScript class must be decorated with a
RemoteClass annotation.

The Java class must have a default, no-arg constructor.

The Java class must have bean-style properties.

For example, the server-side object model of this example may consist
of Book and Publisher Java classes, along
with an InventoryManager data access object:

Because BlazeDS's requirements on server-side objects are easily
satisfied in most enterprise applications, providing remote access to
server-side Java objects from Flex clients can be accomplished with
minimal changes to a Java Web application. (Remote object invocation
with BlazeDS is not limited to server-side objects defined in Java: A
forthcoming article will describe how to invoke any JVM-hosted object
from Flex, and will illustrate that with an example using Scala objects
on the server.)

Note that because ActionScript supports properties, there is no need
to define JavaBeans-style setter and getter methods. Note also that we
do not need a client-side representation for
InventoryManager.

Remote Method Invocation

In addition to serialization, BlazeDS also provides a server-side
infrastructure that enables a Flex application to directly invoke
methods on a Java object running in a Web container. In this example, we
want to invoke InventoryManager's
getCurrentInventory() method.

On the server, BlazeDS consists of a set of JAR files and a handful
of configuration XML documents. You can drop the JARs in a Web
application's lib directory, and the XML files in the
WEB-INF directory. The entire client-server communication,
including serialization on the server, takes place via
flex.messaging.MessageBrokerServlet, provided as part of
BlazeDS. Thus, you must add this servlet to your application's
web.xml file:

The servlet parameters tell the servlet where to find its
configuration files. One of those configuration files, inside the
flex directory in this example, configures remote access to
a server-side Java object's methods. To register
InventoryManager for remote method invocation, add the
following to the BlazeDS remoting configuration file:

The above configuration instructs BlazeDS to create an instance of
InventoryManager, and make it available in the application
scope. As a result of these configuration options:

When the Web app starts up, BlazeDS instantiates a servlet that
listens for incoming remote calls. The servlet creates an instance of
InventoryManager and saves it in the Web application
context with the name inventorymanager.

An incoming call from a Flex client specifies the desired object's
name, inventorymanager, the name of the method to invoke,
as well as parameters for the method.

BlazeDS finds the specified object, serializes the parameters from
the AMF format to Java objects, invokes the method, serializes the
return values back to the AMF format, and send the result back to the
client.

On the client, we need only to change references from
HTTPService to RemoteObject:

Because we now expect a list of Books from the remote
call, we replace the XMLListCollection with an
ArrayCollection.

The remote object reference represents the server-side
InventoryManager; it is left untyped on the client, as we
only need to invoke one method on this object. We refer to the remote
object by the name it was given in the server-side configuration (see
above).

The remote method invocation in this example does not consume any
parameters, and returns a collection of typed Book
ActionScript objects. Not only is Book typed, but each
book's publisher parameter is serialized into an
ActionScript Publisher object.

Notice that the remote operation is invoked via the Java method name,
inventoryManger.getCurrentInventory(). Flex packages the
remote invocation into a message, with the remote object and method
names as properties of the message.

Apart from changing the books collection and the remote data
invocation, everything else in the Flex client remains the same,
including the filter function and the datagrid. But in this version, the
Flex complier will catch typing errors during development, as
Book and Publisher are now statically typed
objects.

Summary

The examples in this article illustrated Flex's ability to
incrementally add rich-client features to a Web application. That
capability makes Flex a great tool for agile development. By replacing
parts of an HTML page with embedded Flex components, a Flex client can
arrange its own interaction with server-side data sources, including
invoking remote Java objects of an enterprise Java Web application. A
forthcoming article in this series will extend these concepts to another
JVM-based language, illustrating Flex's integration with server-side
Scala objects.