2010-09-17 2 views
19

У меня есть 2 фильтра в моем приложении. Исходя из некоторого условия, я хочу выбрать, выполнять ли второй фильтр или нет. Есть ли способ сделать это?Как пропустить фильтр в цепочке фильтров в java

Я сделал несколько поисковых запросов без успеха. Я хочу, чтобы запрос продолжался без выполнения второго фильтра. Это возможно?

Любая помощь будет оценена по достоинству.

ответ

9

Вы можете установить Атрибут в своем запросе и проверить его во втором фильтре.

public class FirstFilter implements Filter { 
    //... 

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     servletRequest.setAttribute("executeSecondFilter", true); 
     //... 
     if(someReason) 
      servletRequest.setAttribute("executeSecondFilter", false); 
     filterChain.doFilter(servletRequest, servletResponse); 
    } 
} 

public class SecondFilter implements Filter { 
    //.. 

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     if (servletRequest.getAttribute("executeSecondFilter") == null || !((Boolean) servletRequest.getAttribute("executeSecondFilter"))) { 
      filterChain.doFilter(servletRequest, servletResponse); 
     } 
     //... 
    } 
} 

Вы можете упростить код, приведенный выше, как это:

public class FirstFilter implements Filter { 
    //... 

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     //... 
     if(someReason) 
      servletRequest.setAttribute("executeSecondFilter", false); 
     filterChain.doFilter(servletRequest, servletResponse); 
    } 
} 

public class SecondFilter implements Filter { 
    //.. 

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     if (servletRequest.getAttribute("executeSecondFilter") != null) { 
      filterChain.doFilter(servletRequest, servletResponse); 
     } 
     //... 
    } 
} 

Таким образом, вы просто проверить наличие атрибута «executeSecondFilter»

+1

Приятная идея, но этот пример вызовет NPE, если атрибут не установлен. – BalusC

+1

@BalusC, поэтому я положил '! = True', но auto-unboxing выиграл сравнение Object, теперь он исправлен :) –

+1

Вы также можете использовать' Boolean.TRUE'. Тем не менее, я лично считаю это уродливым;) – BalusC

47

В дополнение к ответу Колина, есть другой способ: просто не звоните FilterChain#doFilter(), но RequestDispatcher#forward().

if (condition) { 
    request.getRequestDispatcher(((HttpServletRequest) request).getServletPath()).forward(request, response); 
} else { 
    chain.doFilter(request, response); 
} 

Но это пропустит всех фильтров от тока на, ожидает от тех, которые слушают на <dispatcher>FORWARD</dispatcher>.

+1

Хорошее решение. Но мы думали, что будем делать атрибут, потому что он немного проще. –

+6

Добро пожаловать. Однако это единственное решение, когда исходный код другого фильтра полностью не контролируется (сторонний участник и т. Д.). – BalusC

+8

Приведенный выше пример забывает часть URL-адреса после базового пути сервлета. Это исправит это: request.getRequestDispatcher (((HttpServletRequest) запрос) .getServletPath() + StringUtils.defaultString (((HttpServletRequest) запрос) .getPathInfo())) .forward (запрос, ответ); – Cojones

 Смежные вопросы

  • Нет связанных вопросов^_^