过滤映射url-pattern,排除子目录

有没有办法让filtermapping不包含子目录?

例如。

我的上下文根目录中有.xhtml文件,我还有一个名为“test”的子文件夹,其文件具有相同的扩展名。 有没有可能将filter映射到上下文根目录中的文件而不是“test”目录中的文件?

url-pattern在匹配方面确实是限制性的。 它只允许精确,前缀或后缀matchnig。 不在中间/整体/正则表达式匹配。 所以例如/*.xhtml你打算做什么是行不通的。

如果你只想在/test文件夹中排除XHTML,那么你最好的是一个Filter监听*.xhtmlurl-pattern ,它基本上完成了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配置为filter的 ,以便您可以从web.xml内部而不是Filter的代码中控制值。

解决方案,基本上您需要自己的Filter类并将排除的URL定义为filter的init-param

 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 excludedURLs; public void init(FilterConfig filterConfig) throws ServletException { this.loginPage = filterConfig.getInitParameter("loginPage"); String[] excluded = filterConfig.getInitParameter("excludedURLs").split(";"); excludedURLs = new ArrayList(); 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中定义filter,映射和排除URL

  LoginValidationFilter test.LoginValidationFilter  loginPage /login.jsp   excludedURLs /admin/;/assets/;/content/;/css/;/js/;/login.jsp;/login.cmd;/logout.cmd;forgot_password.jsp;pageName=    LoginValidationFilter /*  

使用可用于标准servlet /filter的内容,没有直接的方法来排除子目录,因为*.ext样式映射包含子目录。 你可以通过声明另一个专门处理/test/*.xhtml映射的filter并相应地处理它来解决这个问题。

您可以为上下文根中的每个文件添加url-mapping值,因此filter将应用于这些文件,但不会应用于测试文件夹中的文件(实际上它只适用于那些特定文件)。 以下对我有用

 /index.faces 

一些容器(如树脂)定义了一个扩展来过滤web.xml中的映射定义,允许指定url-regexp ,它允许基于正则表达式匹配url。 ( 参考 )。 看看你的容器是否有这样的东西。