2012-10-29 95 views
2

我想实现一个过滤器来执行身份验证,但不知何故它被卡住在无限循环中......任何想法都会被赞赏。Java Filter无限循环

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

这段代码在调试模式只是在无限的时间运行,basicly我希望将用户重定向到的login.jsp时未登录他。 任何答复赞赏。

+0

这是过滤器也对'login.jsp'运行页? – doublesharp

+0

是的,不幸的。无论如何,我提出了一个解决方案: “如果(uri.indexOf(” login.jsp的“)> - 1){ \t \t \t chain.doFilter(请求,响应); //只要继续链 \t \t \t返回; \t \t}“ – czupe

+0

或者是否有更优雅的方式从过滤中排除login.jsp?我想在web.xml中的一些行,但据我所知它不支持这标记或类似此功能:( – czupe

回答

10

这里,

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

请注意,我还取消了对空字符串作为用户名nonsensicial检查(但是你会确保你的代码无处被设置为空字符串作为用户名。只需使用null表示一个非登录另外请注意,我修复了重定向网址,因为如果当前请求的URL位于子文件夹中,它会失败。

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

4

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

// 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; 
    } 
} 
+0

谢谢你doublesharp,我投票了你的解决方案(和基本上我们在评论部分讨论的额外的getContextPaath()和endsWith()函数)...是很难接受只有一个,但BalusC为我提供了一些新的信息(因为我看到的速度更快......)再次感谢doublesharp! – czupe

+1

总是投票赞成更多的信息和更快的执行:) – doublesharp