Monday, September 13, 2010

GWT and Grails

I spend some time tried and figured out how the GWT and Grails actually work together. So I keep it here so I can refer it later and may also be helpful to some one else.

1. install GWT

a. wget http://google-web-toolkit.googlecode.com/files/gwt-2.0.4.zip
b. unzip
c. setenv GWT_HOME

2. install grails just download grails install package from grails.org (I am using grails 1.3.4)

unzip it to some directory
setenv GRAILS_HOME

3. Create the grails project

grails create-app grailsgwtdemo

4. goto the grails project directory

cd grailsgwtdemo

5. install grail gwt plugin

grails install-plugin gwt

6. create the gwt module

grails create-gwt-module com.demo.client

The following two files created
./src/gwt/com/demo.gwt.xml
./src/gwt/com/client/demo.java

7. create gwt module hosting page

grails create-gwt-page index.gsp com.demo.client

This create the hosting page
web-app/index.gsp

8. try run it:

a. run web in one env:

grails run-app

b. run gwt client in another env:

grails run-gwt-client

9. Now try to do some interaction with services on the server side provided in grails

9.1 Create grails service:

grails create-service gwtdemo

This create the file:
grails-app/services/grailsgwtdemo/GwtdemoService.groovy

9.2 expose the service by adding this line into grails-app/services/grailsgwtdemo/GwtdemoService.groovy

static expose = [ 'gwt:com.demo.client' ]

9.3. Create the service method for the client:

String doit(String data){
"echo from server:"+data
}

Note: If you put def in place of the above return variable type String, the following autogenerated rpc code will have the Object.

9.4. grails generate-gwt-rpc

This generates the following 4 files:
src/java/org/codehaus/groovy/grails/plugins/gwt/client/GwtActionService.java
src/java/org/codehaus/groovy/grails/plugins/gwt/client/GwtActionServiceAsync.java
src/java/com/demo/client/GwtdemoService.java
src/java/com/demo/client/GwtdemoServiceAsync.java

9.5 Add this import

import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

and annotation above the doit(String data) method
@RemoteServiceRelativePath("rpc")

9.6. add web-app/index.gsp in the body: Now is:


add these to the ./src/gwt/com/client/demo.java

imports:
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
variables:
private Label label=new Label();
private TextBox tb=new TextBox();
private Button button =new Button("click me!");
private static GwtdemoServiceAsync myService=GWT.create(GwtdemoService.class);

public void onModuleLoad() {
RootPanel.get("echo").add(label);
RootPanel.get("echo").add(tb);
RootPanel.get("echo").add(button);
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
myService.doit(tb.getText(),new MyAsyncCallback(label));
}
}
);

}


public static class MyAsyncCallback implements AsyncCallback {
private Label mylabel;
public MyAsyncCallback(Label label){
this.mylabel=label;
}
public void onFailure(Throwable caught) {
this.mylabel.setText("sth wrong:"+caught.toString());
}

public void onSuccess(Object data) {
this.mylabel.setText((String)data);
}
}

10. Compile grails

grails compile

11. Compile gwt modules

grails compile-gwt-modules

12. run it again:

grails run-app
grails run-gwt-client

13. test on

http://localhost:8080/grailsgwtdemo/index.gsp

14. generate war file and deploy it

grails war

That's it. Pretty Straight forward.

1 comment:

  1. I wrote a follow-up to this that includes the sample code generated from this post:

    http://blogs.uoregon.edu/casspr/2013/05/21/grails-2-2-gwt-2-4/


    Not hard, but there are some things that are non-intuitive to the final setup that having the sample code helps with. This works with the 0.8 version of the gwt plugin. I have the resources plugin enabled and it still works. I had to remove my project directory for the project a couple of times, initially, but it eventually worked.

    Thanks for the post.

    ReplyDelete