@WebFilter exclude url-pattern

user2492364 picture user2492364 · Jul 9, 2015 · Viewed 23.1k times · Source

I use a filter to check URL patterns for the logged in user.

But I have many URL patterns I need to filter.

{ "/table/*", "/user/*", "/contact/*", "/run/*", "/conf/*", ..., ..., ...}

It's becoming unmaintainable. It will be simpler just to exclude:

{ "/", "/login", "/logout", "/register" }

How can I achieve this?

@WebFilter(urlPatterns = { "/table/*","/user/*", "/contact/*","/run/*","/conf/*"})
public class SessionTimeoutRedirect implements Filter {

    protected final Logger logger = LoggerFactory.getLogger("SessionFilter");

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (request.getSession().getAttribute("Id") != null) {
            chain.doFilter(req, res);
        } else {
            logger.debug("session is null:"+request.getRequestURL());                    
            response.sendRedirect(request.getContextPath()+"/login");
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

    @Override
    public void destroy() {

    }

}

Answer

BalusC picture BalusC · Jul 9, 2015

The servlet API doesn't support an "exclude" URL pattern.

Your best bet is to just map on /* and compare the HttpServletRequest#getRequestURI() against the set of allowed paths.

@WebFilter("/*")
public class LoginFilter implements Filter {

    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
        Arrays.asList("", "/login", "/logout", "/register")));

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", ""); 

        boolean loggedIn = (session != null && session.getAttribute("Id") != null);
        boolean allowedPath = ALLOWED_PATHS.contains(path);

        if (loggedIn || allowedPath) {
            chain.doFilter(req, res);
        }
        else {
            response.sendRedirect(request.getContextPath() + "/login");
        }
    }

    // ...
}