Whenever I set up a new site, I want to make sure that example.com points to www.example.com. As writers say, students always buy a book report on the Internet this is basic SEO – check out this link for a quick explanation. I know that this is trivial to do in Apache, but for the sake of simplicity, I wanted to use Tomcat only as my web server.

After much searching around, it became clear that (1) Tomcat can’t do this, and (2) I’m not the only person with this problem. The solution is a Java servlet filter called URLRewriteFilter. It does the job perfectly, but it took me a while to get it set up right, so here’s a quick how-to for anyone else in the same position.

The instructions on the project’s homepage will get you most of the way there. You unzip the contents of the binary download (a single .jar and a config file) into your context’s directory, then add a servlet mapping to make sure that UrlRewriteFilter gets to handle all requests. Make sure that the UrlRewriteFilter servlet mapping goes at the top of the web.xml file, to ensure that the filter gets to see HTTP requests before any other servlet.

The tricky part is getting the config file WEB-INF/urlrewrite.xml just right, so here’s the configuration that worked for me:

<urlrewrite>
<rule>
    <name>seo redirect</name>
    <condition name="host" operator="notequal">^www\.example\.com</condition>
    <from>^/(.*)</from>
    <to type="permanent-redirect" last="true">http://www.example.com/$1</to>
</rule>
</urlrewrite>

The condition element tells us that we want to trigger this rule when the HTTP request host header is not equal to www.example.com. Because it’s a regular expression, we escape the dots with backslashes (and use a start-anchor for good measure). The from element uses parentheses to capture the whole of the path the the resource that’s being asked for, minus the starting forward slash. Of course, if the request is just for example.com (probably the most common scenario) then this will be empty. The captured value is then used in the to element to construct that path for the redirect. So example.com/tour.jsp should redirect to www.example.com/tour.jsp.

Update

A quick update to mention a gotcha that I ran into; if you set up UrlRewriteFilter as described above then it will redirect you if you try to access your website on your development machine by going to localhost:8080. This can lead to very frustrating scenarios involving repeatedly hitting F5 while muttering “why aren’t you showing my changes, dammit?” and failing to notice that the address bar reads www.mywebsite.com. Because UrlRewriteFilter lets you have multiple conditions, it’s quite easy to get the correct behaviour:

<urlrewrite>
<rule>
    <name>seo redirect</name>
    <condition name="host" operator="notequal">^www\.example\.com</condition>
    <condition name="host" operator="notequal">^localhost</condition>
    <from>^/(.*)</from>
    <to type="permanent-redirect" last="true">http://www.example.com/$1</to>
</rule>
</urlrewrite>

Subscribe to articles from the web category via RSS or ATOM

Comments


comments powered by Disqus