I have a JSF 2 application and configured the following in web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/error.html</location>
</error-page>
For testing purposes I have the following code in a @SessionScoped class within an init Method annotated with @PostConstruct in order to let the session quickly expire:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession) ec.getSession(false);
session.setMaxInactiveInterval(5);
Now, when I have an h:commandButton with outcome = "somepage.jsf" then a click after the 5s will redirect to the error page.
When I instead call some bean action or putting the page name in action on the very same button using the action attribute , I see the ViewExpiredException in the server’s log, but no redirection occurs.
Why is that so? And how to generally redirect to another page no matter which action took place after the session expires?
The behaviour is different because an asynchronous (ajax) request is been sent. Ajax requests require a special XML response. Exceptions on ajax requests needs to be handled by either the
jsf.ajax.addOnErrorhandler in JavaScript or a customExceptionHandler.By default they have namely no single form of helpful feedback in the client side. Only in Mojarra with project stage set to
Developmentyou’ll see a bare JavaScript alert message with the exception message. But that’s it. There is no single form of feedback inProductionstage.With a custom
ExceptionHandleryou would be able to simulate exactly the same form of feedback as in synchronous requests. You could parse theweb.xmlto find the proper error page location, create a newUIViewRootaround it and force JSF to set ajax rendering to@all. Since that’s after all relatively quite some work, the JSF utility library OmniFaces provides exactly such an exception handler out the box in flavor ofFullAjaxExceptionHandler. You can find the showcase page here.