[Java] URL Rewriting on Tomcat (or any other servlet container)

Here is a very nice little utility I found recently on an unfortunately very difficult to navigate website. In case it’s not immediately apparent from that site what I am referring to, I’m talking about the ‘UrlRewriteFilter‘ utility featured near the top of the page. This handy Filter implementation allows you to configure mod_rewrite style URL rewriting rules for your J2EE webapp. If you are having trouble navigating the official site, you can use this direct link to download ‘UrlRewriteFilter‘ version 3.2.

Sadly, apart from being difficult to navigate, some of the information on the official ‘UrlRewriteFilter‘ website pertaining to setup and usage of the filter is also incorrect/out of date. This is really quite a shame, because ‘UrlRewriteFilter‘ is an excellent little utility and I’m quite tired of seeing people needlessly running multi-server configurations (typically Apache httpd for static content, and something like Tomcat, Resin, Jetty, etc. for dynamic content) out of a desire to use this-or-that particular module that only works with httpd or (even worse) out of the outdated and no-longer-relevant notion that servlet containers cannot efficiently serve static content. So in an effort to save ‘UrlRewriteFilter‘ from obscurity and an undeserved death at the hands of poor documentation and a shoddy distribution site, here is a complete set of instructions for getting the filter to work in your webapp.

First, you will need to ensure that the ‘UrlRewriteFilter‘ JAR file is on your web-application’s classpath. How you do this will depend upon your build process/how you are constructing your webapp(s), but long story short placing the JAR file in your webapp under ‘/WEB-INF/lib’ will do the trick, and if you’ve spent any time at all working with webapps you probably already have a preferred way of doing this. Alternately, you may want to install the JAR file in your servlet container’s ‘/lib’ folder, particularly if you are deploying multiple webapps on your server and you want to have ‘UrlRewriteFilter‘ available to any/all of them automatically.

In any case, once you have the ‘UrlRewriteFilter‘ JAR on your webapp’s classpath, the real setup can begin. Open your application’s ‘web.xml‘ file, and add the following filter configuration to your webapp:

<!-- URL rewriting -->
<filter>
    	<filter-name>UrlRewriteFilter</filter-name>
      	<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
      	<init-param>
        	<param-name>logLevel</param-name>
        	<param-value>WARN</param-value>
        </init-param>
</filter>
<filter-mapping>
    	<filter-name>UrlRewriteFilter</filter-name>
    	<url-pattern>/*</url-pattern>
</filter-mapping>

This instructs the servlet container to route every request that the server receives through the ‘UrlRewriteFilter‘. Note that although it is not discussed on the official site, that ‘logLevel‘ parameter is absolutely essential. If you omit it, the filter will fail to initialize properly and yield some very bizarre behavior.

Anyways, once your ‘web.xml‘ has been updated, the final step is to add a ‘urlrewrite.xml‘ file in the same directory as your ‘web.xml‘ file, and configure it to your liking. Here is an example ‘urlrewrite.xml‘ file with a couple basic rewrite rules:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
        "http://tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
    <!-- user-account activation link -->
    <rule>
    	<from>/activate/([a-f0-9]+)?(.*)</from>
     	<to>/userController?action=activateUser&amp;token=$1&amp;$2</to>
    </rule>

    <!-- default rules included with urlrewrite -->
    <rule>
        <note>
            The rule means that requests to /test/status/ will be redirected to /rewrite-status
            the url will be rewritten.
        </note>
        <from>/test/status/</from>
        <to type="redirect">%{context-path}/rewrite-status</to>
    </rule>
    <outbound-rule>
        <note>
            The outbound-rule specifies that when response.encodeURL is called (if you are using JSTL c:url)
            the url /rewrite-status will be rewritten to /test/status/.

            The above rule and this outbound-rule means that end users should never see the
            url /rewrite-status only /test/status/ both in thier location bar and in hyperlinks
            in your pages.
        </note>
        <from>/rewrite-status</from>
        <to>/test/status/</to>
    </outbound-rule> 
</urlrewrite>

This defines two rules. The first simply rewrites URL’s of the form ‘/activate/######?[params]‘ to something like ‘/userController?action=activateUser&token=######&[params]‘, and the second is the default example rule that comes with ‘UrlRewriteFilter‘ and allows you to see a basic diagnostic page by pointing your browser at ‘[your server]/test/status‘.

And there you have it. Quite simple, really, and now there’s one less reason to continue running two distinct server instances where one would do just as well.

This entry was posted in coding, configuration, java, servlet, software and tagged , , . Bookmark the permalink.

3 Responses to [Java] URL Rewriting on Tomcat (or any other servlet container)

  1. Bernard says:

    Hi,

    I am currently facing a url issue with a web application that I have installed on a server on my LAN.

    The LAN is connected to the internet through a modem / router with a dynamic IP address. In order to access the web application from outside the LAN, I have configured a no-ip account and linked the no-ip dns to the server running the web application.

    I can now access the application from a remote computer, but some functionalities do not work. In some cases, the application launches a new window and the url in that case has “192.168.1.4:8082″ as hostname. This is the local IP address of the server on the LAN, which is not known outside of the LAN. In order to work, it should be my no-ip dns.

    On the forum of the web application I have been advised to use url rewriting to solve this problem, but I am not sure if it would work as I don’t even reach the web server. Could you advise me on this?

    Thanks in advance.

  2. cyrus says:

    Hi,

    I’m a newbie to tomcat. I’ve installed tomcat on my unix system using the tar.gz distribution. I want to redirect request to one(let’s say XYZ) of my webapis to other(let’s say ABC). So the request http://localhost:8080/XYZ/select?a=b should get redirected to http://localhost:8080/ABC/select?a=b.
    I placed the urlrewrite-4.0.0.jar inside pathToTomcatExtractionFolder/lib folder

    I edited the web.xml file present inside pathToTomcatExtractionFolder/conf/web.xml and added :

    UrlRewriteFilter
    org.tuckey.web.filters.urlrewrite.UrlRewriteFilter

    logLevel
    WARN

    UrlRewriteFilter
    /*

    I’ve placed urlrewrite.xml inside pathToTomcatExtractionFolder/conf/. and defined this rule inside it:

    /XYZ/select?(.*)
    /ABC/select?$1

    After this I restarted the tomcat but even then when I call http://localhost:8080/XYZ/select?a=b in my browser, it’s not getting redirected.

    Thanks

  3. Shakeel says:

    How can I see this in action? Filter seems to be deployed properly but I don’t know if it is working. Where can I see that?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>