为啥 Tuckey UrlRewrite Filter 在规则匹配后不调用chain.doFilter?

Posted

技术标签:

【中文标题】为啥 Tuckey UrlRewrite Filter 在规则匹配后不调用chain.doFilter?【英文标题】:Why Doesn't Tuckey UrlRewrite Filter call chain.doFilter after a rule is matched?为什么 Tuckey UrlRewrite Filter 在规则匹配后不调用chain.doFilter? 【发布时间】:2011-06-29 22:32:12 【问题描述】:

这里使用 Spring 框架...

我创建了一个过滤器来更改 css 文件的响应主体,如果我直接调用一个 url,它就会运行。但是,如果匹配 urlrewrite 规则,则会跳过过滤器。

示例: 在 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>

在urlrewrite.xml中有这样一个映射设置:

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

(我们需要这个有很多原因)

因此,任何路径以“/styles-special/”开头的 *.css 文件都将被重写为“/styles/”,并且不会调用 cssFilter,但任何路径以 w 开头的 *.css 文件/ "/styles/" 将按预期运行cssFilter。

我尝试将 cssFilter 的 url 模式更改为多个不同的选项,但结果相同。在我看来, tuckey urlrewrite 过滤器只是在重写后不调用 chain.doFilter() ,但也许它比这更复杂?

知道这里可能存在什么问题吗?这是预期的功能吗?任何解决方法? ...也许拦截器或控制器是去这里的方式?

提前感谢您对此的任何建议!


注意:使用以下内容(由 axtavt 建议):

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

修复了链接问题并运行了过滤器。但是,我收到以下错误:

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)

这是来自过滤器的代码 sn-p:

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
...

【问题讨论】:

【参考方案1】:

当 Tuckey UrlRewrite Filter 重写 URL 时,它会将请求转发到新 URL,而不是将其传递到过滤器链中。默认情况下,过滤器不会应用于转发的请求,因此您需要对其进行配置:

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

【讨论】:

太棒了!当我添加它时,过滤器就会运行!不幸的是,当我在 GenericResponseWrapper 上调用 getData 时出现错误。嗯,我如何发布代码 sn-p? 不确定这是否是标准的 *** 做法,但我编辑了原始帖子以回复此答案。感谢您提供的信息,如果您有更多信息,将不胜感激。 ...显然,请求正在发生一些事情,但我不知道它可能是什么。 @tkane2000:GenericResponseWrapper 是什么?另外,您确定异常发生在标记的行吗? GenericResponseWrapper 扩展了 HttpServletResponseWrapper 并创建了一个新的 java.io.ByteArrayOutputStream。无论如何,你是对的,问题实际上出在过滤器映射上。我已将 url-pattern 更改为“/styles/*”,因为这也是它转发的内容,但它不喜欢这样,并且“/styles-special/*”也不起作用。把它改回“*css”就可以了,所以希望这就足够了。肯定显得有些喜怒无常! 谢谢!之后我必须在 Tuckey 中使用 last="true" 和我自己的过滤器,所以这对我很有帮助!

以上是关于为啥 Tuckey UrlRewrite Filter 在规则匹配后不调用chain.doFilter?的主要内容,如果未能解决你的问题,请参考以下文章

urlrewrite与struts2结合使用基本配置

使用urlrewritefilter发现部分请求url报404

UrlRewriteFilter 错误

FORM范围总是空的? URL范围好吗?

如何从 URL、Spring Boot 和 AngularJs 应用程序中删除 #?

Tuckey 过滤器 - https 重定向