2010-08-12 2 views
6

Есть ли способ сделать, чтобы mapfapping не включал подкаталоги?Фильтр, отображающий url-шаблон, который исключает подкаталоги

Например.

У меня есть .xhtml файлы в моем контексте root, и у меня также есть подпапка с именем "test" с файлами с тем же расширением. Можно ли сопоставить фильтр с файлами в корне контекста, а не с файлами в «тестовом» каталоге?

ответ

17

url-pattern действительно ограничительный в соответствии. Он позволяет только точный, префиксный или суффиксный матчин. Совпадение не среднее/общее/регулярное. Так, например, /*.xhtml то, что вы намереваетесь сделать, не сработает.

Если вы хотите исключить XHTML в папке /test только, тогда лучше действительно Filter слушать на url-pattern из *.xhtml, который делает в основном следующую работу в doFilter() метода:

// First cast ServletRequest to HttpServletRequest. 
HttpServletRequest hsr = (HttpServletRequest) request; 

// Check if requested resource is not in /test folder. 
if (!hsr.getServletPath().startsWith("/test/")) { 
    // Not in /test folder. Do your thing here. 
} 

В HttpServletRequest#getServletPath() основном возвращает часть URI запроса из контекстного пути.

Вы можете при необходимости сконфигурировать значение /test в качестве фильтра <init-param>, чтобы вы могли управлять значением изнутри web.xml, а не в коде фильтра.

+1

Я сначала подумал, что жесткий фильтр в фильтре? но init-param умный. Узнали что-то здесь. – JoseK

+0

@Jose: добро пожаловать. – BalusC

-1

Некоторые контейнеры (например, смола) определяют расширение для определения отображения фильтра в web.xml, которое позволяет указать url-regexp, что позволяет сопоставлять URL-адреса на основе регулярного выражения. (reference). Посмотрите, есть ли в вашем контейнере что-то вроде этого.

0

Используя то, что доступно для стандартных сервлетов/фильтров, нет прямого способа исключить подкаталог, поскольку сопоставления типов *.ext включают подкаталоги. Вы можете обойти это, объявив еще один фильтр, который специально обрабатывает отображение /test/*.xhtml и обрабатывает его соответствующим образом.

+0

Но фильтр с отображением/* все равно включил бы все под/тест, не так ли? –

+0

Это правильно. Я думал, что первый из них соответствует тому, который используется, но это не тот случай. Вместо этого вы можете добавить проверку регулярного выражения url в свой фильтр - если он соответствует регулярному выражению, тогда фильтр выполняет его работу до делегирования в цепочку останова фильтра. Если регулярное выражение не совпадает с ним, оно просто делегирует цепочку фильтров без какой-либо работы. – mdma

3

Решение, в принципе вам нужен собственный класс фильтра и определить исключающие URL, как инициализации-параметров для фильтра

package test; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class LoginValidationFilter implements Filter { 

    private String loginPage = ""; 
    private List<String> excludedURLs; 

    public void init(FilterConfig filterConfig) throws ServletException { 
     this.loginPage = filterConfig.getInitParameter("loginPage"); 

     String[] excluded = filterConfig.getInitParameter("excludedURLs").split(";"); 
     excludedURLs = new ArrayList<String>(); 
     for (int i = 0; i < excluded.length; i++) { 
      excludedURLs.add(excluded[i]); 
     } 
    } 

    public void destroy() { 
     this.loginPage = ""; 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, 
      ServletException { 

     HttpServletRequest httpRequest = request instanceof HttpServletRequest ? (HttpServletRequest) request : null; 
     HttpServletResponse httpResponse = response instanceof HttpServletResponse ? (HttpServletResponse) response 
       : null; 

     if (httpRequest == null || httpResponse == null) { 
      filterChain.doFilter(request, response); 
      return; 
     } 

     boolean isExcludedURL = false; 
     for (int i = 0; i < excludedURLs.size(); i++) { 
      if (httpRequest.getRequestURL().indexOf(excludedURLs.get(i)) > -1) { 
       isExcludedURL = true; 
       break; 
      } 
     } 

     if (isExcludedURL) { 
      filterChain.doFilter(request, response); 
     } else { 
      if (UserUtil.validateUserLogin(httpRequest)) { 
       filterChain.doFilter(request, response); 
      } else { 
       httpResponse.sendRedirect(httpRequest.getContextPath() + loginPage); 
      } 
     } 
    } 
} 

и определить фильтр, отображение и исключить URL-адреса в web.xml

<filter> 
    <filter-name>LoginValidationFilter</filter-name> 
    <filter-class>test.LoginValidationFilter</filter-class> 
    <init-param> 
     <param-name>loginPage</param-name> 
     <param-value>/login.jsp</param-value> 
    </init-param> 
    <init-param> 
     <param-name>excludedURLs</param-name> 
     <param-value>/admin/;/assets/;/content/;/css/;/js/;/login.jsp;/login.cmd;/logout.cmd;forgot_password.jsp;pageName=</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>LoginValidationFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+0

Извините, это мой первый пост, мне потребовалось около 30 минут, чтобы исправить формат. Решение, в основном вам нужен свой собственный класс фильтра и определить исключение URL-адресов как init-param для фильтра. – softskin

0

Вы можете добавить значение URL-адреса для каждого файла, который у вас есть в корне контекста, поэтому фильтр будет применяться к этим файлам, но не к файлам в тестовой папке (на самом деле это применимо только к этим конкретным файлам). Следующие работали для меня

<url-pattern>/index.faces</url-pattern> 

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

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