Grails and UrlRewriteFilter: Problem with Params

I’m using UrlRewriteFilter to map some legacy URLs to our new Grails application. It’s configured as follows:

web.xml

...
<filter>
    <filter-name>rewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>charEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
	<filter-name>rewriteFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>

urlrwrite.xml

...
<rule>
	<from>^/legacy-search-url$</from>
	<to last="true">/search/result</to>
	<set type="parameter" name="pagesize">5</set>
</rule>

Now I had the problem that the forward worked as expected (SearchController with action “result” was invoked), but in params parameter pagesize was missing.

After a while of debugging I found out the following:
GrailsWebRequest, which holds the params is created with the GrailsWebRequestFilter. This filter is added to the web.xml in the controllers-plugin and the filter-mapping is placed at the end or after the charEncodingFilter. In my case after charEncodingFilter and so before the rewriteFilter:

generated web.xml

<filter-mapping>
    <filter-name>charEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
	<filter-name>grailsWebRequest</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>FORWARD</dispatcher>
	<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
	<filter-name>sitemesh</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
	<filter-name>rewriteFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>

That means that the params-object is created before the rewriting happens, which explains that the pagesize parameter is not there. The solution is to place the rewriteFilter in first position of the filter-mapping or at least before the charEncodingFilter (if present).

Rethinking the problem I had the opinion that it should work regardless to the order, as the grailsWebRequest-filter has a forward dispatcher and should be called again after the rewriting. That’s correct so far, but as GrailsWebRequestFilter extends OncePerRequestFilter the GrailsWebRequest is not recreated on the second call.

Hint: If you are using the URL Rewrite Plugin, you will have the same problems, as it is loaded after the controllers-Plugin.

Versions: Grails 1.1.1

Posted in Grails. Tags: . 1 Comment »