Enhancing your GWT Application with the UrlRewriteFilter
Last week, I spent some time trying to change the location of my cache/nocache HTML files in my GWT project. I started the project with the gwt-maven-plugin's archetype. The message I posted to the gwt-maven Google Group is below.
Rather than having my application's HTML file in
src/main/java/com/mycompany/Application.html, I'd like to move it to
src/main/webapp/index.html. I tried copying the HTML and adding the
following to my index.html, but no dice:
<meta name="gwt:module" content="com.mycompany.Application"/>
Is this possible with the gwt-maven-plugin? I'd like to have my main
HTML and CSS at the root of my application.
The good news is I figured out a solution using the UrlRewriteFilter that 1) allows hosted mode to work as usual and 2) allows your app to be served up from the root URL (/ instead of /com.company.Module/Application.html). Here's the urlrewrite.xml that makes it all possible.
<?xml version="1.0" encoding="UTF-8"?> <!DOCENGINE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN" "http://tuckey.org/res/dtds/urlrewrite3.0.dtd"> <urlrewrite> <rule> <from>^/$</from> <to type="forward" last="true">/com.mycompany.app.Application/Application.html</to> </rule> <rule> <from>/index.html</from> <to type="forward" last="true">/com.mycompany.app.Application/Application.html</to> </rule> <-- This last rule is necessary for JS and CSS files --> <rule> <from>^/(.*)\.(.*)$</from> <to type="forward">/com.mycompany.app.Application/$1.$2</to> </rule> </urlrewrite>
If you're using the gwt-maven plugin, this file goes in src/main/webapp/WEB-INF
. In addition, you'll need to add the following to your web.xml.
<filter> <filter-name>rewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>rewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Finally, add the UrlRewriteFilter dependency in your pom.xml:
<dependency> <groupId>org.tuckey</groupId> <artifactId>urlrewritefilter</artifactId> <version>3.1.0</version> </dependency>
Please let me know if you have any questions.
Update: Jeff posted an alternative configuration that allows you to eliminate the last rule in urlrewrite.xml, as well as use the beloved mvn jetty:run command. To use cleaner WAR packaging and the Jetty plugin, add the following to your pom.xml:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <webappDirectory> ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application </webappDirectory> </configuration> </plugin> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.14</version> <configuration> <webAppConfig> <contextPath>/</contextPath> <baseResource implementation="org.mortbay.resource.ResourceCollection"> <resourcesAsCSV> ${basedir}/src/main/webapp, ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application </resourcesAsCSV> </baseResource> </webAppConfig> <scanIntervalSeconds>3</scanIntervalSeconds> <scanTargets> <scanTarget>${basedir}/src/main/resources</scanTarget> <scanTarget>${basedir}/src/main/webapp/WEB-INF</scanTarget> <scanTarget> ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application </scanTarget> </scanTargets> </configuration> </plugin>
Then you can trim your urlrewrite.xml down to:
<urlrewrite> <rule> <from>^/$</from> <to type="forward" last="true">/Application.html</to> </rule> <rule> <from>/index.html</from> <to type="forward" last="true">/Application.html</to> </rule> </urlrewrite>
Of course, you could also change the welcome-file in your web.xml or use index.html and the <meta http-equiv="REFRESH"> option. Personally, I have so much affection for the UrlRewriteFilter that I like having it in my project. I'm sure I'll need it someday.
Thanks Jeff!
Won't the rule "/$" match anything with a trailing slash in the URL? Is this the behaviour you're after? E
Posted by Elwyn Malethan on February 24, 2009 at 09:52 AM MST #
Posted by 209.181.65.238 on February 24, 2009 at 03:55 PM MST #
Posted by Jeff Genender on February 24, 2009 at 03:55 PM MST #
@Elwyn - you are correct. The manual suggests using <from>^/$</from>. I tried that and it works. I'll update the post.
@Jeff - I'd definitely be interested in that configuration. Can you post it here (or at least a link to a sample)? Might be easiest to reply to my thread on the gwt-maven mailing list.
Posted by Matt Raible on February 24, 2009 at 04:06 PM MST #
Posted by Jeff Genender on February 24, 2009 at 05:00 PM MST #
Posted by Clay Mitchell on March 04, 2009 at 07:02 PM MST #
Posted by Asha on March 25, 2009 at 08:39 AM MDT #
Posted by Asha on March 25, 2009 at 09:47 AM MDT #
Posted by Matt Raible on March 25, 2009 at 02:45 PM MDT #
Thanks Matt. I would like to explain in detail. I have a gwt apps, which I am currently accessing as http://localhost:8080/myapp/myapp.html. I want to remove this myapp/myapp.html part from url and replace with some myportal. How would I achieve this using urlrewritefilter. I added rule for this as
But this does not work. Please suggest.
Posted by Asha on March 26, 2009 at 04:32 AM MDT #
@Asha: the <from> is the url that the user is requesting.
Turn on logging (see http://tuckey.org/urlrewrite/manual/2.6/) and you'll see the webapp name doesn't get passed into the pattern. You want something like <from>/myapp.html</from>.
Posted by Matthew McEachen on July 23, 2009 at 04:42 AM MDT #
Thanks for the tutorial!
In my case, it worked only when I put / followed by the HTML.
Posted by Rodrigo Marini on November 09, 2011 at 01:35 PM MST #
Hey Matt!
I saw your article here on Rewriting and GWT, thought you might be interested in this...
https://github.com/ocpsoft/rewrite/tree/master/integration-gwt
...an extension to http://ocpsoft.org/rewrite/
Worth mentioning? :) I think it simplifies this example a good deal (particularly if running in a Servlet 3.0 environment!
~Lincoln
Posted by Lincoln Baxter, III on April 11, 2012 at 12:59 PM MDT #