I want to display in a <p:growl>
that the session has expired.
I found many methods to handle session expiration like:
But I couldn't push a faces message to <p:growl>
.
To the point, how can I automatically run some (JavaScript) code in client side when the HTTP session has automatically expired in server side?
You can use PrimeFaces idle monitor for this. User is redirected to logout action after timeout to invalidate the session. 2 minutes before a countdown dialog is shown to warn user. After moving the mouse again session is extended.
PrimeFaces idle monitor and dialog is placed in a template you can add to every page which is involved:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:composition>
<h:form prependId="false">
<p:idleMonitor
timeout="#{session.maxInactiveInterval * 1000 - 125000}"
onidle="startIdleMonitor()"
onactive="timeoutDialog.hide()" />
<p:dialog id="timeoutSession"
header="#{msg['session.expire']}"
widgetVar="timeoutDialog"
showEffect="fade" hideEffect="fade"
modal="true"
width="400"
height="110"
closable="false"
draggable="false"
resizable="false"
appendToBody="true"
onHide="stopCount()"
onShow="doTimer()">
<br />
<p>
<span class="ui-icon ui-icon-alert" style="float: left; margin: 8px 8px 0;"/>
<p:panel>
#{msg['logoff.soon.1']}
<span id="dialog-countdown" style="font-weight: bold"></span>
#{msg['logoff.soon.2']}
</p:panel>
</p>
<br />
<p style="font-weight: bold;">#{msg['move.cursor']}</p>
</p:dialog>
<p:remoteCommand name="keepAlive" actionListener="#{auth.keepSessionAlive}" />
</h:form>
<script type="text/javascript">
var TIME = 120; // in seconds
var countTimer = TIME;
var processTimer;
var timer_is_on = 0;
var redirectPage = "#{request.contextPath}/auth/j_verinice_timeout";
var countDownDiv = "dialog-countdown";
var txtCountDown = null;
if (!txtCountDown)
txtCountDown = document.getElementById(countDownDiv);
function startIdleMonitor() {
countTimer = TIME;
txtCountDown.innerHTML = countTimer;
timeoutDialog.show();
}
function timedCount() {
txtCountDown.innerHTML = countTimer;
if (countTimer == 0) {
stopCount();
window.location.href = redirectPage;
return;
}
countTimer = countTimer - 1;
processTimer = setTimeout("timedCount()", 1000);
}
function doTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(processTimer);
timer_is_on = 0;
keepAlive();
}
</script>
</ui:composition>
</html>
To activate timeout handling in multiple pages include the timeout template in your layout template:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xml:lang="de-DE">
<h:head>
...
</h:head>
<body>
<ui:include src="/template/sessionTimeOut.xhtml" />
<ui:include src="/nav.xhtml"/>>
<ui:insert name="content">Default content</ui:insert>
<ui:include src="/footer.xhtml"/>>
</body>
</html>
A specific time out for your web application you can set in your web.xml:
<!--?xml version="1.0" encoding="UTF-8"?-->
<web-app>
...
<session-config>
<!-- Session idle timeout in min. -->
<session-timeout>30</session-timeout>
</session-config>
</web-app>
You can read more about this solution in this blog post: JSF and PrimeFaces: Session Timeout Handling