Question

I have a problem with the handling of ViewExpiredExceptions within ajax requests. In my special case it is a rich:datascroller which makes problems. I use omnifaces 1.8.1's FullAjaxExceptionHandler to handle VEEs thrown by Ajax components.

web.xml:

<error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/my/pages/error/viewExpired.xhtml</location>
</error-page>

viewExpired.xhtml:

<?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:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html">
    <f:event type="preRenderView" listener="#{viewExpiredHandler.handle}" />
</html>

And the Java Class:

@Named
@RequestScoped
public class ViewExpiredHandler {

    public void handle() {
                String outcome = "/path/to/home.xhtml";
                //Version 1 *************
             try {
                ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
                String redir = ec.getRequestContextPath() + outcome;
                ec.redirect(redir);
            } catch (IOException e) {
                ...
            }
                //Version 2 ************
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        fc.setViewRoot(fc.getApplication().getViewHandler().createView(fc, outcome));
        fc.getPartialViewContext().setRenderAll(true);
        fc.renderResponse();
        }
}

If the session expires and the I click on a datascroller button I see my handle() method gets invoked but the forwarding to the home page doesn't work.

With Version 1 nothing happens at all, with version 2 I first get a blank screen and if I refresh the page with the browser button the handle() method gets invoked again and successfully redirects to the home page

Can you see any error in my code?

Was it helpful?

Solution

The redirect has no effect, because FullAjaxExceptionHandler entirely takes over the rendering and JSF thus can't write the ajax redirect to the response. Changing the view has no effect, because the FullAjaxExceptionHandler has at that moment already the error page view at its hands and won't consult the FacesContext for the changed view. You get a blank screen because your error page is blank by itself.

Just let the browser redirect by itself. Make use of JS window.location. Replace your entire viewExpired.xhtml page with this content:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <script>window.location="#{request.contextPath}/path/to/home.xhtml";</script>
    </body>
</html>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top