编程语言
首页 > 编程语言> > Java过滤器无限循环

Java过滤器无限循环

作者:互联网

这个问题已经在这里有了答案:            >            Servlet filter runs in infinite redirect loop when user is not logged in                                    1个
我想实现一个过滤器来执行身份验证,但是不知何故它陷入了无限循环中……任何想法都值得赞赏.

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    doBeforeProcessing(request, response);

    Throwable problem = null;
    HttpSession session = httpRequest.getSession(true);
    if(session.getAttribute("userName")!=null&&session.getAttribute("userName")!=(""))
    {
        try {
            chain.doFilter(request, response);
        } catch (Throwable t) {
            // If an exception is thrown somewhere down the filter chain,
            // we still want to execute our after processing, and then
            // rethrow the problem after that.
            problem = t;
            t.printStackTrace();
        }   
    }else{
        httpResponse.sendRedirect("login.jsp");
        return;
    }

调试模式下的这段代码只会无限次运行,基本上,我想在用户未登录时将其重定向到login.jsp.
任何答案表示赞赏.

解决方法:

这里,

httpResponse.sendRedirect("login.jsp");

您是向目标页面发送新的HTTP请求,而不是使用当前请求.如果将新的HTTP请求映射到过于通用的URL模式(例如/ *),则该请求当然会再次击中过滤器.并且将执行相同的检查,并将其再次重定向.等等.这是一个永无止境的故事.

当当前请求的页面是登录页面时,您还需要添加额外的检查来执行FilterChain#doFilter().

String loginURL = httpRequest.getContextPath() + "/login.jsp";

if (httpRequest.getRequestURI().equals(loginURL)) || session.getAttribute("userName") != null) {
    chain.doFilter(request, response);
} else {
    httpResponse.sendRedirect(loginURL);
}

请注意,我还删除了对作为用户名的空字符串的无意义的检查(但是,您要确保您的代码无处将空字符串作为用户名.仅使用null表示未登录的用户.还要注意,我已修复以及重定向URL,因为当当前请求的URL位于子文件夹中时,重定向URL将会失败.

另一种替代方法是将所有这些受限制的页面放在一个公共子文件夹中,例如/ app,/ secured,/ restricted等,然后将过滤器映射到/ app / *,/ secured / *,/ restricted / *等.如果将登录页面保留在此文件夹之外,则在请求登录页面时将不会调用过滤器.

标签:java,authentication,servlets,infinite-loop,servlet-filters
来源: https://codeday.me/bug/20191011/1893823.html