Monday, March 22, 2010

GWT + Grails = Rock n Roll: Part 2 - Two separate projects talking JSON through RequestBuiler

This post is Part 2 of Grails + GWT = Rock n Roll series. You can see Part 1 here. Part 1 showed how to create an application based on GWT and Grails. To join the two, I used Grails-GWT plugin.

In this post today, after a few days reading about GWT and playing with the application created in Part 1, I decided to also try to develop another application with GWT + Grails, but this time without using the plugin. Thus, I could even decide if I prefer with or without the plugin. This post will show you how to create a solution composed of two separate applications, one GWT and the other Grails, communicating through the exchange of data using JSON.

Separating Grails and GWT in two distinct applications 

As described in Part 1, if you do not use the plugin and have two separate applications (one other GWT and Grails) instead, this means having to deal with the Same Origin Policy (SOP) in development time. In production it may be simpler. You could always find a way to get the HTML, CSS and JavaScript generated by the GWT compiler into the grails project (you could just copy and paste from one side to the other). But in development we have to deal with SOP in a way more productive than having to copy and paste from one side to another. The simplest way I found was using a ProxyServlet, originally created by Jason Edward, and then evolved by Matt Raible. The source of this class I got from the project Implementing OAuth with GWT created by Matt Raible. It is simple to use, and solves the problem easily. What it does in our context is:
- GWT application on the client side makes a request to the server;
- GWT application on the server side receives this request and forwards it to the Grails application
- Grails application receives this request and responds JSON
- GWT application receives this JSON response and forwards it to the GWT client

Thus we need not bother with SPO.

Why do we need all this? After all, why do we want to have two separate applications (one other GWT and Grails)? Well, that ends up being a personal decision of each one, ok? But for me, I find it interesting to follow the standards of each project. A GWT project, as recommended, should be organized in a way, with a particular folder tree, etc. It may not be followed, but it is a recommended standard. So, why not speak the same "language" in chat rooms, discussion forums, new developers on the team, etc?

In addition, separating the two projects leads to an interesting reflection on the conceptual architecture of rich applications for the web (RIA - Rich Internet Applications). By separating, you are literally, physically, implementing the SOFEA architecture (Service Oriented Front End Architecture). SOFEA was very well presented in the article Life Above the Service Tier (worth the read. The authors now have a group on this subject and have a website at: ThinServerArchitecture.com).

In SOFEA applications, the whole User interface logic runs on the client side, in our case, the browser. The View and Contoller layers will have a project just for them (the GWT project). This is the most decoupled Front-End  as it gets. This is interesting in my opinion, because then your server application turns out to have the sole responsibility to provide services for the Front-End (User Interface - UI). It seems like we're back to the concept of client x server, and somehow, we are, but a little different because it is a thin client, where only the user interface logic and flow of navigation control are on the client side. All other business rules are and should be on the server.

Two other reasons for this separation into two applications are (these are from Matt Raible's blog Packaging SOFEA Applications for Distribution):
- It may be simpler to work different teams each in a different project
- Each project can be versioned independently

Well, after all these reasons, the fact is: I created a new application that consists of a GWT app responsible for the Front-End, and a Grails app for the Back-End (providing services, remember SOA?). Here things start getting even more cohesive and decoupled. Interesting results ....

Communication using JSON 

For the communication between the Front-End and Back-End, I chose to use JSON. A grails app can easily generate a JSON response, while GWT can easily consume JSON. So, being a lightweight protocol to exchange data, and easily served and consumed by the GWT and Grails, I think JSON is a good choice. But if you prefer to work with XML, or other proprietary format, the decision is yours.

Therefore, to create this new application, simply create a new GWT project, and another Grails project.

Application Front-End (GWT) 

I'm using Eclipse with the plugin for GWT, therefore, to create a new project just click to create new GWT project in Eclipse. I created this GWT project called rockgwtfront, with the package com.rockgwt.front

The Eclipse wizard creates an EntryPoint class, the XML Configuration Module, and also creates an RPC service implementation. But we do not need this service for this example, therefore, you can delete the package com.rockgwt.front.server and package com.rockgwt.front.shared, and can also delete files GreetingService.java and GreetingServiceAsync.java from com.rockgwt. front.client package. Then change the class Rockgwtfront.java to not use this service anymore. In the end, I got the EntryPoint class  below:

package com.rockgwt.front.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

public class Rockgwtfront implements EntryPoint {

    public void onModuleLoad() {
        final Button sendButton = new Button("Get Hendrix songs");
        final FlexTable songsTable = new FlexTable();

        // We can add style names to widgets
        sendButton.addStyleName("sendButton");
        
        sendButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                String hendrixSongsServiceUrl = GWT.getHostPageBaseURL();
                if(!GWT.getHostPageBaseURL().contains("rockgwt"))
                    hendrixSongsServiceUrl += "rockgwt/";
                    
                hendrixSongsServiceUrl += "hendrix/songs";
                RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, hendrixSongsServiceUrl);
                builder.setTimeoutMillis(10000);
                builder.setCallback(new RequestCallback() {
                    
                    @Override
                    public void onResponseReceived(Request request, Response response) {
                        if (response.getStatusCode() == 200) {
                            
                            JSONValue v = JSONParser.parse(response.getText());
                            JSONArray songs = v.isArray();
                            if(songs != null){
                                updateBacklogItemsTable(songsTable, songs);
                            }
                            else{
                                throw new JSONException("O retorno nao veio como um objeto de Projeto"); 
                            }
                        } else {
                            onError(request, new RequestException(response.getText()));
                        }
                    }
                    
                    @Override
                    public void onError(Request request, Throwable exception) {
                        Window.alert(exception.getLocalizedMessage());
                    }
                });
                try {
                    builder.send();
                } catch (RequestException e) {
                    Window.alert(e.getLocalizedMessage());
                }
            }
        });

        RootPanel.get("sendButtonContainer").add(sendButton);
        RootPanel.get("songsTableContainer").add(songsTable);

    }
    
    private void updateBacklogItemsTable(FlexTable songsTable, JSONArray songs) {
        songsTable.clear();
        for (int i=0; i<songs.size(); i++) {
            JSONObject item = songs.get(i).isObject();
            songsTable.setWidget(i, 0, new Label(item.get("name").isString().stringValue()));
            songsTable.setWidget(i, 1, new Label(item.get("album").isString().stringValue()));
        }
                    
    }
}



Note that the class above uses a RequestBuilder to perform the request to the server. RequestBuilder is a GWT class that can be used to make remote requests. With it, the requests are always asynchronous, ALWAYS. Here there is a callback object that will be called when the request comes back from the server. Then, this callback can do whatever it takes with the response received. In this case, I parsed the JSON response to work with the data returned. At the end, I just take this data and present them in a table, that's all.

The GWT application expects a JSON return in the following format:
[( "name": "Hey Joe", "album": "Are You Experienced"),
( "name": "Bold as Love", "album", "Axis: Bold as Love")]

Therefore, it is necessary that the Grails application returns a JSON exactly in this format above.

You must add the JARs needed by the ProxyServlet quoted above to ~/rockgwtfront /war/WEB-INF/lib. So, add commons-fileupload-1.2.1.jar, httpclient-4.0.1.jar, and httpmime-4.0.1.jar to the lib (in the future we can manage this dependencies with Maven). Create the ProxyServlet class. You can download the OAuth 1.3 and see the ProxyServlet there. Next, you must configure the web.xml to let it know that ProxyServlet exists. I mapped this proxyServlet for it to be run for every /rockgwtback/* request. See below:



<web-app>
  <servlet>
        <servlet-name>RockServletservlet-name>
        <servlet-class>com.rockgwt.front.servlet.ProxyServletservlet-class>
        <init-param>
            <param-name>proxyHostparam-name>
            <param-value>localhostparam-value>
        init-param>
        <init-param>
            <param-name>proxyPortparam-name>
            <param-value>8080param-value>
        init-param>
        <init-param>
            <param-name>secureparam-name>
            <param-value>falseparam-value>
        init-param>
    servlet>
  
    <servlet-mapping>
        <servlet-name>RockServletservlet-name>
        <url-pattern>/rockgwt/*url-pattern>
    <servlet-mapping>
  
 
  <welcome-file-list>
    <welcome-file>Rockgwtfront.htmlwelcome-file>
  <welcome-file-list>
<web-app>

Note that the servlet-mapping shows how the url should be requested by the GWT client. (/ rockgwt/*).

For the Grails project, you can create a new app using the command line, or you can create a new one using Eclipse's STS (SpringSource Tool Suite). I created this grails app calling it rockgwtback. For this app, I created a controller called HendrixController that has the action "songs." This action returns a list of songs from Hendrix. See below:


package com.rockgwt.back.controller

class HendrixController {
    def index = { }

    def songs = {
        println "chegou"
        render(builder: 'json') {
                songs = array {
                       song name: '1) Hey Joe', album: 'Are You Experienced'
                       song name: '2) Bold as Love', album: 'Axis: Bold as Love'
                   }
        }
    }

}


Also changed the name of the application within the application.properties putting app.name = rockgwt

That's it!

Thus, we have a system running with Grails and GWT, independent of each other, but together forming our application. Here we miss a way to merge the two applications in production. Probably I would do it with Maven, so I have a single app in production.

Friday, March 12, 2010

Grails and Dates: automatic binding a Date attribute from a custom formatted string


Here is a small recipe for those who are not using the DatePicker default Grails.
The Grails comes with a tag that is g:datepicker. It generates listboxes (comboboxes) for day, month, year, hour, minute and second. You can even choose which of these comboboxes you want to generate.

But there are times we do not want to use these combos, and just want a text field where the user can type the date in any format, such as dd/MM/yyyy or dd/MM/yy, or yyyyMMdd, or .. . ... or ... or

Also, if you have an internationalized application, there may users with Portuguese Locale and input format like dd/MM/yyyy, or others with an English Locale and MM/dd/yyyy format.

Well, the goal here is to show how to configure Grails to use different input formats for dates, so it can parse automatically whenever you have an attribute of type Date in a domain object (or a Command object) that we need to bind from the parameters received in a POST (or GET).

Here it goes:
1) User fills out a field input type = "text", with a date in a format that you determine, ex: MM/dd/yyyy
2) He/she sends this POST, which gets to your Controller and you have the params attribute
3) you want to automaticaly  bind (let's say my domain object is Person, and in it there is a Date birthday):
Person p = new Person(params)  

For this to happen correctly, and its birthday attribute be binded with a value of type Date, you must create a PropertyEditorRegistrar customized for you. Create a package in src/groovy, say com.myapp.editor and create there a PropertyEditorRegistrar:


package com.myapp.editor; 
 
 import java.text.SimpleDateFormat; 
 import java.util.Date; 
 
 import org.springframework.beans.PropertyEditorRegistrar; 
 import org.springframework.beans.PropertyEditorRegistry; 
 import org.springframework.beans.propertyeditors.CustomDateEditor; 
 import org.springframework.context.i18n.LocaleContextHolder; 
 
 public class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar { 
 
  def messageSource; 
 
  public void registerCustomEditors(PropertyEditorRegistry registry) { 
    registry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(messageSource.getMessage("dateFormat4y",null,'dd/MM/yyyy',LocaleContextHolder.locale )),true)); 
  } 
 
 } 
  

Note that to work properly, you need to edit your grails-app/i18n/messages.properties (messages_en_US.properties, messages_en.properties) to have each one its correct setting. Ex for the en:
dateFormat4y=MM/dd/yyyy  

The next step is to register this PropertyEditorRegistrar in the grails-app/conf/spring/resources.groovy:
beans = { 
 
  customPropertyEditorRegistrar(com.myapp.editor.CustomPropertyEditorRegistrar) { 
     messageSource = ref('messageSource') 
  } 
 
 }  

That's it!

Cheers

Grails: how to run different logic in production and development environments

There are times when we need to run different stuff depending on the environment the app is running on. For example, integration with external systems are sometimes simulated (mocked) in Development, and are executed for real in Production.

Here's a simple way to run one thing in Development and another in Production (or as many environments as you  need ...).

import grails.util.Environment; 
 
class MyController{ 
   Environment.executeForCurrentEnvironment { 
      production { 
         // Here goes the prod code
      } 
      development { 
         // Here goes the dev code
      } 
   } 
} 

Tuesday, March 9, 2010

Grails + GWT = Rock n Roll: Part 1 - exploring a new world

Welcome to wonderful world of Rock n Roll. Rock bands, a lot of times, are frowned upon by most traditional people. Other times they are revered by young rebels. Doesn't matter. The best bands, in the end, only do one thing: Rock n Roll.

But what's it all about? No doubt the music is the main product of this rebel factory. Behind the people with tattoos, earrings and full of torn clothes, sometimes alcoholics and drug addicts, deep down there are musicians that together (and here's the most important: Together) are able to touch the souls hungry for pure and simple rock. Ever heard a good Lynyrd Skynyrd with their 3 guitars, piano, drums, etc? No doubt there is great musicality there. Together they get rock fans astounded even nowadays.

After this metaphorical introduction, I will start today a series of posts about GWT and Grails, two technologies that together, for me, are emerging as the greatest rock band of recent times.

Grails is IMHO simply the best framework for web development in the java platform (at least those I know).

GWT (Google Web Toolkit), on the other hand, I'm just a beginner, or rather curious. To be honest, I have been a little tired of dealing directly with HTML, CSS and Javascript, especially with the rise of Javascript that must be handled when developing AJAX applications. Even using libraries such as jQuery, or Prototype, anyway, it is a lot of JavaScript to handle.

Because of this (and other reasons), I think that GWT can be of great help. One of the major reasons is also the belief that I'm getting that GWT can help a lot on having a decent architecture also in the View layer, not just the model, the controller, the DAO, etc.. If we look at an architecture of a traditional Grails application from the bottom up, we can see that:
  • - The DAO is well resolved,
  • - Services are there and fulfill their role (transaction control, for example),
  • - The Controller also has its role as the boundary between our HTTP world and business rules/logic
  • - But then comes the View and we start to lose ouselves and make a mess with HTMLs, CSSs, Styles, JavaScript .js files, inline JavaScript, and so on.
I've been studying a bit of GWT to understand more deeply and I'm starting to believe that it can be used to more easily engineer a decent View layer. For example, you can use an MVP (Model View Presenter) with GWT. Anyone out there can say that you can also do so with JavaScript directly. Yes, you may, but you can't deny that GWT makes things easier. First: It is JAVA! You get tools, refactorings, debugging, and more. You also get the fact that GWT abstracts you from worldly concerns, such as obfuscation and minimization of JavaScript, to say the least. It does this for us.

So that's it guys. Let's start .... I'l write the posts in accordance with the adventure that I am going through. I have never developed a real application with GWT + Grails. So we will do so together. It will be small, but let's go!

To start with, I installed the GWT plugin for Eclipse. Also downloaded the GWT SDK (currently I am using version 2.0.3 of GWT). Download them all here: http://code.google.com/intl/en/webtoolkit/download.html

I did a little experiment with GWT alone, without Grails yet. For this, I created a new GWT project using the Eclipse wizards that the plugin gives me. It creates a project already running from within eclipse, all beautiful. And this new project already has a small sample page, with a modal dialog, an Ajax request and everything. All there for you to begin understanding EntryPoint, GWT Modules, widgets and everything else.

So the first suggestion I give is this: play with the new application generated by the Eclipse plugin.

The first thing I noticed about applications with GWT is that everything is AJAX, I mean asynchronous. All communication with the server is asynchronous. Then I saw that the application generated by the Eclipse plugin has a different layout from a Grails application. So I get the first problem: how to join the two worlds?

Well, in the end, GWT only to generates HTMLs and Javascript. So you can compile your GWT project, get the generated HTML and Javascript, and copy to your Grails project, in web-app folder. Simple as that! But that would not be productive.

So I questioned: how people gather around Grails with GWT? They make a GWT project and another Grails project, and then join the two in some way (with maven for example)? Or they create just one project with it all?

And more... if they are two distinct projects, how to deal with the Same Origin Policy (SOP)?

I saw that there are people who actually use the first solution, and people who use the second. For example, Matt Raible. Since I was developing with AppFuse I'm a fan of his. I learned a lot from the structure that he set for AppFuse.

And Matt uses the first solution? He has two applications: one GWT and one Grails. Then, in development environment he has two apps running simultaneously. And he deals with SPO through a smart GWT proxy. The proxy receives requests form GWT client, forwards it to the Grails application, get back the response from it, and forward the same to the browser that has the GWT client. Very crazy, but it works. (at least this is what I understood he is doing)

In production environment he actually puts them together.
He has a smart Maven that does all this for him automatically, generating a single WAR that has the Grails and GWT client applications together. Then the SPO problem disappears.

The other alternative is to gather everything together from scratch in a single application. To facilitate this, Peter Ledbrook created the GWT plugin for Grails (do not be fooled by this page. The plugin is now in version 0.5 and supports GWT 2.0).

I, for now, will follow this simpler path (always like the simplicity): I'll use the GWT plugin for Grails.It seems so simple now ...... but I got a couple of weeks to reach this conclusion. And so far I wanted to understand why Matt Raible does not use the plugin. Maybe it is bad for some reason. If so, I have not yet discovered the badness.

So my friend, here are the initial steps:
  • - Installing the SDK GWT
  • - Create the environment variable GWT_HOME pointing to the root of the GWT SDK
  • - Install the Eclipse plugin for GWT
  • - Create a simple application using the GWT plugin for eclipse.
  • - Open the application in the browser using the URL displayed by Eclipse (with gwt.codesrv parameter in the URL - this parameter is what allows you to change the Java code and refresh your browser to see the change there immediately).
  • - Ensure that the GWT browser plugin is installed (it will popup asking you to be installed).
  • - Run this application and play around with different layouts GWT.
That's it. Now that you played with GWT a bit, let's join the two (GWT + Grails):
  • - Create a new Grails application with the command grails create-app rockgwt
  • - Go into it (cd rockgwt)
  • - Install the GWT Grails plugin (using the grails install-plugin gwt). I'm using Grails 1.2.x and grails-gwt plugin 0.5
  • - Create a GWT Module with the command plugin grails create-gwt-module com.rockgwt.RockNRoll
  • - Create a host page for your GWT Module. I did this by creating a controller and one grails page, index.gsp, for this controller. This page is the one that will host GWT:
  • 1) grails create-controller com.rockgwt.controller.Principal
  • 2) grails create-gwt-page main / index.gsp com.rockgwt.RockNRoll (when this command asks you if you want to create the Controller, say no, because you just created it in the previous step --- I think the plugin does not recognize the Controller created inside apackage, whatever).
  • - Compile your module with the command grails compile-gwt-modules (it takes a little bit)
  • - Run the Development Mode with the command grails run-gwt-client Note that it will open the application window of GWT Development Mode
  • - Open another Terminal, go to your project rockgwt and run grails application (that's right, you have two things running: the grails run-app , and grails run-gwt-client).
  • - Open the browser and go to the Home of your GWT + Grails application : http://localhost:8080/rockgwt?gwt.codesvr=127.0.0.1:9997
  • - To guarantee success, simply click the Launch Default Browser in the Development Mode window.
  • - The address you want to access in the end will be your main controller:
    http://localhost:8080/rockgwt/principal/index?gwt.codesvr=127.0.0.1:9997
  • - Be sure to put this crazy parameter. It is responsible for allowing you to change the Java code and give a refresh on the browser to see the changes immediately.
Now, open your class RockNRoll and leave it like this:
(this class is in your project rockgwt in src/gwt/com/rockgwt/client)

package com.rockgwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;

/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class RockNRoll implements EntryPoint {
/**
* This is the entry point method.
*/
public void onModuleLoad() {

final Button sendButton = new Button("Rock n Roll");

RootPanel.get().add(sendButton);
}
}


Refresh your browser.

UPDATE (3/8/2010):
- Just to complete....... in order to use Eclipse, click the right button of the mouse on top of src/gwt and select Build Path> Use the Source Folder
- And finally right click the mouse on the project rockgwt and select the Google> Webtoolkit Settings, inside the wizard that opens, select the first checkbox that appears at the top:"Use Google Web Toolkit." So you have everything you need in the classpath of the application in Eclipse.

Tks