Let’s do it! Flex and Grails

fx_grailsI have to admit, that I’m quite enthusiastic about new technologies, especially RIA (Rich Internet Applications) solutions. Recently I was going to give a try to JavaFX and Adobe Flex. And since I’m a big fan of Grails – my goal was to connect these two technologies.

As a result I have Flex front-end application with Grails running in the background, which is a really nice combo. Especially, when we can develop our Flex part in excellent IDE – FlexBuilder. Some people say, that it’s based on Eclipse. Others say, that it have decent visual design tool. Well, all of this is true. It’s simply pleasure to work with this tool. And I have a feeling, that it’s not my last post about Flex and FlexBuilder.

Flex part

Let’s create a New Flex Project. I was working with FlexBuilder, so it automaticly created all folders and opened our main mxml file. Flex code:  Show  |  Hide 

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” creationComplete=”listService.send()”>
<mx:HTTPService id=”listService” url=”http://localhost:8080/supernotes/note/list” useProxy=”false” method=”GET”/>
<mx:HTTPService id=”saveService” url=”http://localhost:8080/supernotes/note/save” useProxy=”false” method=”POST” result=”listService.send()”>
<mx:request xmlns=””>
<id>{note_id.text}</id>
<author>{author.text}</author>
<priority>{priority.text}</priority>
<message>{message.text}</message>
</mx:request>
</mx:HTTPService>
<mx:HTTPService id=”deleteService” url=”http://localhost:8080/supernotes/note/delete” useProxy=”false” method=”POST” result=”listService.send()”>
<mx:request xmlns=””>
<id>{dg.selectedItem.id}</id>
</mx:request>
</mx:HTTPService>
<mx:Script>
<![CDATA[
import flash.system.Security;
import flash.system.SecurityPanel;
[Bindable]

private var formatArray:Array = [“Super urgent”, “Normal”, “Laaazy”];
private function clearForm():void {
note_id.text = “”;
author.text = “”;
priority.selectedIndex = 0;
message.text = “”;
}
]]>
</mx:Script>

<mx:VDividedBox x=”0″ y=”-11″ height=”100%” width=”100%” paddingLeft=”10″ paddingRight=”10″ paddingTop=”10″ paddingBottom=”10″>
<mx:Panel width=”100%” height=”300″ layout=”absolute” title=”Create/Update Book”>
<mx:Form x=”10″ y=”10″ width=”930″ height=”138″>
<mx:FormItem label=”ID”>
<mx:TextInput width=”40″ id=”note_id” text=”{dg.selectedItem.id}” enabled=”false”/>
</mx:FormItem>
<mx:FormItem label=”Author”>
<mx:TextInput width=”200″ id=”author” text=”{dg.selectedItem.author}” maxChars=”50″/>
</mx:FormItem>
<mx:FormItem label=”Priority” width=”200″>
<mx:ComboBox id=”priority” selectedIndex=”{formatArray.indexOf(dg.selectedItem.priority)}”>
<mx:dataProvider>{formatArray}</mx:dataProvider>
</mx:ComboBox>
</mx:FormItem>
<mx:FormItem label=”Message”>
<mx:TextInput width=”420″ id=”message” text=”{dg.selectedItem.message}” maxChars=”50″/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar horizontalAlign=”right” height=”70″ y=”156″>
<mx:Button label=”New” click=”clearForm()”/>
<mx:Button label=”Save” click=”saveService.send(); clearForm()”/>
</mx:ControlBar>
</mx:Panel>
<mx:Panel width=”100%” height=”444″ layout=”absolute” title=”List of notes”>
<mx:DataGrid x=”0″ y=”0″ width=”100%” height=”100%” id=”dg” dataProvider=”{listService.lastResult.data.note}”>
<mx:columns>
<mx:DataGridColumn width=”120″ headerText=”ID” dataField=”id”/>
<mx:DataGridColumn width=”320″ headerText=”Author” dataField=”author”/>
<mx:DataGridColumn width=”220″ headerText=”Priority” dataField=”priority”/>
<mx:DataGridColumn width=”320″ headerText=”Message” dataField=”message”/>
</mx:columns>
</mx:DataGrid>
<mx:ControlBar horizontalAlign=”right”>
<mx:Button label=”Delete” click=”deleteService.send()” enabled=”{dg.selectedItem != null}”/>
</mx:ControlBar>
</mx:Panel>
</mx:VDividedBox>
</mx:Application>

Grails part

There is even less work with Grails – we need to create a project, then one domain class and one controller:
 grails create-app supernotes  
 grails create-domain-class Note  
 grails create-controller Note  

Code for Grails NoteController:  Show  |  Hide 

class NoteController {
def index = { redirect(action:list, params:params) }
def list = {
response.setHeader(“Cache-Control”, “no-store”)
def noteList = Note.list(params)
render(contentType:”text/xml”) {
data {
for(i in noteList) {
note {
id(i.id)
author(i.author)
priority(i.priority)
message(i.message)
}}}}}
def save = {
def note
if(params.id) {
note = Note.get(params.id)
}
else {
note = new Note()
}
note.properties = params
note.save()
render “”
}
def delete = {
def note = Note.get(params.id)
if(note) {
note.delete()
}
render “”}}

Code for Grails Note domain class:  Show  |  Hide 

class Note {
String author
String message
String priority
static constraints = {
author(maxLength:20)
message(maxLength:100)
priority(inList:[“Super urgent”, “Normal”, “Laaazy”])
}}

crossdomain.xml

One more thing: we need to put crossdomain.xml file in our grails application (web-app folder) to make sure, that our Flex front-end client will be able to connect to server. Here code for crossdomain.xml:  Show  |  Hide 

<?xml version=”1.0″?>
<!DOCTYPE cross-domain-policy SYSTEM “/xml/dtds/cross-domain-policy.dtd”>
<cross-domain-policy>
<allow-access-from domain=”http://localhost” to-ports=”*” />
<allow-http-request-headers-from domain=”http://localhost” />
</cross-domain-policy>

As we can see, with few lines of code we are getting a decent application – Grails are responsible for data storing and the rest of server stuff, and Flex handles client requests along with excellent GUI. In a nutshell – it’s real pleasure to develop in Grails and it’s a pleasure to make stuff with Flex, especially in FlexBuilder. Stay tuned and share your experience and comments with us!

11 comments

  1. Suggesting people implement a crossdomain that allows access from * is extremely irresponsible. You have opened the site up wide to a variety of exploits. I highly recommend anyone reading this not to follow the crossdomain.xml example posted here.

  2. Thank you for pointing this little mistake Dan. It is indeed very dangerous, especially when server is placed behind firewall, because it enables access to protected areas. Posted crossdomain.xml was used only for the sake of tutorial, but since it really can be dangerous I will change it for more secure. Again thanks for your comment.

    Wojtek

  3. @Alexander:
    thanks for comment, have to admit, that i haven't tried IDEA yet. FlexBuilder has nice visual editing tool, and it speeds up 'layout' design pretty much. Does IDEA have such a tool as well? What i heard about IDEA was excellent code handling – like determining params of created method etc.
    Is it worth trying?

    Wojtek

  4. Maybe you can improve your code presentation areas to make the lines indented and syntax colored.

  5. Good start. Next steps could be using one of the most interesting features of Flex, which is the transparent integration of Flex and Spring using binary AMF3 protocol. My recomendation is to have a look flex plugin, so productive, that I created an application in 5 minutes with 5 simple steps, including plugin installation.

  6. The data flow for the existing grails and flex files are great. But I want to forward from one mxml file to another mxml file while click a button in first mxml file. At the button click event i have to send the request to controller and send response as a url to forward to my next mxml page. But it is not working. Any idea?

  7. Well , the view of the passage is totally correct ,your details is really reasonable and you guy give us valuable informative post, I totally agree the standpoint of upstairs. I often surfing on this forum when I m free and I find there are so much good information we can learn in this forum! http://less-accurate.com/

Comments are closed.