在JSF Web应用程序中处理“会话已过期”,在JBoss AS 5中运行

这个问题与我的另一个问题“ 如何在Java Web应用程序中过期会话时重定向到登录页面? ”有关。 以下是我正在尝试做的事情:

  1. 我在JBoss AS 5上运行了一个JSF Web应用程序
  2. 当用户处于非活动状态时,例如15分钟,我需要注销用户并将其重定向到登录页面,如果他在会话过期后尝试使用该应用程序。
  3. 因此,正如’ JSF Logout and Redirect ‘中所建议的那样,我已经实现了一个filter,用于检查会话过期情况,并在会话过期时将用户重定向到session-timed-out.jsp页面。
  4. 我已经在web.xml中的所有其他filter定义之上添加了SessionExpiryCheckFilter,因此我的会话到期检查将始终获得第一次命中。

现在迎来我所面临挑战 。 由于我使用的是JBoss AS,当会话过期时,JBoss会自动将我重定向到登录页面(请注意,不会调用会话到期检查filter)。 因此,在我登录后,我的SessionExpiryCheckFilter拦截了请求,并且它看到会话可用。 但是,它抛出了exceptionjavax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.

以前有人遇到过这个问题吗? 有什么想法可以解决这个问题?

以下方法适合我。 请注意,您必须使用JSTL核心taglib重定向而不是jsp重定向才能使其正常工作(因为jsp也会过期)。

FacesConfig.xml中,您输入以下内容:

  javax.faces.application.ViewExpiredException /sessionExpired.jsf  

sessionExpired.jsp

 <%@page contentType="text/html" pageEncoding="UTF-8"%>  <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  

您还可以将此方法用于其他错误类型或exception。 例如,元素包含错误代码或exception类型与Web应用程序中资源路径之间的映射:

  400 /400.html  

或元素包含Javaexception类型的完全限定类名。

  javax.servlet.ServletException /servlet/ErrorDisplay  

如果您使用的是Mojarra / Sun RI,可能需要尝试将其添加到web.xml:

  com.sun.faces.enableRestoreView11Compatibility true  

但请注意,这并不总是完美的解决方案。 它隐藏了用户丢失会话的事实。

为Restore视图实现javax.faces.event.PhaseListener

 @Override public void afterPhase(PhaseEvent event) { FacesContext facesContext = event.getFacesContext(); if(facesContext.getViewRoot()==null){ try{ facesContext.getExternalContext().redirect(HOME_PAGE); facesContext.responseComplete(); } catch (IOException e){ e.printStackTrace(); } } } @Override public void beforePhase(PhaseEvent event) {} @Override public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } 

在faces-config.xml中注册

我建议结合filter编写会话监听器。

会话到期时,您可以创建新的会话对象并在新对象上设置超时值。

只需检查filter中的超时值并重定向浏览器即可。

请参阅http://www.java2s.com/Code/Java/Servlets/Servletsessionlistener.htm

我试着为它编写一个filter,但是有些它不适用于我,所以我为它做了一个替代。

我在每个页面都这样做,我不希望用户在没有登录的情况下访问:

   // my code  

这将调用我的会话管理bean中的函数validuser()

现在这是我的function。 在登录期间,我已经将用户对象插入到会话中。

 public void validuser() { FacesContext context = FacesContext.getCurrentInstance(); UserLogin ul = (UserLogin) context.getExternalContext().getSessionMap().get("userbean"); if (ul == null) try{ context.getExternalContext().redirect("/HIBJSF/faces/LoginPage.xhtml"); context.responseComplete(); } catch (IOException e) { e.printStackTrace(); } } 

如果有会话但没有人登录,则会转到重定向页面。