May
23
2009

A framework for GWT multipage applications

This article is about the development of Rich Internet applications with Google Web Toolkit (GWT) that consist of multiple HTML pages like flickr or facebook. It dicusses  techniques to distinguish the different HTML host pages on the client side and an architecture to organize your entrypoints. Finally a framework for gwt multipage applications is introduced.

GWT applications, HTML host pages, modules and entry points

Some time ago I was developing a web application with jsp that consisted of a couple of jsp files. To enhance the usability of the user interface I wanted to add some ajax functionality to the pages and thus I was looking for a reasonable way to integrate GWT into my project. But that was not a simple thing, since the classical GWT application has got one HTML host page and only one entry point. I did not want to create one module per jsp file and so I was googling for a solution – I’m not the only one having this problem, but did not find a simple way to solve this problem. So I decided to develop my own solution and share it as an open source project on code.google.com.

How to choose the right entrypoint for the current page

If you’ve got one module for the entire web application with one registered entrypoint you have to know, which page is currently displayed to call the code according to the page. Some possibilities (this list is not complete!) are abvious:

  • Render a javascript variable containing the name of the entrypoint on the server side into the header of the html page and read the value via JSNI.
  • Render a meta tag to the header containing the name of the entrypoint on the server side and read the value via the DOM object.
  • Use the page’s title or a part of the title and read the value via the Window object.
  • Use the URL of the page and read the value with the Window object.

I decided to choose the last option and annotate entrypoints with a regular expression describing the adresses that are valid for the entrypoint.

A framework for multipage applications with GWT

Now we need an architecture for a framework that decides which entrypoint is the right one, creates an instance and calls its onModuleLoad method. The first step is to mark the entrypoints with java annotations containing a regular expression for which the entrypoints are valid:

package com.claudiushauptmann.gwt.multipage.sample.client;

import com.claudiushauptmann.gwt.multipage.client.MultipageEntryPoint;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

@MultipageEntryPoint(urlPattern = "MyMultipageEntryPoint.html")
public class MyMultipageEntryPoint implements EntryPoint {

public void onModuleLoad() {
Label label = new Label("MyMultipageEntryPoint");
RootPanel.get().add(label);
}

}

Second, we need a dispatcher entrypoint that is called instead of the target entry points, that decides which is the right entrypoint and calls it’s onModuleLoad method:

<module>
<!-- Inherit the core Web Toolkit stuff.                  -->
<inherits name='com.google.gwt.user.User'/>

<!-- Inherit the gwt-multipage module -->
<inherits name='com.claudiushauptmann.gwt.multipage.gwt-multipage'/>

<!-- Use this EntryPoint instead of your own one. -->
<entry-point class='com.claudiushauptmann.gwt.multipage.client.EntrypointDispatcher'/>
</module>

Via deferred binding the dispatcher entrypoint knows all possible entrypoints and looks whose regular expression matches the current url.

Conclusion

This framework was developed for multipage Rich Internet applications that are using GWT. The focus is about the pages and their entrypoints. There are some other issues about multipage Rich Internet applications that are not topic of this article but will perhaps find a place in this framework in the future.

If you are interested in this project you will find it at code.google.com:

http://code.google.com/p/gwt-multipage/

Please give some feedback and report bugs! The downloads are here, some more documentation will come soon.

37 Comments »

  • Hi Claudius,

    If only I had found this article 10 months ago when I started building SambaJam! :)

    I eventually had to settle for a different model and create different projects for each page. If you want to check it out, we are running a Beta (completely free, not trying to sell you anything) and I would love to get the opinion of a fellow GWTer. It’s a collaboration platform built on top of the Alfresco Open Source Content Management system.

    Send me an email if you would like to have a look. It’s also not limited so if you like the application you can invite others to collaborate with you :)

    Anyways, I’ve just bookmarked your blog, it’s definetely one of the best ones I would say.

    Regards,
    Ale

    Comment | October 16, 2009
  • Brian

    I have to say, this just saved me a lot of time. We have a very large GWT application. We have just discovered that we needed another entry point into our application. Out of all of the other solutions out there, this is by far the best and easiest. No code duplication, no increased compile time, and we did not have to change a thing in our deployment. Great work.

    Comment | November 3, 2009
  • Abhinav Upadhyay

    Awesome work. I would say its the struts framework for gwt.

    Comment | December 22, 2009
  • Carl

    The module XML file supports the declaration of multiple entry points, as many as you like. The OnModuleLoad() methods of these are invoked in the order that the entry points are defined within that file. So, a simple approach to supporting multiple HTML pages with a single module would appear to be (I have not yet tried this) just defining multiple entry points, and creating the corresponding entry point classes, and then, at the top of each entry point’s OnModuleLoad() method, check the HTML page using one of the techniques that you have described (e.g., checking the URL) and if the page does not correspond to that entry point, just return, at which point the next entry point’s OnModuleLoad() method would be invoked. Your framework will no doubt be more maintainable, but for just a couple of HTML pages this approach ought to work.

    Comment | December 23, 2009
  • Sripathi Krishnan

    Pretty neat.

    Another feature you may want to add is support for GWT.runAsync(). Right now, if I have 3 entry points, the first page is going to download the code for all 3 of them. But since there is such a clean separation between EntryPoints, you may want to wrap them in a GWT.runAsync call. That would significantly reduce the size of the javascript file.

    I am guessing you could add this feature without an impact to any client code. Only EntryPointFactoryImplGenerator and EntrypointDispatcher would need to change.

    Let me know if you agree with the idea; I can try and submit a patch in the next few days..

    Comment | December 24, 2009
  • Claudius Hauptmann

    @Carl: Thank you for your hint! Some time ago I used this approach in a small project and it was working well.

    @Sripathi Krishnan: This is a wonderful idea! I’m really looking forward to your patch!

    Comment | December 25, 2009
  • Maik

    This is really a nice framework!

    Here is a tip on how using it when you have aliases for a web-page. I run my service in Jetty as the root context. So it is accessible directly via a FQDN (with urlPattern=”/”). In addition the same page should be accessible via FQDN/public_1.html and FQDN/index.html. So the urlPattern could look like “/|/index.html|/public_1.html” (for me it doesn’t work w/o the leading /’s ).

    However the above regex, which works well when used with Java’s String.match() method, doesn’t work with GWT. The problem is that the choices after the standalone “/” are ignored. I.e. if you’d write: “/index.html|/|public_1.html” it would match the FQDN and “FQDN/index.html” but it would not match “FQDN/public.html”. Don’t ask me why, again it would work in plain Java. Having noticed this behaviour using the regex “/index.html|public_1.html|/” yielded the desired result.

    Comment | February 8, 2010
  • Fatih

    Awesome. I was wondering what is the current status on this project.
    thanks

    Comment | February 28, 2010
  • Claudius Hauptmann

    Hello Fatih! Thank you! I’m very busy at the moment. The next steps are the migration of the build management to apache maven like gwt-maps-gxt (http://code.google.com/p/gwt-maps-gxt/), adding tests and supporting moving/changing context-roots. Is there a feature that you’re missing or are you having trouble? I’m as always looking forward to patches and new ideas! Claudius

    Comment | February 28, 2010
  • Claudius Hauptmann

    Hello!

    Release 1.0.0.Beta3 is available:
    http://groups.google.com/group/gwt-multipage/browse_thread/thread/49164cab0cd1057a
    http://code.google.com/p/gwt-multipage/downloads/list

    Please have a look at the issues (kind of road map):
    http://code.google.com/p/gwt-multipage/issues/list

    thx

    Comment | March 3, 2010
  • Eric

    I don’t understand the value of Sripathi’s idea.

    Doesn’t that devolve back to using separate projects – except with slightly worse performance when the runAsync is called?

    Or is the target of this for legacy JSP apps. I’d appreciate some more information in case I’m not groking the idea correctly.

    Comment | March 9, 2010
  • Claudius Hauptmann

    Hello Eric, the idea is to support JSP apps. Sometimes web application with multiple pages are a better solution for example pages like ebay or facebook. Not all lines of code are necessary at every page und with codesplitting only the necessary party are downloaded. I hope GWT manages that no lines of code are downloaded twice.

    Comment | March 16, 2010
  • The module XML file supports the declaration of multiple entry points, as many as you like. The OnModuleLoad() methods of these are invoked in the order that the entry points are defined within that file. So, a simple approach to supporting multiple HTML pages with a single module would appear to be (I have not yet tried this) just defining multiple entry points, and creating the corresponding entry point classes, and then, at the top of each entry point’s OnModuleLoad() method, check the HTML page using one of the techniques that you have described (e.g., checking the URL) and if the page does not correspond to that entry point, just return, at which point the next entry point’s OnModuleLoad() method would be invoked. Your framework will no doubt be more maintainable, but for just a couple of HTML pages this approach ought to work.

    Comment | May 28, 2010
  • Hello Eric, the idea is to support JSP apps. Sometimes web application with multiple pages are a better solution for example pages like ebay or facebook. Not all lines of code are necessary at every page und with codesplitting only the necessary party are downloaded. I hope GWT manages that no lines of code are downloaded twice.

    Comment | June 1, 2010
  • Hi,

    I found a site that has tutorials on using GWT/smartGWT and gwt-multipage.

    It looks pretty good.

    Here’s the link -> http://uptick.com.au/content/managing-multiple-host-pages

    Cheers
    Mark

    Comment | June 12, 2010
  • Claudius

    @Mark: Awesome! Thank you!

    Comment | June 12, 2010
  • dory forma

    Unfortunately, I’m new to GWT and to Eclipse and I’ve been trying again and again to add your code and library to my primitive project but whenever I launch it in debug mode I get the error massage “invalid module name: ‘multipage.get-multipage’”.

    Could you possibly provide a bullet outline somwhere of how to properly set up an eclipse GWT web application project to include your functionality?

    Comment | June 15, 2010
  • dory forma

    In my post above, I mistyped there and the error message says “gwt-” not “get-”. I’ve added the library, added the annotation, and modified the xml as you indicate, but still get this error when the modules are loaded and don’t know how to debug that further or correct it.

    Comment | June 16, 2010
  • Hi Claudius,

    Do you support locales in the URL pattern?

    @MultipageEntryPoint(urlPattern = “account.html”)
    public class AccountEntryPoint implements EntryPoint

    e.g. &locale=de

    Kind regards
    Rob

    Comment | June 20, 2010
  • Hi Claudius,

    To be more precise re “support for locales in the URL pattern”:

    @MultipageEntryPoint(urlPattern = “account.html”)
    public class AccountEntryPoint implements EntryPoint

    http://www.myDomain.org/account.html?locale=de

    or

    http://www.myDomain.org/account.html?locale=fr

    Kind regards
    Rob

    Comment | June 20, 2010
  • Claudius

    Hi Rob,
    yes, of course it is supported. Just add it to your regex! There will be more aid in future versions that handle this and other parameters like gwt.codesvr automatically. Please have a look at the handling of the gwt.codesvr parameter:
    http://code.google.com/p/gwt-multipage/source/browse/trunk/gwtmultipage/gwtmultipage-sample/src/main/java/org/gwtmultipage/sample/client/MultipageEntryPointIndex.java
    Claudius

    Comment | June 20, 2010
  • Hi Claudius,

    I didn’t have any luck with with locales. What I mean is sometimes the URL will just be:

    -> http://www.myDomain.org/account.html and

    sometimes it will be suffixed with “?locale=de” or “?locale=fr”.

    So, “account.html” works when there is no locale but not when there is a locale.

    I had a look at the code server regex e.g. “(account.html)?(\\\\?gwt.codesvr=127.0.0.1:9997)?” which works when there is no locale but not when there is a locale.

    Then I reviewed the regex pages -> http://java.sun.com/javase/7/docs/api/java/util/regex/Pattern.html and tried a combination but I haven’t had any luck yet.

    Any suggestions?

    Kind regards
    Rob

    Comment | June 21, 2010
  • Claudius

    Hi Rob,
    does something like this work? It does definitly not solve all necessary combinations of parameters.
    account.html(\\\\?locale=(de|fr))?((&|\\\\?)gwt.codesvr=127.0.0.1:9997)?
    Perhaps this site might help: http://www.regular-expressions.info/
    Kind regards
    Claudius

    Comment | June 21, 2010
  • Hi Claudius,

    Thanks for getting back to me.

    “account.html(\\\\?locale=(de|fr))?((&amp;|\\\\?)gwt.codesvr=127.0.0.1:9997)?”

    Works for both:

    -> http://www.myDomain.org/account.html
    and
    -> http://www.myDomain.org/account.html?locale=de

    Thanks again.

    Kind regards
    Rob

    Comment | June 22, 2010
  • rjb

    Claudius, (how) does history work across pages? Is there anything special that the app has to take into account to accommodate GWT history and page switches?
    -rjb

    Comment | July 21, 2010
  • Farid

    Hello dear Claudius,
    Thanks for your great framework.
    Would you please help me with this problem? I have inserted goToRelativePage(“second.html”); inside onModuleLoad(), but I got this message “GWT module ‘gwt7′ may need to be (re)compiled” .
    Your help would be appreciated.
    Regards.

    Comment | August 1, 2010
  • Claudius

    Hi Farid,
    perhaps you should add “?gwt.codesvr=127.0.0.1:9997″. Which type of Entrypoint-Annotation do you use? Url or JavascriptToken?
    Claudius

    Comment | August 1, 2010
  • Claudius

    Hi rjb,
    I didn’t proof that yet. Please share your experience with us!
    Claudius

    Comment | August 1, 2010
  • Farid

    Hello there.
    I got the answer. It works fine.
    Regards.

    Comment | August 2, 2010
  • Shantanu

    Hi,

    I have downloaded gwtmultipage-1.0.0.Beta5. jar and using multipage framework.
    I dont want to display the html showing number of entrypoints at first page. Instead I want to go to my main entry point from where the flow of application begins.

    In detail:
    I have two entry point classes. one is main in which I have scrollabletable. On click of its row second entry point should get called. This is working fine. But when I start application there is first screen which list out the two entry points. When I click on the main, the flow begins. Can I avoid the initial screen displaying list of entry point classes? Please help asap.

    Thanks in advance.
    Regards,
    Shantanu

    Comment | August 3, 2010
  • Claudius

    Hello Shantanu,

    thank you for using gwtmultipage! The menu should only appear if no entry point is matching. Perhaps something is wrong with the regex or the JavascriptToken?

    Regards,
    Claudius

    Comment | August 3, 2010
  • Shantanu

    Thanks Claudius for your immediate reply. I have added anotation @UrlPatternEntryPoint(value = “MergeUI.html”) in MergeUI.java (main Entry point class) and similarly to another entry point class with respective html. Also I have added below entry in my gwt.xml:

    Besides these changes I have not added anything. Sp please suggest if I am missing something.

    Thanks and Regards,
    Shantanu

    Comment | August 3, 2010
  • Claudius

    Hello Shantanu,

    please dont’t forget to add “?gwt.codesvr=127.0.0.1:9997″ to your regex (see other comment above). We will add some functionality to add that automatically to the regex in future.

    Regards,
    Claudius

    Comment | August 3, 2010
  • Shantanu

    Sorry… the entries in gwt.xml are inherits name=’org.gwtmultipage.gwtmultipage’ and entry-point class=’org.gwtmultipage.client.EntrypointDispatcher’

    Regards,
    Shantanu

    Comment | August 3, 2010
  • Shantanu

    Hi Claudius,

    As per advice I have added gwt.codesvr….. to annotation.
    Still I am getting the page of list of entry point class.

    If I put the my entry point class in gwt.xml instead of EntryPointDispatcher then I am not able to see the next entry ponit html/class.

    On click of row in first entrypoint I am opening new Browser window with code Window.open(“/Screen2.html”, “”, “”);

    will this multipage framework will in case of opening multiple pages in new browser window? Please advice.

    Thanks and Regards,
    Shantanu

    Comment | August 3, 2010
  • Shantanu

    Hi Claudius,

    I have developed multipage project and as per your earlier tip to add “?gwt.codesvr=IP:9997″, the project works fine at development mode. Now I have deployed the gwt application in JBOSS with my earlier application. Now facing the same problem as earlier that the list of multipages are coming at the page first and as I am traversing by clicking at the particular html, the screen come with pages list.

    Can u please help in this regard?
    What changes I need to do in the code to work the multipage framework when deployed at JBOSS.?

    your reply is really appreciated as I am at the final stage of project and can not complete without this issue resolved.

    Thanks in advance.

    Regards,
    Shantanu

    Comment | August 27, 2010
  • Shantanu

    Hi Claudius,

    I would like to thank you for your extended support and developing a handy gwt multipage framework. It is really useful and solves my requirement to the fullest.

    As per our discussion on last friday, your solution is accurate and able to integrate the framework with my existing code.

    Thanks a ton.

    Regards,
    Shantanu

    Comment | August 30, 2010

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress. Theme: TheBuckmaker