出于日志记录的目的,我感兴趣的是检测我的JSF应用程序中何时发生会话超时。
我已经实现了一个PhaseListener,用于检查用户是否已登录并且其会话已处于活动状态。我对 afterPhase 方法的实现是:
var url_accepted (在代码中使用)包含用户应有权访问的公共页面列表,以便提供登录表单。
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
AuthenticationBean sessionBean = (AuthenticationBean) session.getAttribute("sessionBean");
String url_req = context.getViewRoot().getViewId();
//1. Check if user has a session and is logged in:
if(((sessionBean == null) || (sessionBean != null && !sessionBean.isLoggedIn())) && !url_accepted.contains(url_req)){
context.getApplication().getNavigationHandler().handleNavigation(context,null,"auth_error");
return;
}
//2. Code continues in order to check if a logged user has permissions to access the requested page(not relevant):
}
当用户因会话超时而断开连接时,PhaseListener无法从 ExternalContext 检索我的sessionBean,并将 null 分配给sessionBean属性。此时,我无法区分用户之前是否已登录或已被超时断开连接。
我已经读过,可以使用errorPages来检测 ViewExpiredException 异常并将视图重定向到特定页面。但我不知道是否可以在源代码中管理此异常。
我的问题是:我可以在PhaseListener实现中捕获此 ViewExpiredException 以处理会话超时吗?
提前致谢。
答案 0 :(得分:1)
我在JSF项目中面临同样的情况。解决方案是使用Filter来捕获会话过期。 BalusC(JSF专家)解释了这个问题,并展示了一个很好的例子:
另外,不要忘记在注销方法和会话超时处理程序中添加session.invalidate()
。