2010-08-12 88 views
6

有什麼辦法讓filtermapping不包含子目錄嗎?過濾器映射url-pattern不包括子目錄

例如。

我在我的上下文根中有.xhtml文件,我也有一個名爲「test」的子文件夾,文件的擴展名相同。有沒有可能將過濾器映射到上下文根中的文件而不是「test」目錄中的文件?

回答

17

url-pattern確實是限制性的匹配。它只允許準確的,前綴或後綴matchnig。不是中間/整體/正則表達式匹配。所以例如/*.xhtml你打算做什麼是行不通的。

如果你想在/test文件夾排除XHTML而已,那麼你最好是一個真正的Filter監聽的*.xhtml基本上做以下工作在doFilter()方法的url-pattern

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

我首先想到在Filter中硬編碼?但init-param很聰明。在這裏學到了些東西。 – JoseK 2010-08-13 11:35:37

+0

@Jose:不客氣。 – BalusC 2010-08-13 11:58:22

-1

某些容器(如樹脂)定義了一個擴展來過濾web.xml中的映射定義,該擴展允許指定url-regexp,它允許基於正則表達式匹配url。 (reference)。看看你的容器是否有這樣的東西。

0

由於*.ext風格映射包含子目錄,因此使用標準servlet /過濾器可用的內容,沒有直接排除子目錄的方法。您可以通過聲明另一個專門處理/test/*.xhtml映射的過濾器並相應地處理該過濾器來解決此問題。

+0

但一個映射/ *的過濾器仍然包括/ /下的所有東西它會不會? – 2010-08-12 12:58:43

+0

這是正確的。我在想,第一個匹配的是使用的,但事實並非如此。相反,你可以在你的過濾器中添加一個url正則表達式檢查 - 如果它匹配正則表達式,那麼過濾器在委託給重新生成過濾器鏈之前執行它的工作。如果正則表達式不匹配,只是委託給過濾器鏈而不做任何工作。 – mdma 2010-08-12 14:42:07

3

的解決方案,基本上你需要自己的過濾器類,並定義排除網址爲INIT-參數有關過濾

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

,並定義過濾器,映射和在web.xml中排除URL的

<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分鐘的時間來更正格式。解決方案,基本上你需要你自己的過濾器類,並定義排除網址作爲過濾器的init-param。 – softskin 2014-01-20 17:11:57

0

您可以爲上下文根中的每個文件添加一個url-mapping值,因此篩選器將應用於這些文件,但不會應用於測試文件夾中的文件(實際上它只適用於這些特定文件)。下面的工作對我來說

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