在JSF Web应用程序中处理“会话已过期”,在JBoss AS 5中运行
这个问题与我的另一个问题“ 如何在Java Web应用程序中过期会话时重定向到登录页面? ”有关。 以下是我正在尝试做的事情:
- 我在JBoss AS 5上运行了一个JSF Web应用程序
- 当用户处于非活动状态时,例如15分钟,我需要注销用户并将其重定向到登录页面,如果他在会话过期后尝试使用该应用程序。
- 因此,正如’ JSF Logout and Redirect ‘中所建议的那样,我已经实现了一个filter,用于检查会话过期情况,并在会话过期时将用户重定向到session-timed-out.jsp页面。
- 我已经在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(); } }
如果有会话但没有人登录,则会转到重定向页面。