Java过滤器无限循环[重复]

Posted

技术标签:

【中文标题】Java过滤器无限循环[重复]【英文标题】:Java Filter Infinite loop [duplicate] 【发布时间】:2012-10-18 08:39:57 【问题描述】:

我想实现一个过滤器来进行身份验证,但不知何故它陷入了无限循环......任何想法都值得赞赏。

    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。 任何答案表示赞赏。

【问题讨论】:

这个过滤器是否也在login.jsp页面上运行? 是的,很遗憾。无论如何,我想出了一个解决方案:“if (uri.indexOf("login.jsp")>-1) chain.doFilter(request, response); // 继续 chain.return; " 或者有没有更优雅的方法可以将 login.jsp 从过滤中排除?我认为 web.xml 中有一些内容,但据我所知,它不支持此 标签或类似此功能的东西:( 那么这绝对是你的循环的原因,你已经找到了问题的解决方案......不幸的是,过滤器 url-mapping 没有排除语法 【参考方案1】:

这里,

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

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

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

【讨论】:

【参考方案2】:

问题是您的过滤器在login.jsp 上运行,并且当用户未登录时会反复重定向到自己。因为过滤器url-pattern 上没有排除语法,所以如果您已经在login.jsp 页面上,您需要检测过滤器中的 URL 并忽略重定向:

    // your auth code
 else 
    String redirect = httpRequest.getContextPath() + "/login.jsp";
    String uri = httpRequest.getRequestURI().toString();
    if (uri.endsWith(redirect))
        // URI ends with login.jsp, just process the chain
        chain.doFilter();
     else 
        // not on the login page and not logged in, redirect
        httpResponse.sendRedirect(redirect);
        return;
    

【讨论】:

谢谢你,doublesharp,我对你的解决方案投了赞成票(基本上我们在评论部分谈论的是额外的 getContextPaath() 和 endsWith() 函数)......很难只接受一个,但 BalusC 为我提供了一些新信息。 (正如我所见,它也更快......)再次感谢 doublesharp! 总是投票支持更多信息和更快的执行:)

以上是关于Java过滤器无限循环[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Java - 带有浮点数的无限while循环[重复]

Java TCP Client-Server - 在两个应用程序中陷入无限循环[重复]

使用 setInterval() 的无限异步循环 [重复]

Python - 用于停止无限循环的键盘命令? [重复]

Rails 3:过滤后模型导致无限循环

Bash参数解析逻辑陷入无限循环[重复]