Tuesday, April 28, 2009

GWT, Spring 3.0 MVC, and REST on Google App Engine / Java - Part 2

From Part 1 of GWT, Spring 3.0 MVC and REST on Gae/J posting, you should now have a spring application with REST up and running and should be deployable on google app engine.

Integrating GWT with your backend now is pretty straight forward for the most part. Restlet is a REST framework, they released a module called Restlet-GWT module. For more understanding about it and why use rest with GWT, here is a link to blog posting on release Restlet ported to GWT. I'll be referring to the Greeting demo when you create a new application with the Google eclipse plugin. In what ever you named your Entry point class, look for the function

private void sendNameToServer()

your going to replace everything from greetService.greetServer(textToServer, with this..

final Client client = new Client(Protocol.HTTP);
client.get("http://localhost:/greet.json", new Callback() {
public void onEvent(Request request, Response response) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel.removeStyleName("serverResponseLabelError");
JSONValue json;

json = JSONParser.parse(response.getEntity().getText());
JSONValue value = json.isObject().get("hello");

serverResponseLabel.setHTML(value.toString());
dialogBox.center();
closeButton.setFocus(true);
}
});

Sorry for formatting, but you can see
client.get("http://localhost:/greet.json", new Callback() {

here is where I'm calling the rest url to retrieve the json string returned from the backend and GWT already provides functionality to parse JSON. For more information on Restlet-GWT. Restlet Maven Repository.

I found an issue with running Spring MVC 3.0 on google app engine ( could be only hosted mode). GWT compiles and generates a bunch of css, and javascript files. To get the nice REST style url's all requests need to be mapped to context
( / )


<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>



The servlet mapping will match the longest matching map first. So when something like


<script type="text/javascript" language="javascript" src="/static/app/app.nocache.js"></script>



is given .. this should go directly to the mapping default servlet (above example), and not the main spring dispatcher. The issue is with jetty vs tomcat and how they handle paths. From the posting I found on stackoverflow (servlet for serving static content) "The problem is that Tomcat's default servlet does not take the ServletPath into account (so it looks for the static files in the main folder), while Jetty does (so it looks in the static folder)." Luckily the user provides the file of a servlet. In the servlet I made one change in the servlet class provided.
In the function protected String getPath(HttpServletRequest req).. I changed it to return pathInfo; and not return servletPath + pathInfo; . This changes makes the behavior like Tomcat, and so you won't have to move all your files inside of a folder called static. This basically ignores the /static/ and looks for path after that. Now in your web.xml just define new servlet, and define for static mapping.

Thats it.. You should now have your GWT front end talking to your Spring 3.0 MVC application running in hosted mode, and GAE/J. The cool thing is now you can switch between regular spring mvc application functionality (exmaple: submitting forms) using html, css and GWT. Coming up - Nightmare dependencies with Spring 3.0 M2 and Data nucleus GAE/J, GenericDao with Spring and JDO, and Spring Security.

4 comments:

  1. I succeeded in getting REST (with the new REST support in Spring 3) done in the Google App Engine.
    It wouldn’t be an easy task, but thanks to one brilliant blog post, a forum post and a very helpful JIRA issue, it can be resolved just by searching.

    1. The brilliant blog post about Spring REST in general by Eyal Lupu.
    This post is just a rewrite of that one, just adding the GAE-related stuff.
    All details about REST content negotiation and how the Spring MVC works with REST is explained there.
    2. The forum post about problems with GAE and XStream.
    This helps to unterstand the reason for the sun.reflect.ReflectionFactory is a restricted class exception when using XStream on GAE.
    3. The JIRA issue 566, which investigates the problem in more detail and provides a solution which is valid for at least the usage in this context.

    ReplyDelete
  2. In my experience Spring -GWT has been harder to understand as less documentation. Although it sound very appealing what Spring -GWT combination provides....

    -www.ZTextbook.com

    ReplyDelete
  3. In my experience Spring -GWT has been harder to understand as less documentation. Although it sound very appealing what Spring -GWT combination provides....

    -
    http://www.ZTextbook.com

    ReplyDelete
  4. Hello.. Firstly I would like to send greetings to all readers. After this, I recognize the content so interesting about this article. For me personally I liked all the information. I would like to know of cases like this more often. In my personal experience I might mention a book called Green Parks Costa Rica in this book that I mentioned have very interesting topics, and also you have much to do with the main theme of this article.

    ReplyDelete