我正在尝试通过Primefaces组件idlemonitor处理会话超时。
我这样做是因为我需要让用户知道由于不活动,会话已经过期。我需要通过对话框显示此消息,他关闭对话框后,应将其重定向到登录页面。他应该无法单击“后退”并在应用程序上浏览,就像什么也没有发生一样;如果他单击“后退”,则应将其重定向到sessionexpired.xhtml页面。
我将idleMonitor放入了我的[[loggedintemplate.xhtml,因此,仅当您登录后,无论在哪个页面上登录,我的所有页面都源自< [loggedintemplate.xhtml。
这是我的[[loggedintemplate.xhtml中的代码如下:<p:idleMonitor timeout="6000" onidle="idleDialog.show()" />
<p:dialog header="Timeout" resizable="false" closable="false"
widgetVar="idleDialog" modal="true">
<p:panel styleClass="noborderpanel">
<p:panelGrid columns="1" styleClass="adressegrid">
<p:outputLabel value="Session has expired due to inactivity" />
<p:commandButton action="#{loginController.timeout()}"
value="Ok" />
</p:panelGrid>
</p:panel>
</p:dialog>
因此,此代码的功能基本上是检查用户是否在6秒钟内处于非活动状态,如果他处于非活动状态,则会弹出一个无法关闭的对话框,并告诉他会话已到期。
方法loginController.timeout()应该注销用户,使会话无效等。
我的问题是我不知道如何使会话无效,如何注销用户等。如果我使用FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
,它的确会使会话无效,但我还需要更多。例如,如果用户超过30分钟(默认的JavaEE超时时间)处于非活动状态,则会得到nullPointerException。
我想“手动”处理超时,有没有办法禁用默认JavaEE超时?
手动处理超时的最佳方法是什么,而不是像这样:<session-config>
<session-timeout>20</session-timeout>
</session-config>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/expired.xhtml</location>
</error-page>
6秒后会生成一个对话框(通过javascript警报),并让用户知道他在一段时间内处于非活动状态,并且会话已过期。关闭对话框后,用户将被重定向到登录页面。
顺便说一句,我仅用6秒钟进行测试。我的默认设置是:
idlemonitor: 30分钟
<!-- language: lang-xml -->
<p:idleMonitor timeout="1800000" >
<p:ajax event="idle" listener="#{loginController.timeout()}" oncomplete="alert('Session expired etc.')"/>
</p:idleMonitor>
loginController.timeout()的代码:
public void timeout() throws IOException {
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
FacesContext.getCurrentInstance().getExternalContext()
.redirect("...loginpage.xhtml");
}
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:pu="http://primefaces.org/ultima"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:form>
<p:idleMonitor timeout="#{session.maxInactiveInterval * 1000 - 130000}" onidle="PF('idleDialog').show();PF('timeoutTimer').start();" />
<p:dialog id="timeoutDialog" header="Are you there?" widgetVar="idleDialog" modal="true" closable="false" draggable="false" resizable="false" >
<p:panelGrid columns="1" styleClass="ui-noborder">
<p:panel>
<h:outputText value="You are about to be logged off in " />
<p:spacer width="10"/>
<pe:timer id="timeoutTimer" widgetVar="timeoutTimer" singleRun="true" timeout="120" format="mm:ss" autoStart="false" listener="#{userSessionBean.logout()}"/>
<p:spacer width="10"/>
<h:outputText value=" mins." />
</p:panel>
<p:panel>
<h:outputText value="Please click 'Ok' to keep the session alive" />
</p:panel>
<p:panel style="text-align: center;">
<p:commandButton id="confirm" value="Ok" actionListener="#{userSessionBean.keepAlive()}" onclick="PF('timeoutTimer').stop(true);" oncomplete="PF('idleDialog').hide();" process="@this"/>
<p:spacer width="10"/>
<p:commandButton id="timeoutLogout" value="Log Out" widgetVar="timeoutLogoutWV"
actionListener="#{userSessionBean.logout()}" oncomplete="PF('timeoutTimer').stop(true); PF('idleDialog').hide(); location.reload(true);"/>
</p:panel>
</p:panelGrid>
</p:dialog>
</h:form>
</ui:composition>
以此形式将其插入您的基本模板中
<ui:include src="./sessionTimeOut.xhtml" />
这是Java辅助代码
public void keepAlive() { logger.info("User " + loggedInUser.getUserLogin() + " requested the Session " + getCurrentHttpSessionId() + " to be kept alive at " + new Date().toString()); /** * Do nothing */ } public String logout() throws IOException { FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); FacesContext facesContext = FacesContext.getCurrentInstance(); ExternalContext externalContext = facesContext.getExternalContext(); externalContext.getContextName(); logger.info(FacesContext.getCurrentInstance().getExternalContext().getContextName()); facesContext.getExternalContext().redirect("/Project/views/login.xhtml"); logger.info("Logout"); }
我希望这会有所帮助。谢谢。