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