Wednesday, September 2, 2009

Grails : reverse url mappings using g:link tag

Hi friends,

Reverse url mappings is needed when url is to be generated based on controller and the action. It can be implemented using g:link tag or createLink.


UrlMappings.groovy
"/book/$title"(controller:'book', action:'show')


When the controller and action name are variables, could be any and we need to get the right url. Then we can use g:link


controlller="book"
actionName="show"
myTitle="Grails-in-action"

<g:link controller="$controllerName" action="$actionName" params="[title:myTitle]"/>


The generated url would be "/book/Grails-in-action"

One more thing, since g:link tag generates anchor tag at the end, we can g:link tag around button, image etc. just like the anchor tag.
Hope the above code helps.

Wednesday, August 12, 2009

Grails : performance tuning using caching

Hi friends,

In one of our projects, we had lot of performance issues with the portal. That project had all the data loaded in the memory, so we were not concerned about database hits but the huge data being transferred. So after careful thought process and observations, we got to know following facts :

1. To many requests were made to the server (approx 110)
2. Every time connection opening & closing consumed lot of time.
3. File size were quite heavy. Files like js, images, css

We used Firebug, a firefox addon to identify the first problems. So in a process to improve performance we implemented three things

1. Not open & close connection on every request : For this to happen, we created filters and in before filter we added the following code :
response.setHeader('Connection','keep-alive')
2. Caching the response : To cache the response, we added the following code to the before filter :
response.setHeader('CacheControl', "public") response.setDateHeader('Expires', System.currentTimeMillis() +60*1 000)
3. Reduce the size of files to be loaded : To do this, we zipped all the files and set the response header again in before filters as given in the following code :
response.addHeader('Accept-Encoding','gzip, deflate')

Page download time reduced to 1/5th of the original time after using these techniques.

There is another option that can be explored, which is ETAG, which saves us from downloading the file again, if there are no changes from the last response.

Hope this helped. Please share your thoughts to improve the performance.

Cheers!

Regards,
~~Amit Jain~~
amitjain1982@gmail.com







Grails - multiple layouts

Hi Friends,

The small project that I worked had many different layouts, like different for home and rest of the pages. So we generally make use of main.gsp to define the basic layout of the application which is common to all gsps. So to cater to different layouts issue, I created multiple(as required) gsps just like main.gsp in the layouts folder. And wherever a particular layout was needed corresponding gsp was included in the meta tag. For example

For home page layout - mainHome.gsp and referred it as < meta name="layout" content="mainHome"/ >

For admin page layout - mainAdmin.gsp and referred it as < meta name="layout" content="mainAdmin"/ > and like ways.

So this saved me from writing the same code again and again.

Cheers!
~~Amit Jain~~
amitjain1982@gmail.com

Friday, August 7, 2009

Grails : custom error page on any exception

Hi Friends,

To display the custom error page on production instead of any exception that might occur, We can use modify error.gsp file. Error.gsp file is the one which is executed anytime any exception occurs.
As grails enables us to configure the application in development, production and testing environments. We can use the same error.gsp file and render certain gsp as per the current environment.

< html >
< g:if test="${GrailsUtil.isDevelopmentEnv()}" >
< head >
< title >Grails Runtime Exception< /title >...
< /head >< body > ...
...< !-- Default error.gsp body part -- >
< /body >
< /g:if >
< g:else >
< g:render template="/errorPage"/ >
< /g:else >
< /html >

In the above code, in development environment the error.gsp would execute the default code but in any other environment it would render the template "errorPage", which is our custom user friendly errorPage template.

Cheers!
~~Amit Jain~~
amitjain1982@gmail.com

Grails : How to set value in FckEditor

Hi Friends,

I was using fckeditor plugin, where I found that when I wanted to display the data from the database in the fckeditor, it appeared but it displayed the html code as well and with no formatting as it didn't render the html code. So the workaround I found is shared below :

< fckeditor:editor
id="content" name="content"
width="600"
height="400"
toolbar="Standard"
fileBrowser="default"
value="${myBean.content}"
>
${myBean.content}
< /fckeditor:editor >

Hope this helped.

Cheers!
~~Amit Jain~~
amitjain1982@gmail.com

Monday, July 13, 2009

Flex on grails : CRUD and useful links

Hello friends,

I am learning flex 3 these days as I wrote in my previous blog. Today I found a very useful link which explains about crud functionality of flex on grails. Its easy to understand and directly implementable. Check this
http://graniteds.blogspot.com/2009/03/building-flex-multi-tab-crud.html

I have also found few more useful links which are as follows :

1. http://blog.xebia.com/2008/02/20/tutorial-master-detail-screen-in-flex-backed-up-by-grails-application/
2. http://www.infoq.com/articles/flex-grails
3. http://corfield.org/blog/index.cfm/do/blog.entry/entry/Grails_and_Flex
4. http://sites.google.com/site/flexongrails/
5. http://www.adobe.com/devnet/flex/articles/flex_grails.html (controller support)
6. http://marceloverdijk.blogspot.com/2007/08/another-sexy-flex-grails-example.html
7. https://www.ibm.com/developerworks/web/library/wa-riagrails1/
8. Install GDS Plugin - http://www.grails.org/plugin/gdsflex
9. http://learn.adobe.com/wiki/display/Flex/Get+oriented+to+Flex
10. http://livedocs.adobe.com/flex/3/html/help.html?content=Part7_DataVis_1.html
11. http://graniteds.blogspot.com/2009/04/building-flex-multi-tab-crud.html

# Few websites designed using flex.

1. http://www.disney.in/DisneyChannel/supersites/sonnywithachance/
2. http://stevenmerrilltenor.com/

Hope these links would help you learn flex.

Cheers,
~~Amit Jain~~
amitjain1982@gmail.com

Monday, July 6, 2009

Flex on grails : How flex interacts with controllers/services

Hello friends,

I have recently started learning Flex and the backend is grails. After playing with following 3 grails plugins which supports flex, I chose gdsflex and have seriously started learning it.

1. flex-scaffold
2. flex
3. gdsflex 0.5 ver


In this blog we would discuss about gdsflex. I tried the programs given in the blog(http://www.grails.org/plugin/gdsflex) but I had to make some changes to the code, which I am going to share now.

Install plugin :

grails install-plugin gdsflex


To be on the safer side, run the following command as there were some issues with initial versions of gdsflex.
grails gas3

Create a domain classes
class Person {
Long id;
Integer version
String uid
String firstName
String lastName
Set contacts = []
static hasMany = [contacts:Contact]
static mapping = {
contacts cascade:"all,delete-orphan"
}
}

class Contact {
Long id;
Integer version
String uid
Person person
String email
static belongsTo=Person
}
Create a people controller :

import org.granite.tide.annotations.TideEnabled

@TideEnabled
class PeopleController {
List people
def list = {
people = Person.list();
}
}
Create a mxml file in flex folder a sub directory of view folder :

< mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
xmlns:gv="org.granite.tide.validators.*"
layout="vertical"
backgroundGradientColors="[#0e2e7d, #6479ab]"
preinitialize="Spring.getInstance().initApplication()" >

< mx:Script > < ![CDATA[ import mx.collections.ArrayCollection;
import org.granite.tide.spring.Spring;
import org.granite.tide.events.TideResultEvent;
import org.granite.tide.events.TideFaultEvent;
import Person;
import Contact;

[Bindable]
[In]
public var peopleController:Object;

[Bindable]
[In]
public var people:ArrayCollection;

public var dummyPerson:Person;
public var dummyContact:Contact;

private function getList():void {
peopleController.list();
} ]]>
< /mx:Script >

< mx:VBox width="100%" >
< mx:HBox >
< mx:Button id="bList" label="Get list" click="getList()"/ >
< /mx:HBox >

< mx:HBox width="100%" >
< mx:DataGrid id="dgPeople" dataProvider="{people}"
change="dgContacts.dataProvider = dgPeople.selectedItem.contacts" >
< mx:columns >
< mx:DataGridColumn dataField="firstName"/ >
< /mx:columns >
< /mx:DataGrid >

< mx:DataGrid id="dgContacts" >
< mx:columns >
< mx:DataGridColumn dataField="email"/ >
< /mx:columns >
< /mx:DataGrid >
< /mx:HBox >
< /mx:VBox >

< /mx:Application >


To create dummy data to test the application, you may write the following code in init closure of booStrap.groovy file

Person person
Contact contact
(0..10).each {
person = new Person(firstName:'Amit' + it, lastName:'Jain' + it)
person.save(flust:true)
contact = new Contact(email:'amitjain1982@gmail.com_'+ it,person: person)
contact.save(flush:true)
}


To run the application, firstly execute

grails run-app applicationName

grails mxmlc //to compile all mxml files as gdsflex 0.5 version doesn't auto compile file

Execute the following url in the browser
http://localhost:8080/appName/fileName.swf //here fileName is the name of mxml file.



You are ready to go. You have implemented lazy initialization using flex on grails.

Cheers!
~~Amit Jain~~
amitjain1982@gmail.com