2011-11-15 127 views
6

我有一个登录页面,我有一个用户bean来验证用户的用户名和密码。这个Bean是会话作用域。 如果有人写URL并尝试跳转登录页面,我该如何检查并将其重定向到登录页面?检查会话是否存在JSF

另一方面。假设我已经登录,我正在工作,突然间我出去了一段时间,我的会议到期。当我返回并尝试与表单进行交互时,它会发送一条消息,提醒我会话到期。如何在发生这种情况时再次将其重定向到登录表单?

在此先感谢。希望我解释一下自己。

钻嘴鱼科2.1.4,Tomcat的7,战斧1.1.11

回答

14

如果有人写了一个网址,并试图跳登录页面,我怎么能检查和重定向他到登录页面?

您似乎使用本土认证。在这种情况下,您需要实施servlet filter。 JSF存储会话范围内管理豆作为HttpSession属性,所以你可以只检查在doFilter()方法:

HttpServletRequest req = (HttpServletRequest) request; 
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager"); 

if (userManager != null && userManager.isLoggedIn()) { 
    chain.doFilter(request, response); 
} else { 
    HttpServletResponse res = (HttpServletResponse) response; 
    res.sendRedirect(req.getContextPath() + "/login.xhtml"); 
} 

地图这个过滤器上的URL模式覆盖保护的页面,例如/app/*


当我返回并尝试以发送一条消息,提示我的会话到期的方式进行交互。如何在发生这种情况时再次重定向到登录表单?

我知道这涉及到Ajax请求吗?对于正常的请求,您可以在web.xml中使用<error-page>。如果设置在web.xml国家节能法的客户端如下

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
</context-param> 

是不是一种选择,那么你需要实现自定义ExceptionHandler

public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper { 

    private ExceptionHandler wrapped; 

    public ViewExpiredExceptionHandler(ExceptionHandler wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public void handle() throws FacesException { 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 

     for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) { 
      Throwable exception = iter.next().getContext().getException(); 

      if (exception instanceof ViewExpiredException) { 
       facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired"); 
       facesContext.renderResponse(); 
       iter.remove(); 
      } 
     } 

     getWrapped().handle(); 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return wrapped; 
    } 

} 

(注意,这个特殊的例子导航到viewexpired ,所以它期望有一个/viewexpired.xhtml作为错误页面)

以上需要烘烤的以下ExceptionHandlerFactory implementsat离子:

public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory { 

    private ExceptionHandlerFactory parent; 

    public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) { 
     this.parent = parent; 
    } 

    @Override 
    public ExceptionHandler getExceptionHandler() { 
     return new ViewExpiredExceptionHandler(parent.getExceptionHandler()); 
    } 

} 

而这又需要faces-config.xml登记如下:

<factory> 
    <exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory> 
</factory> 
+0

我对此有点怀疑。我被要求添加一个名为“转到主页面”的commandLink,但是当我点击它时,它首先进入ViewExpired页面,然后我必须再次点击进入主页面。如何在没有单击commandLink的情况下直接进入主页面? – BRabbit27

+1

使之成为一个普通的'',而不需要查看状态就发送一个新的GET请求。你不需要通过POST提交任何数据,对吧? – BalusC

+0

解决了这个问题,但又出现了另一个问题。如果我留在登录页面中,ViewExpiredException也会发生。如何避免这种情况? – BRabbit27

1

如果要实现自己的系统,你可以将属性添加到用户名为会话或什么的。此属性可以是布尔值所以无论何时会话开始,您都可以将此属性设置为true。写所谓许可的方法。例如:你想有,你可以在一开始添加以下代码限制

public void permission() throws IOException { 

     if(userStatelessBean.getSession() == false) { 
      System.out.println("*** The user has no permission to visit this page. *** "); 
      ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); 
      context.redirect("login.xhtml"); 
     } else { 
      System.out.println("*** The session is still active. User is logged in. *** "); 
     } 
    } 

在每个JSF页面中的(这个例子)您页:

<f:metadata> 
    <f:event type="preRenderView" listener="#{sesija.permission()}"/> 
</f:metadata> 

这是什么要做的是渲染页面之前,对象名称sesija调用JSF ManagedBean并检查您在指定的方法创建的rulles是否满意或不满意。

我希望你觉得这有用,

谢谢。

+0

U.V.因为这帮助我管理权限,但这不能回答真正的问题(管理过期视图) –