Thursday, October 01, 2009

Url Rewrite Filter duplicates query string parameters

Sun's Webspace portal uses tuckey.org's Url Rewrite Filter, in which you place a bunch of URL rewrite rules in urlrewrite.xml. This is a great way to implement friendly URLs. For example, you can have an easy to type URL that the public will use such as http://www.example.com/search which the Url Rewrite Filter will route to the real portlet/servlet: http://www.example.com/real/path/to/search.

I was debugging a search service when I noticed that the request parameters values were being duplicated by the time it hit my controller. I.e. I was expecting single value parameters in my request:

querywinter sport
advancedSearchfalse

But found this instead (multi valued parameters):

querywinter sportwinter sport
advancedSearchfalsefalse

It turns out that the Url Rewrite Filter was was configured to propagate query parameters when it didn't need to. I.e. I had the following rule in place:

<rule>
   <from>^/search(.*)$</from>
   <to type="forward">/real/path/to/search$1</to>
</rule>

The $1 at the end of the TO element means: put the query parameters (the (.*) grouping in the FORM element) back on the end of the URL. This isn't needed because the Url Rewrite Filter is invoked after the query string has already been processed: the query string parameters have already been parsed and put in the Request object. Thus, the Url Rewrite Filter caused the parameters to be processed a second time.

The fix was simple, once I understood the reason. Just drop $1 from the end of the TO element.

<rule>
   <from>^/search(.*)$</from>
   <to type="forward">/real/path/to/search</to>
</rule>