Java过滤器URL重写循环问题

时间:2010-12-20 00:18:55

标签: java url-rewriting servlet-filters

我希望有人能指出我在哪里出错了。我正在尝试创建一个类似于Paul Tuckey's URLRewriteFilter的简单过滤器,但是我只需按照我需要的那样去做。

我无法让它停止循环回原始URI。我已经窥探了URLRewriteFilter代码,它似乎基本上和我正在做的事情一样。这是我的过滤器代码:

public static final String dispatcherURI = "/Dispatcher?q=";
public void doFilter(final ServletRequest request, final ServletResponse response,
                     final FilterChain chain)
        throws IOException, ServletException {
    final HttpServletRequest rq = (HttpServletRequest)request;
    final HttpServletResponseWrapper rsw =
        new HttpServletResponseWrapper((HttpServletResponse)response);
    final String uri = rq.getRequestURI();
    if (uriIsDispatchable(uri)) {
        final String forwardPath = dispatcherURI+uri;
        rq.getRequestDispatcher(forwardPath).forward(rq, rsw);
        LOG.info("Forward From: "+uri+", To: "+forwardPath);
    }
    else {
        try { chain.doFilter(request, response); }
        catch (Exception e) {
            LOG.error(e);
            throw new RuntimeException(e);
        }
    }
}

// checks URI against an ArrayList of URIs that should be ignored.
private static boolean uriIsDispatchable (final String uri) {
    boolean result = true;
    for (String i : ApplicationValues.uriIgnore) {
        if (uri.indexOf(i) == 0) {
            result = false;
            break;
        }
    }
    return result;
}

这是web.xml中的过滤条目

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>myapp.filter.URLRewrite</filter-class>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

关于代码的一些注意事项: 像/ home这样的URI应该转发给调度程序servlet,如:/ Dispatcher?q = / home 然后,调度程序servlet根据查询字符串中的内容确定要执行的代码。

过滤器正确地忽略了“uriIgnore”ArrayList(包括/ Dispatcher)中的URI,但是forward继续在/ home上循环。为了完整起见,这里是在上面的uriIsDispatchable方法中搜索的uriIgnore ArrayList的内容:

public static final List<String> uriIgnore = new ArrayList<String>(4);
static {
  uriIgnore.add("/Dispatcher");
  uriIgnore.add("/netbeans-tomcat-status-test");
  uriIgnore.add("/resources");
  uriIgnore.add("/robots.txt");
}

另外,我正在运行代替Apache的最新Tomcat 6。

感谢任何帮助。感谢。

3 个答案:

答案 0 :(得分:2)

我认为当程序执行语句时:rq.getRequestDispatcher(forwardPath).forward(rq,rsw); 它会调用doFilter() method again, and then the program will be an endless loop. I think you can add a parameter to tell the url is from another doFilter()与否,因此它可以识别并转发网址。

答案 1 :(得分:1)

当我有时间仔细阅读URLRewrite Filter代码时,我会解决这个问题,但与此同时,如果我真的想要最高性能的URL重写,我会让mod_rewrite和Apache做它

我的解决方案(我确信还有更好的方法可以做到这一点):

# .htaccess file contents
# Apache has the same docroot as the Java web app.
# Java webapp is running on port 8084
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f [NC,OR]
RewriteCond %{REQUEST_FILENAME} !-d
# directory where images, static html files and JS scripts are located.
# Apache will serve these.
RewriteRule ^resources - [L,NC]
# obviously, we want Apache to serve robots.txt
RewriteRule ^robots.txt$ - [L,NC]
RewriteRule ^(.*)$ http://localhost:8084/Dispatcher?q=$1 [L,P,QSA]
</IfModule>

答案 2 :(得分:0)

相同的无限循环问题 here,配置urlrewriter只过滤REQUEST,而不是FORWARD,尝试一下 在你的web.xml中这样:

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

在这种情况下,转发后不再执行规则处理。