Chapter 11. Flex on Grails

This chapter covers

  • Integrating Flex with Groovy and Grails
  • Installing the Grails Flex Plugin
  • Exposing a Grails service to Flex
  • Integrating Flex with JMS

Not all real-world development is against an existing application. Every once in a while you have fun developing new code. What do you do when you want to rapidly prototype a data-driven application with Flex? With the Flex part it’s easy enough to develop a UI, but what about the backend? You could always develop a Java-based backend using the same methods and techniques we described throughout this book, or you could take advantage of another framework, such as Grails, to quickly get your data-driven backend off the ground.

11.1. Why Groovy and Grails?

Groovy has been affectionately called Java 2.0 by many in the Java world, so it should be no surprise that you can integrate with Groovy and Grails as easily—and in some aspects more easily—as in previous chapters.

 

Groovy is Java 2.0

“Groovy is a lot like Java 2.0, if someone set out to completely rewrite the Java language today. Rather than replacing Java, Groovy complements it, providing a simpler, slicker syntax where the type checking is done dynamically at runtime. You can use Groovy to write Java applications on the fly, to glue together Java modules, or even to extend existing Java applications—you can even use Groovy to unit test your Java code. And the beauty of it is, Groovy lets you do all these things faster—sometimes a lot faster—than you would if you were writing pure Java code.”

Andrew Glover from his Fluently Groovy series on IBM DeveloperWorks (http://www.ibm.com/developerworks/edu/j-dw-java-jgroovy-i.html)

 

You may be wondering “Why Flex and Grails?” To which we respond, “Why not?” In this final chapter we’re going to demonstrate how you can quickly build and prototype data-enabled Flex applications, leveraging the rapid development provided by Groovy and Grails coupled with the powerful Grails plugin for Flex. Whether your intent is to spike out a particular piece of functionality or to build a complete application, there are few options that will allow you to develop as rapidly as Grails.

We’re going to assume that you are at least somewhat familiar with both Groovy and Grails, but if you’ve never seen or done any development using either, you should still be able to follow along. We’ll show idiomatic Groovy code but won’t go into too much detail about what the code does as that is beyond the scope of this chapter. If you want to learn more about Groovy we suggest starting with the Groovy homepage (http://groovy.codehaus.org) or by reading Groovy in Action, Second Edition by Dierk Koenig (http://www.manning.com/koenig2/), published by Manning Publications. In this chapter we’ll be building a simplified contact management application called Flex Contacts. You’ll build a single Master-Detail screen that you can use to track your contacts as shown in figure 11.1

Figure 11.1. The sample application

Before you start writing the application, you’ll need to install Grails.

11.2. Downloading and installing Grails

Installing Grails is a rather simple task. Point your browser to the Grails project downloads page (http://grails.org/Download) and download the appropriate distribution for your platform. This chapter was written using Grails 1.1.2, which was the latest stable distribution available at the time of writing. There is no reason to install Groovy separately because it’s included with the Grails distribution. Grails is available in two main forms, a binary distribution and a source distribution. Download the binary distribution in either Zip or Tar/GZ format, depending on your operating system.

After you’ve downloaded the binary distribution for Grails, unzip the Grails distribution to a folder such as c:devgrails-1.1.2. Then create a GRAILS_HOME environment variable and point it to the same folder. As a last step, append GRAILS_HOMEin to your PATH variable so that you can run the Grails executable from the command line. When you’ve finished, open up a command line and type grails –version and you should see output similar to this snippet.

C:dev> grails -version

Welcome to Grails 1.1.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: C:devgrails-1.1.2

Base Directory: C:dev
...

Congratulations! You’ve got Grails installed and configured. Now let’s move on to creating the Grails application.

11.3. Creating the Grails application

Here’s where you see one of the first examples of Grails’ convention over configuration way of doing things. To create your Grails application, you must open a command line and navigate to the folder where you want to create your Grails application, for example c:devprojects and type the following command.

C:devprojects> grails create-app flex-contacts

With that one simple command Grails has enough information to generate your project for you. No hard to remember or cryptic command line parameters, one simple concise command and Grails creates the project structure and installs all the necessary dependencies. You don’t even have to install a database server or servlet container to run the application; that’s all included out of the box when you create your Grails application. If you think that was easy, wait until you see how easily you can add functionality to your Grails application using plugins. But first, let’s continue building the Grails application by starting with defining the domain model.

11.3.1. Create the Contact domain model

Next you’ll create the domain class that will be responsible for holding contact information. For this you’ll need only one domain object called Contact. Create the Contact object by issuing the following command:

C:devprojectsflex-contacts> grails create-domain-class contact

This will create the Contact domain model class in the grails-app/domain folder within your flex-contacts project. In the Contact domain model, you’re going to add a few simple properties for persisting the contact information such as first name, last name, and address information, as well as simple validation constraints. Here is what your completed Contact.groovy file will look like.

Listing 11.1. Contact.groovy file

The Contact class contains fields that you’ll need to hold things like first name, last name, and address . You’ve also defined a few constraints so that you can validate that you get all the information you need from the frontend. You’ve also implemented a toString() method to provide a more meaningful implementation than the default. Now let’s create the service that you’ll be exposing to the Flex application.

11.3.2. Create the ContactService

To expose your Grails application to the Flex frontend, create a service that will expose the functionality for your application to perform CRUD operations on your Contact domain object. To do this you issue the following command on the command line:

C:devprojectsflex-contacts> grails create-service contact

This will create a class named ContactService, shown in listing 11.2, in the grails-app/services folder. The ContactService will contain the methods you’ll be exposing to Flex to consume as a remote service. Inside the ContactService.groovy file you’ll implement a few simple methods to enable your Flex application to get a list of all the contacts in the database, get a specific contact, save a contact, and delete a contact from the database.

Listing 11.2. ContactService.groovy file

Most of the ContactService class should look familiar to you. The only line that may look odd is that which contains the code static expose = ['flex-remoting'] . This single line of code is all you need to expose this service to Flex so that you can call any of the service methods from your Flex application. You also make all of the service methods in your service transactional by setting the transactional property to true . The Flex plugin for Grails, which we’ll install in a bit, follows the Grails philosophy of convention over configuration in that it abstracts much of the configuration that you would have needed to build had this been a Java application leveraging either BlazeDS or LiveCycle Data Services to expose this functionality.

11.3.3. Bootstrap sample data

The last step building the Flex client is to bootstrap your application with sample data so that you have contact information in the database when you first run it. This will also allow you to see that the Flex remoting is working correctly. To do this you add the code shown next to the BootStrap.groovy file in the grails-app/conf folder of your application.

Listing 11.3. BootStrap.groovy file

Bootstrapping data in Grails allows you to have data injected into the application each time you restart it. You do this by creating a couple of Contact objects in your BootStrap.groovy file and call save() on them to persist them to the database. This is a helpful feature of Grails as you move through development and beats having to manually enter contacts every time. You would typically use this file for bootstrapping any kind of initial data in your application, such as states and state codes. Now you’re ready to begin developing the Flex frontend for the Grails application you created.

11.4. Getting rich with Flex

Now that you have created your Grails application you can move on to the task of creating the Flex client that will integrate with Grails. You’ll start by installing the Flex plugin for Grails, then add the Flex application to the Grails project.

11.4.1. Installing the Flex plugin

From the root of the project directory enter the following command to install the Flex plugin for the Grails application:

C:devprojectsflex-contacts> grails install-plugin flex

This command will pull down all of the Flex libraries your application needs to be able to compile the Flex application. This may take time because the plugin has to pull down many dependencies. After all the messages have scrolled by, the plugin should be successfully installed. Like many other features in Grails development, enabling an application for Flex integration is extremely simple and declarative. No configuration files need to be created, though some configuration files are contained within the web-app/WEB-INF folder if you need to fine-tune the Flex compiler settings.

11.4.2. Creating the domain classes in Flex

You can begin the Flex development by creating a domain object in ActionScript. This object will act as a data transfer object of sorts, allowing you to deal with full-fledged objects when your service returns data to the client. This approach avoids having to deal with the pseudoproxy objects that Flex would wrap your objects into if it didn’t have anything to translate it into.

When you installed the Flex plugin in the previous step, it created a flex folder under web-app/WEB-INF. Inside this folder resides another folder called user-classes, which contains a file that clues you into where you’re supposed to place your ActionScript classes, appropriately called add_your_as_and_swc_files_here. Create a file in the user-classes folder called Contact.as.

Listing 11.4. Contact.as

The code should resemble the client side domain classes that you created earlier for your FlexBugs application. Take note of the annotations at the top of the file, [Bindable] and [RemoteClass] . The [Bindable] annotation lets Flex know that whenever one of the values changes in this object, it should notify anything else that is bound to this object to let it know that it should update itself. We didn’t utilize data binding in our other application but for this quick example we did, in order to keep the examples shorter.

In case you have forgotten, the [RemoteClass] annotation allows a Flex class to be mapped to a server-side class. The Contact.as class is mapped to the Contact.groovy domain class you created earlier. Because you’re using a package structure in this trivial example, you don’t need to fully qualify it here; if your domain object in Grails fell under a specific package, you would have to fully qualify that object in this annotation for it to work correctly.

You need to add a couple of Hibernate-specific properties to your Contact domain class for your application to behave as intended, along with all the normal public properties that you need to include for the data fields you want to be able to be persist.

11.4.3. Creating the Flex application

Now that you’ve got your domain object created for the client side, you’ll need to create a file to contain the main Flex application itself, which will be called main.mxml and is created in the web-app folder of your Grails application.

You’ll break this down into bite-sized chunks that should be easier to digest than if you were simply presented with the end state of the application. First you’ll start by creating the Application object. As in the other sample application, your Flex application will have the Application element as its root node of the MXML file as shown in this snippet.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*"
layout="vertical"
creationComplete="contactService.getContacts()"
viewSourceURL="srcview/index.html">

</mx:Application>

Now that you’ve got the base application started, you’re ready to start laying out the basic layout.

Defining the layout

Look at figure 11.1 again, and take note that you’ve got three main containers in use for this application. You’ve got the header at the top containing the text Flex Contacts on Grails, and two panels containing the master view and the details view. Let’s create the basic layout for your application. To do that you’re going to leverage a couple of layout components: HBox and Panel. We’ll break up the Main.mxml and look at each section individually.

Listing 11.5. Main.mxml (a)

This listing shows the code used to generate the layout of our application. In the snippet we saw previously, you specified that your application use vertical as its main layout method so your components will flow vertically down as you add them to the application. Here you start by adding an HBox container containing a single Text component. This Text component contains the text for our title that appears in the header. Next you wrap two Panel containers in another HBox so they’ll show up side by side in the application. These two Panel components will house the master view and detail view .

Creating the master view

Inside the first Panel container you’ll create the master view using the DataGrid component, which allows you to display tabular data rather painlessly.

Listing 11.6. Main.mxml (b)

This portion of the listing shows the code to create the contacts DataGrid as well as to define the columns to be displayed. You may have noticed the items contained within the curly braces {}; this is how to specify data binding in a Flex application. You’ve bound the dataProvider property of the DataGrid to the contactsList variable, which you’ll define later. This is where you’ll store the results from your RemoteObject method call to get all the contacts. Notice that all of your column names should match what you defined in the Contact object you created earlier. This allows Flex to automatically figure out which data field to map to which column.

A ControlBar will contain all of the buttons needed to interact with this control.

Creating the detail view

Now that the master view has been created, it’s on to the detail view. The detail view will provide a mechanism for editing and updating your contacts. Although we could have allowed editing right in the DataGrid itself, it wouldn’t have made for a good example and doesn’t show off the power of data binding in Flex.

Listing 11.7. Main.mxml (c)

Here is the code for the detail view in which you leverage another container object, the Form component . Unlike its HTML counterpart, the Form component in Flex is strictly a container. You don’t need to have your fields wrapped in a Form component to post data to the server side.

Inside the Form component you define a series of FormItem components that contain the GUI form components used for data entry. These should be fairly self-explanatory. Take note of the data binding syntax in the text attributes for these components. This indicates that you’ll be binding the text values of these components to a variable called selectedContact. As a last step, you add another ControlBar as you did for the master view to contain any buttons needed to control the application.

11.4.4. Adding the RemoteService

Flex has a few components that enable it to communicate with the server side, namely HTTPService, WebService, and RemoteService. In a nutshell WebService facilitates easy communication with SOAP-based web services. HTTPService allows you to consume and call other web services using a variety of protocols such as XML and JSON and is the best choice if you’re trying to interact with some sort of RESTful resource. RemoteService leverages Adobe’s binary AMF ) protocol, which tends to give the best performance of the three.

Listing 11.8. Adding the RemoteService
<mx:RemoteObject id="contactService" destination="contactService">
<mx:method name="getContacts"
result="handleGetContacts(event.result)"
fault="showFault(event)"/>
<mx:method name="update" fault="showFault(event)"/>
<mx:method name="remove" fault="showFault(event)"/>
</mx:RemoteObject>

As stated previously you’re going to use the RemoteObject component to facilitate communication with the server side, and you’ve defined the methods that you’ll be calling so you can define the callback methods that you’ll be using to handle the results coming back from the server, as well as any faults.

11.4.5. Putting it all together

You’re almost done. You now put it all together and add methods that you’ll call to handle events from the UI.

Listing 11.9. Main.mxm (d)

Most of what is shown in the listing should make sense. Here you define a Contact object in MXML rather than ActionScript . Notice that you’re also performing data binding back to the form components, creating a two-way binding between the selectedContact variable and the detail form. Next define the event handler and fault handler for the RemoteObject that you defined in listing 11.8. Last you have all the event handlers for the components in the master view and detail view .

Now that you’ve completed this part of the application, you can start up your Grails application by executing grails run-app and navigating to the application. After your application is running, fire up your browser and navigate to http://localhost:8080/flex-contacts/main.mxml and you should see something resembling figure 11.1. You’ve got a functional Flex application running on Grails. Over the next few sections you’re going to modify this simple example to leverage JMS and ActiveMQ.

11.5. Install the Grails JMS and ActiveMQ plugins

Next you’re going to demonstrate the ability of your Grails application to push data out to the Flex application using Flex components that integrate with JMS to produce and consume messages. This will allow you to remove the Refresh button and some of the plumbing involved to refresh the Flex DataGrid when a user adds, edits, or deletes a contact. This helps clean up the client by reducing the amount of view logic and complexity. To install the Grails JMS plugin from the root of the project directory use this snippet:

$ grails install-plugin jms

Then do the same for the ActiveMQ plugin:

$ grails install-plugin activemq

After these plugins are installed you’re ready for development. The beauty of Grails conventions is that they hide most of the complexity of plugging in new external frameworks such as JMS and ActiveMQ. It’s worth mentioning that the JMS and ActiveMQ plugins are still fairly new but seem to do the job for the most common situations. Now that you have the plugins for making the application JMS-enabled, you can move on to updating the Grails application code. Only a few things need to happen to provide a JMS service to the Flex client and these are described next.

11.6. Add the ActiveMQ Spring bean

There’s one configuration detail you need to tend to. You need to configure the JMS plugin to leverage the ActiveMQ broker. You can do this either by adding a Spring bean to the resources.xml or by adding the bean using the Groovy DSL approach. The snippet that follows demonstrates adding the bean by using the DSL approach of adding your connection factory as a bean in the resources.groovy configuration file located in the grails-app/conf/spring folder of the application.

// Place your Spring DSL code here
beans = {
connectionFactory(org.apache.activemq.ActiveMQConnectionFactory) {
brokerURL = "vm://localhost"
}
}

The code shown here is the Groovy way to configure Spring beans in Grails, and defines a connectionFactory bean of type ActiveMQConnectionFactory and initializes its brokerURL property to point at vm://localhost. Now that you got the configuration out of the way you can move on to tweaking the Contact domain class.

class Contact implements Serializable {
...
}

To store messages on a message queue the objects need to implement the Serializable interface. You need to update the Contact class to implement the Serializable interface as shown previously.

11.7. Subscribe the Flex client to the Grails JMS service

Now you’re ready to configure the Flex framework as a JMS consumer. First you’ll start with the BlazeDS configuration.

11.7.1. Update the services-config.xml

You need to configure Flex with a contactsTopic in the top-level BlazeDS configuration file. When the Flex plugin is installed it places the services-config.xml inside the /web-app/WEB-INF/flex directory. Let’s edit it by adding the Flex message service inside the services element. The full services-config.xml is included in the next listing for clarity and to show that the order of the bean definitions has significance. Inside the services element the Grails service comes first followed by the JMS configuration.

Listing 11.10. services-config.xml

The bulk of the services-config.xml file was generated when you installed the Flex plugin; however you need to add a new service section for the JMS service that you’ll be using , and a section stating that you’d like the service to use the JMS adapter . You also need to configure the JMS topic that you’ll be communicating with . To see all the options you’ve defined, refer to the BlazeDS user documentation at http://livedocs.adobe.com/blazeds/1/blazeds_devguide/. Now let’s move on to modifying our ContactService to utilize your messaging.

11.7.2. Modifying the ContactService

The existing ContactService class is relatively simple. Here is the updated ContactService class with the additions for publishing the updated contact list.

Listing 11.11. ContactService updated

You add the publishContacts() method to publish updates to the topic you configured in the services-config.xml file. The sendPubSubJMSMessage takes two arguments. The first argument is the JNDI destination name defined in your topic, and the other is the list of contacts. Next, you wire up the update and remove methods to publishContacts when they are invoked. Other methods can be called depending on your needs. Because a topic supports the publish/subscribe model, it is used for one-to-many messaging which works well with the Contacts application. For one-to-one or point-to-point messaging you would use a queue instead. To learn more about the JMS plugin, visit the Grails website at http://www.grails.org/JMS+Plugin.

11.7.3. Update the Main.mxml

The final thing to do before relaunching the contacts application is to update the Flex client main.mxml file. You will add the JMS service to the mix and make other minor changes. Let’s start with the Application element.

Listing 11.12. Main.mxml (e)

The Flex Consumer object is used to connect to the contactsTopic. When the application initializes, you need to subscribe to the contactsTopic. To do so you configure the creationComplete event definition to call subscribe on the jms-Consumer. The consumer listens for changes from the ActiveMQ broker and uses the handleGetContacts method to consume the data. This method updates the contact list when there are updates.

From here, the application will work fine as is. There are some things to clean up because we’re now making the application JMS aware and they are unnecessary overhead.

Listing 11.13. Main.mxml (f)
private function deleteContact(selectedContact:Contact):void {
contactService.remove(selectedContact);
}

private function updateContact(contact:Contact):void {
contactService.update(selectedContact);
}

...

<mx:ControlBar>
<mx:Button label="Delete Contact"
enabled="{contactsGrid.selectedItem != null}"
click="deleteContact(selectedContact)"/>
</mx:ControlBar>

You remove the calls to the getContacts() method on your RemoteObject when deleteContact and updateContact are invoked. These calls were necessary, prior to enabling JMS, for the DataGrid to be refreshed whenever the contact list was updated. You can also remove the Refresh button. The Flex consumer will get updates every few seconds and will invoke the method that will update the DataGrid so there’s no more need for these extra calls to the server side. The consumer itself can be further configured if different timing or other options are needed.

To illustrate the push of information from the server to the client, start the Grails application by opening a command line and navigating to the project folder. Type the command grails run-app, which will start the embedded jetty container to run the application. Now open two browsers and point them both to the Flex application at http://localhost:8080/flex-contacts/main.mxml. Then as you make updates in the one window, you should see the contacts being updated in the other browser window—no more having to manually refresh the application to pick up other user’s changes.

11.8. Summary

In this final chapter we showed you how to rapidly prototype data-enabled Flex applications using Groovy and Grails in combination with the Flex plugin for Grails. You started by defining the domain in Grails and exposing some services for your Flex application to use, and the Flex application itself. You then went one step further and enabled your application to use JMS and ActiveMQ for real-time updating of your UI.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.205.27