I don't redirect or forward my user to another page. So when the my SessionExpiredExceptionHandler
(extends ExceptionHandlerWrapper
) handles the ViewExireException. I want the user to stay on the same page and display a PrimeFaces Dialog. For notifying that the session has expired and that the user needs to login again (dialog based). I am use Servlet 3.1 functions to login/logout user and Basic/file
for auth-method to map the users to different system roles.
What is happening now is that the View/page get refreshed after 2 min, but the session doesn't get invalidated. That only happens the second time when the page refreshes, after 4 min.
<session-config>
<session-timeout>2</session-timeout>
</session-config>
Edit: Which is refreshed by the meta tag:
<meta http-equiv="refresh" content="#{session.maxInactiveInterval}" />
How can I make SessionExpiredExceptionHandler
invalidate the session object (Servlet logout) when the Exceptions occur the first time, and how can I invoke a JavaScript (expireDlg.show()) on the client to display a PrimeFaces dialog ?
I have looked at some other threads but not found a viable solution. Session time-out
SessionExpiredExceptionHandler
@Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
if (t instanceof ViewExpiredException) {
ViewExpiredException vee = (ViewExpiredException) t;
FacesContext fc = FacesContext.getCurrentInstance();
Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
NavigationHandler nav = fc.getApplication().getNavigationHandler();
try {
requestMap.put("currentViewId", vee.getViewId());
nav.handleNavigation(fc, null, "Home");
fc.renderResponse();
} finally {
i.remove();
}
}
}
// At this point, the queue will not contain any ViewExpiredEvents.
// Therefore, let the parent handle them.
getWrapped().handle();
}
web.xml
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/home.xhtml</location>
</error-page>
This solution worked for my case. It seams that Primefaces (3.3) is swallowing the ExceptionQueuedEvent. There are no Exception to handle when my ViewExceptionHandler gets called. So instead I used the
p:idleMonitor
component with event listner. I also removed the meta refresh tag.One weird thing is if the
timeout
is excatly the same as theweb.xml
session time-out parameter, the listener won't be invoked.Bean functions
The dialog (
sessionExipreDlg
) called the redirect instead of using navigation handler to get new scope and refresh the page.The session is supposedly to be already invalidated/expired (otherwise a
ViewExpiredException
wouldn't be thrown at all), so I don't see how it's useful to manually invalidate/expire it yourself. But for the case that, you can invalidate it as follows:You can use the PrimeFaces
RequestContext
API to programmatically instruct PrimeFaces to execute some JS code on complete of ajax response.Don't forget to remove the navigation handler block from the exception handler if you actually don't want to navigate.