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