Проблема цикла перезаписи URL-адреса фильтра Java

Я надеюсь, что кто-то может указать, где я ошибаюсь. Я пытаюсь создать простой фильтр, который работает примерно так же, как 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>

Некоторые примечания по коду: URI типа /home следует пересылать сервлету-диспетчеру следующим образом: /Dispatcher?q=/home сервлет-диспетчер затем определяет, какой код выполнять, основываясь на том, что находится в строке запроса.

Фильтр корректно игнорирует URI в ArrayList "uriIgnore" (включая /Dispatcher), но переадресация продолжает зацикливаться на /home. Для полноты картины вот содержимое списка uriIgnore ArrayList, который ищется в методе uriIsDispatchable выше:

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");
}

Кроме того, я использую последнюю версию Tomcat 6, проксированную за Apache.

Любая помощь приветствуется. Спасибо.


person Community    schedule 20.12.2010    source источник


Ответы (3)


Я думаю, что когда программа выполняет оператор: 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() или нет, поэтому он может распознать и затем переслать URL-адрес или нет.

person Jack Ding    schedule 20.12.2010
comment
Переадресация вызовет повторный запуск doFilter, но я думаю, что проблема в том, что переадресованный запрос сохраняет исходный URI, а не пересылаемый URI, что вызывает цикл. Из того, что я могу понять из кода URLRewriteFilter, он использует тот же прямой вызов, что и я, но не зацикливается. Я попробовал Tuckey URLRewiriteFilter на своем сервере с теми же правилами, и он отлично работает. Я уверен, что это что-то простое и очевидное, что мне не хватает. - person ; 20.12.2010

Я займусь этим, когда у меня будет время для дальнейшего изучения кода фильтра URLRewrite, но в то же время кажется, что если я действительно хочу переписать 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>
person Community    schedule 21.12.2010
comment
Когда я найду решение этого вопроса на Java, я обязательно опубликую его здесь. - person ; 22.12.2010

Та же проблема с бесконечным циклом здесь, настройте urlrewriter чтобы отфильтровать только ЗАПРОС, а не ВПЕРЕД, попробуйте что-то подобное в своем web.xml:

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

В этом случае обработка правила не выполняется снова после перенаправления.

person Daniel Hári    schedule 04.10.2016