Without BlazeDS (that is, without deploying any Flex-specific component on the server side), Flex applications can access back-end data using either the HTTPService or the WebService.

  • You can use the HTTPService component to send HTTP requests to a server, and consume the response. Although the HTTPService is often used to consume XML, it can be used to consume other types of responses. The Flex HTTPService is similar to the XMLHttpRequest component available in Ajax.
  • You can use the WebService component to invoke SOAP-based web services.

BlazeDS is a series of data services that provide your Flex applications with additional data connectivity options:

  • The Remoting Service allows your Flex application to directly invoke methods of Java objects deployed in your application server.
  • The Message Service provides a publish/subscribe infrastructure that allows your Flex application to publish messages and subscribe to a messaging destination, enabling the development of real-time data push and collaborative applications.
  • The Proxy Service allows your Flex application to make cross-domain service requests in a secure and controlled manner. In other words, it allows your Flex application to access a service available on a domain other than the domain from which the application was downloaded (without having to deploy a crossdomain.xml policy file on the target domain).

BlazeDS is deployed as a set of JAR files as part of your web application. Like the Flex Software Development Kit (SDK), BlazeDS is an open source project. More information is available here.

The objective of this test drive is to give you, in a very short amount of time, an understanding of how the BlazeDS data services work and what they can do. This test drive consists of a series of seven samples kept as concise as possible (typically between 10 and 50 lines of code) to clearly highlight features of interest.

This test drive is the same test drive available in the full download of BlazeDS.

Install the BlazeDS Turnkey Server

Before running any of the sample applications, you will need to install the BlazeDS turnkey server, a ready-to-use version of Tomcat in which the BlazeDS data services have already been deployed along with sample applications. The goal of the turnkey server is to give developers an easy way to run samples and tutorials out-of-the-box.

To install the BlazeDS turnkey server:

  1. Make sure that you have the JDK 1.5 or higher installed, and that you have a JAVA_HOME environment variable pointing to your Java Development Kit installation.
  2. Download blazeds-turnkey-<version>.zip.
  3. Unzip blazeds-turnkey-<version>.zip in /blazeds

    Note: If you unzip blazeds-turnkey-<version>.zip anywhere else, make sure you adjust the path used in these instructions accordingly.

  4. Start Tomcat
    1. Open a command prompt window
    2. Navigate to /blazeds/tomcat/bin
    3. Execute the following command:
catalina run
    1. In your browser, view http://localhost:8400/samples to make sure the installation is successful. You should see the BlazeDS samples home page.

Sample 1: Accessing data using HTTPService

Run the sample:

  1. After installing the turnkey server, you can run the first sample application at http://localhost:8400/samples/testdrive-httpservice/index.html
  2. Click "Get Data". The DataGrid is populated with XML data returned by catalog.jsp
  3. Also notice some of the built-in DataGrid features:
    • Sortable columns (click on a column header)
    • Moveable columns (click on a column header and drag the column to a new position)

Code walkthrough:

Open main.mxml in the testdrive-httpservice/src directory to view the source code of the application.

Using the Flex HTTPService object, you can send HTTP requests to a server, and consume the response. Although HTTPService can be used to consume different types of responses, it is typically used to consume XML. You can use HTTPService with any kind of server-side technology: JSP, Servlet, ASP, Ruby on Rails, PHP, among others. You specify the target service in the url property of the HTTPService object.

Flex provides sophisticated data binding capabilities. You can bind the value of a property to the value of another property, or to an expression in general. In this example, the dataProvider property of the DataGrid is bound (using the curly braces notation) to the lastResult property of the HTTPService object.

HTTPService calls are asynchronous. The result event is triggered on the HTTPService when the data becomes available to the client application. The fault event is triggered if an error occurs on the server side, or if the network becomes unavailable. (For more information on coding result and fault event handlers, see "Sample 5: Updating Data").

By default, the XML document retrieved from the server is deserialized into an object graph. This allows you to navigate through the result using the dot (.) notation. You can also get the result as an XML document by specifying resultFormat="e4x" on the HTTPService. In that case, you can parse the document using E4X (ECMAScript for XML).

The BlazeDS server is not required to use the HTTPService. By default, the application tries to connect directly to the domain specified in the HTTPService url attribute. This will work if one of the two conditions below is satisfied:

  1. The domain specified in the HTTPService url attribute is the domain from which your application was downloaded.
  2. A crossdomain.xml file granting access to your application's originating domain is available on the domain specified in the HTTPService url attribute. More information on crossdomain.xml is available here.

If you want your application to access services available on another domain without deploying a crossdomain.xml file on that domain (for example, because you may not own the target domain), you can set the useProxy attribute of the HTTPService to true, as in this example. In this case, the request is sent to the BlazeDS proxy, which makes the request to the target domain on the client application's behalf. This configuration also provides more control over the access to the service. For example, you may configure the proxy to require authentication before accessing a service, log access to the service, and so on.

When using the proxy, you can specify a logical name in the HTTPService destination attribute instead of specifying a hardcoded value in the url attribute. You then map this logical name to an actual URL in the WEB-INF\flex\proxy-config.xml file. Open this file to see how the catalog destination is configured.

Note that both HTTP and HTTPS are supported. To use HTTPS, specify "https:://…" in the url.

Sample 2: Accessing data using web services

Run the sample:

  1. Run the web services sample by opening the following URL in your browser: http://localhost:8400/samples/testdrive-webservice/index.html.

    Note: Since this application accesses a live web service, you must have an Internet connection to run it.

  2. Click "Get Data". The DataGrid is populated with data returned by the ProductWS web service hosted on livecycledata.org.

Code walkthrough:

Open main.mxml in the testdrive-webservice/src directory to examine the source code of the application.

You can also view the WSDL file for the web service used in this example at http://livecycledata.org/services/ProductWS?wsdl.

Using the WebService tag, you can invoke SOAP-based web services deployed in your application server or anywhere on the Internet. Objects returned by a web service are automatically deserialized into ActionScript objects. Similarly ActionScript objects passed as arguments to a web service operation are serialized according the WSDL description.

Notice that this example also added DataGrid column definitions (using DataGridColumn).

The BlazeDS server is not required to use the WebService. By default, the application tries to connect directly to the domain specified in the WebService wsdl attribute. This will work if one of the two conditions below is satisfied:

  1. The domain specified in the WebService wsdl attribute is the domain from which your application was downloaded.
  2. A crossdomain.xml file granting access to your application's originating domain is available on the domain specified in the WebService wsdl attribute. More information on crossdomain.xml is available here.

If you want your application to access services available on another domain without deploying a crossdomain.xml file on that domain (for example, because you may not own the target domain), you can set the useProxy attribute of the WebService to true as in this example. In this case, the request is sent to the BlazeDS proxy, which makes the request to the target domain on the client application's behalf. This configuration also provides more control over the access to the service. For example, you may configure the proxy to require authentication before accessing a service, log access to the service, and so on.

When using the proxy, you can specify a logical name in the WebService destination attribute instead of specifying a hardcoded value in the wsdl attribute. You then map this logical name to an actual URL in the WEB-INF\flex\proxy-config.xml file. Open this file to see how the ws-catalog destination is configured.

Flex supports both RPC-encoded and document-literal web services. Like HTTPService, WebService calls are asynchronous; you can set up result and fault event handlers.

Sample 3: Accessing data using Remoting

Run the sample:

  1. Run the remoting sample by opening the following URL in your browser: http://localhost:8400/samples/testdrive-remoteobject/index.html.
  2. Click "Get Data". The DataGrid is populated with data returned by the getProducts() method of the ProductService Java class.

Code walkthrough:

Open main.mxml in the testdrive-remoteobject/src directory to view the source code of the application.

Open the following files in a text editor to see the source code for the server side of the application:

  • {context-root}\WEB-INF\src\flex\samples\product\ProductService.java
  • {context-root}\WEB-INF\flex\remoting-config.xml

Using RemoteObject, you can directly invoke methods of Java objects deployed in your application server, and consume the return value. The return value can be a value of a primitive data type, an object, a collection of objects, an object graph, and more.

The value of the destination property of RemoteObject is a logical name that is mapped to a fully qualified Java class in remoting-config.xml.

Java objects returned by server-side methods are deserialized into either dynamic or typed ActionScript objects. In this example, there is no explicit ActionScript version of the Product Java class. Product objects are therefore deserialized into dynamic objects. Sample 5 uses an explicit Product class in ActionScript.

Like HTTPService and WebService, RemoteObject calls are asynchronous. Use the result and fault events of the RemoteObject to handle results and errors (For more information on coding result and fault event handlers, see "Sample 5: Updating Data").

Sample 4: Flex programming model 101

Run the sample:

  1. Run the Flex programming model 101 sample by opening the following URL in your browser:http://localhost:8400/samples/testdrive-101/index.html.
  2. Click a phone in the list. The details for the selected phone will appear in the right panel.

Code walkthrough:

Open the following files in the testdrive-101/src directory to view the source code of the application:

  • main.mxml
  • Thumb.mxml
  • ProductView.mxml

Like in any other object-oriented programming language, a Flex application consists of a collection of classes. Using Flex, you can create classes using MXML or ActionScript. You typically create view classes in MXML, and model and controller classes in ActionScript.

When you create an MXML file, you are actually creating a class. The root node of the MXML document indicates the class you extend. For example, creating a file named MasterDetail.mxml with an <Application> root node is equivalent to creating an ActionScript class with the following signature:

public class MasterDetail extends Application { }

Similarly, creating a file named ProductView.mxml with a <Panel> root node is similar to creating a class with the following signature:

public class ProductView extends Panel { }

Once you have defined a class, you can use it programmatically or declaratively (as a tag in MXML) without the need for an additional descriptor file. Public properties are automatically available as tag attributes. For example, MasterDetail.mxml defines the <ProductView> tag and binds its product attribute to the selected item in the product list.

Also notice the support for CSS style sheets.

Sample 5: Updating data

Run the sample:

  1. Run the data update sample by opening the following URL in your browser: http://localhost:8400/samples/ testdrive-update/index.html .
  2. Select a phone
  3. Modify some data in the right panel. For example, change the price.
  4. Click Update. The changes are sent to the back end and persisted in the database by the ProductService class.

Code walkthrough:

Open the following files in the testdrive-update/src directory to view the source code of the application:

  • main.mxml
  • ProductForm.mxml
  • Product.as

Open the following files in a text editor to examine the source code for the server side of the application:

  • WEB-INF\src\flex\samples\product\ProductService.java
  • WEB-INF\flex\remoting-config.xml

Product.as uses the [RemoteClass(alias="flex.samples.product.Product")] annotation to map the ActionScript version of the Product class (Product.as) to the Java version (Product.java). As a result, Product objects returned by the getProducts() method of ProductService are deserialized into instances of the ActionScript Product class. Similarly, the instance of the ActionScript Product class passed as an argument to the update method of the RemoteObject is deserialized into an instance of the java version of the Product class on the server side.

Sample 6: Publish/Subscribe messaging – the data push use case

Run the sample:

In this example, a Java component publishes simulated real time values to a message queue. The Flex client subscribes to that queue and displays the values in real time.

  1. To start the server-side feed component, open the following URL in your browser: http://localhost:8400/samples/testdrive-datapush/startfeed.jsp.
  2. Run the data push sample by going to http://localhost:8400/samples/testdrive-datapush/index.html.
  3. Click the "Subscribe to 'feed' destination" button. Pushed values will appear in the text field.
  4. To stop the feed, use http://localhost:8400/samples/testdrive-datapush/stopfeed.jsp.

Code walkthrough:

Open FeedClient.mxml in the testdrive-datapush/src directory to view the source code of the application.

Open the following files in a text editor to examine the application's server-side source code:

  • WEB-INF\src\flex\samples\feed\Feed.Java
  • WEB-INF\flex\messaging-config.xml

Flex supports publish/subscribe messaging through the BlazeDS Message Service. The Message Service manages a set of destinations to which Flex clients can publish and subscribe. Flex provides two components, Producer and Consumer, which are used to respectively publish and subscribe to a destination. To subscribe to a destination, use the subscribe() method of the Consumer class. When a message is published to a destination you subscribed to, the message event is triggered on the Consumer.

In Feed.java, the BlazeDS Java API (specifically, MessageBroker and AsyncMessage) is used to publish messages to the destination. Another option to exchange messages between Flex and Java applications is to map destinations to JMS topics, essentially allowing a Flex client to publish and subscribe to JMS topics. In addition to JMS, the Message Service adapter architecture allows you to integrate with any kind of messaging system.

Messaging destinations are configured in messaging-config.xml. A key element of a destination configuration is the channel used to exchange data between the client and the server. Using BlazeDS, a messaging destination typically uses a streaming or a polling channel.

  • Using a streaming channel, the server response is left open until the channel connection is closed, allowing the server to send down incremental chunks of data to the client. Because HTTP connections are not duplex, a single streaming AMF or HTTP channel actually requires two browser HTTP connections in order to send data in both directions. One is needed for the streamed response from the server to the client that the channel hangs on to. A second transient connection is also needed, and is drawn from the browser pool only when data needs to be sent to the server. This second transient connection is immediately released back to the browser's connection pool when it is no longer required.
  • A polling channel can be configured with a simple interval or with a sever wait if data is not immediately available (long polling). In either case, each poll response completes the request. Browser HTTP 1.1 connections are persistent by default, so the browser will likely recycle existing HTTP connections to send subsequent poll requests, which lowers the overhead for polling.

The streaming channel is the best option when near real time communication is required.

Difference between Microsoft Internet Explorer and Firefox:

Browsers have a limited number of connections that they can maintain per session. The maximum number of connections allowed, as well as the way sessions are handled, are browser specific.

In Internet Explorer, the maximum number of connections per session is two, but if you start multiple Internet Explorer instances from an operating system menu or shortcut, each instance is started in a different process and maintains its own session. However, if you start a new Internet Explorer window using CTRL+N in an existing Internet Explorer instance, that new window shares the same session as the Internet Explorer instance that created it. In other words, you can have an unlimited number of applications using HTTP streaming to get data from the server as long as these applications are started in different Internet Explorer processes. If you start multiple Internet Explorer windows using CTRL+N, you are limited to the maximum number of connections per session, in this case two.

In Firefox, the maximum number of connections per session is eight. If you start multiple Firefox instances from an operating system menu or shortcut, all the instances are started in the same process and share a single session. Since the browser will typically need one connection for traditional HTTP requests, you can theoretically have a maximum of seven HTTP streaming connections with the server across all your browser instances.

In either case, if the limit of connections per session is reached, the next attempt to connect to the server using a streaming channel will fail. BlazeDS provides an elegant fall back mechanism to handle such situations: The client always tries to connect using the first channel in the list of channels defined for the destination in messaging-config.xml. If that connection fails, the client automatically falls back to the next channel in the list. In this example, we defined the following default ChannelSet for all the messaging destinations:

<default-channels> <channel ref="my-streaming-amf"/> <channel ref="my-polling-amf"/> </default-channels>

In other words, the client application will try to connect using a streaming channel first and will fall back to a polling channel if the streaming connection fails.

Sample 7: Publish/Subscribe messaging – the collaboration use case

Run the sample:

  1. Run the chat sample by opening the following URL in your browser: http://localhost:8400/samples/ testdrive-chat/index.html .
  2. Open the same URL in another browser session to open a second instance of the chat application
  3. Type a message in one of the chat clients and click "Send". The message appears in the two chat clients.

Code walkthrough:

Open Chat.mxml in the testdrive-chat/src directory to view the source code of the application.

Open the following files in a text editor to examine the source code for the server-side of the application:

  • WEB-INF\flex\messaging-config.xml

This sample builds on the concepts and APIs introduced in the previous example. To publish a message from a client, use the send() method of the Producer class.

The messaging and real time infrastructure available in BlazeDS enables collaboration and data push applications to be built in a scalable and reliable manner while preserving the lightweight web deployment model.