开发者

Filter mapping url-pattern that excludes subdirectories

Is there any way to make a filtermapping not include subdi开发者_如何学编程rectories?

For example.

I have .xhtml files in my context root, and I also have a subfolder named "test" with files with the same extension. Is there any may to map a filter to the files in context root and not to the files in the "test" directory?


The url-pattern is indeed restrictive in matching. It only allows exact, prefix or suffix matchnig. Not midst/overall/regex matching. So e.g. /*.xhtml what you intend to do ain't going to work.

If you want to exclude XHTML in the /test folder only, then your best is really a Filter listening on an url-pattern of *.xhtml which does basically the following job in doFilter() method:

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

The HttpServletRequest#getServletPath() basically returns the part of the request URI from the context path on.

You can if necessary configure the value /test as an <init-param> of the filter so that you can control the value from inside the web.xml instead of in the Filter's code.


The solution, basically you need your own Filter class and define excluding URLs as init-param for filter

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

And define the filter, mapping and exclude URLs in 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>


Using what is available for standard servlets/filters, there is no direct way to exclude the subdirectory, since *.ext style mappings include subdirectories. You could work around this by declaring another filter that specifically handles the /test/*.xhtml mapping and handles that accordingly.


You can add a url-mapping value for every file you have in the context root, therefore the filter will apply to those files but none to the files in the test folder (actually it will only apply to those specific files). The following worked for me

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


Some containers (like resin) define an extension to filter mapping definition in web.xml which allows specifying url-regexp which allows matching the urls based on regular expression. (reference). See if your container has something like this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜