5

Using Spring Framework here...

I created a filter to change the response body of css files and if I call a url directly it runs. However, if a urlrewrite rule is matched the filter is skipped.

Example: In web.xml:

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    <!-- skipping init params here for brevity -->
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>cssFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
    <filter-mapping>
    <filter-name>cssFilter</filter-name>
    <url-pattern>*css</url-pattern>
</filter-mapping>

There is a mapping set up like this in urlrewrite.xml:

<rule>
    <from>/styles-special/(.*)$</from>
    <to last="true">/styles/$1</to>
</rule>

(we need this for a number of reasons)

so, any *.css file whose path starts w/ "/styles-special/" will be rewritten to "/styles/" and the cssFilter won't be called, but any *.css file whose path starts w/ "/styles/" will run through the cssFilter as expected.

I've tried changing the url-pattern for cssFilter to a number of different options, but same result. It seems to me like the tuckey urlrewrite filter just doesn't call chain.doFilter() after a rewrite, but maybe it's more complicated than that?

Any idea what the issue might be here? Is this expected functionality? Any workarounds? ...maybe an interceptor or controller is the way to go here?

Thanks in advance for any advice on this!!


Note: Using the following (as suggested by axtavt):

<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>

Fixes the issue w/ chaining and the Filter is run. However, I get the following error:

java.lang.IllegalStateException: NO CONTENT
at org.mortbay.jetty.HttpGenerator.addContent(HttpGenerator.java:106)
at org.mortbay.jetty.AbstractGenerator$Output.write(AbstractGenerator.java:644)
at org.mortbay.jetty.AbstractGenerator$Output.write(AbstractGenerator.java:579)

Here's code snippet from Filter:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    OutputStream out = httpResponse.getOutputStream();
    GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse);

    chain.doFilter(request, wrapper);

    if(log.isDebugEnabled()) log.debug("doFilter: chain");

    String respBody = new String(wrapper.getData()); // this throws error
...
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
tkane2000
  • 485
  • 5
  • 11

1 Answers1

14

When Tuckey UrlRewrite Filter rewrites a URL, it forwards request to the new URL instead of passing it down the filter chain. By default filters are not applied to the forwarded requests, so you need to configure it:

<filter-mapping>
     <filter-name>cssFilter</filter-name>
     <url-pattern>*css</url-pattern>
     <dispatcher>REQUEST</dispatcher>
     <dispatcher>FORWARD</dispatcher>
</filter-mapping>
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • Awesome! The filter runs when I add that! Unfortunately, I get an error when I call getData on GenericResponseWrapper. hmm, how do I post code snippet? – tkane2000 Feb 18 '11 at 18:59
  • Not sure if this is standard stackoverflow practice, but I edited the original post to reply to this answer. Thanks for the info and if you have any more it'd be greatly appreciated. ...clearly something is happening w/ the request, but I have not clue what it could be. – tkane2000 Feb 18 '11 at 19:09
  • @tkane2000: What is a `GenericResponseWrapper`? Also, are you sure that exception happens at the marked line? – axtavt Feb 19 '11 at 11:29
  • GenericResponseWrapper extends HttpServletResponseWrapper and creates a new java.io.ByteArrayOutputStream. Anyway, you're right, the problem was actually with the filter-mapping. I had changed the url-pattern to "/styles/*", since that's what it forwards too, but it didn't like that and "/styles-special/*" didn't work either. Changing it back to "*css" did the trick, so hopefully that will be sufficient. It definitely seems to be a bit temperamental! – tkane2000 Feb 20 '11 at 20:50
  • Thank you! I have to use `last="true"` in Tuckey and my own filter afterwards, so this was very helpful to me! – sebastian Oct 14 '15 at 11:56