7

有什么方法可以使过滤器映射不包含子目录?

例如。

我的上下文根中有 .xhtml 文件,还有一个名为“test”的子文件夹,其中包含具有相同扩展名的文件。是否可以将过滤器映射到上下文根目录中的文件而不是“测试”目录中的文件?

4

5 回答 5

18

url-pattern确实在匹配方面有限制。它只允许精确、前缀或后缀匹配。不是中间/整体/正则表达式匹配。因此,例如/*.xhtml,您打算做的事情是行不通的。

如果您只想在/test文件夹中排除 XHTML,那么您最好的方法就是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.
}

基本上从上下文路径返回请求 URI的HttpServletRequest#getServletPath()一部分。

如有必要,您可以将值配置/test<init-param>过滤器的一个,以便您可以从内部web.xml而不是在过滤器的代码中控制值。

于 2010-08-12T16:15:22.687 回答
4

解决方案,基本上您需要自己的过滤器类并将排除 URL 定义为过滤器的 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<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>
于 2014-01-20T17:03:55.413 回答
0

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

于 2010-08-12T11:14:48.117 回答
0

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

<url-pattern>/index.faces</url-pattern>
于 2017-11-17T17:45:33.370 回答
-1

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

于 2010-08-12T11:14:47.753 回答