Filter mapping url-pattern that excludes subdirectories
Asked Answered
B

5

7

Is there any way to make a filtermapping not include subdirectories?

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?

Bearce answered 12/8, 2010 at 11:0 Comment(0)
E
18

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.

Expurgate answered 12/8, 2010 at 16:15 Comment(1)
I first thought hard coded in Filter? but the init-param is smart. Have learnt something here.Phenacite
F
4

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>
Fa answered 20/1, 2014 at 17:3 Comment(1)
Sorry, this is my first post, it took me about 30 minutes to correct format. The solution, basically you need your own Filter class and define excluding URLs as init-param for filter.Fa
H
0

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.

Hove answered 12/8, 2010 at 11:14 Comment(2)
But a filter with mapping /* would still include everything under /test would it not?Bearce
That's correct. I was thinking that the first one matched is the one used, but that's not the case. Instead, you could add a url regex check in your filter - if it matches the regex, then the filter performs it's work before delegating to the remaning filter chain. If the regex doesn't match it just delegates to the filter chain without doing any work.Hove
P
0

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>
Perennate answered 17/11, 2017 at 17:45 Comment(0)
F
-1

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.

Fideism answered 12/8, 2010 at 11:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.