ViewExpiredException, Page could not be restored

15,341

Solution 1

Solved the problem by following this link on implementing a ExceptionHandlerFactory. A nice solution where you can have an exception navigation rule, but maybe a bit long. Thanks for the help @BalusC.

Solution 2

Your approach should work perfectly fine for synchronous POST requests. However, you're using asynchronous (ajax) POST requests. Exceptions on ajax requests needs to be handled by either the jsf.ajax.addOnError init function in JavaScript or a custom ExceptionHandler.

See also

Share:
15,341
Chris
Author by

Chris

Updated on June 04, 2022

Comments

  • Chris
    Chris almost 2 years

    I've tried to follow different posts on how to handle the ViewExpiredException in Mojarra 2.1.0 (with RichFaces 4) on GlassFish 3.1. But what I define in web.xml doesn't seams to have any effect. I use form base security and the user has to logon to access the content. I just want Glassfish (catalina) to redirect the user to a simple JSF page when the session times-out, with a link back to the login page.

    I always get the the following error message;

    javax.faces.application.ViewExpiredException: viewId:/app_user/activity/List.xhtml - View /app_user/activity/List.xhtml could not be restored.
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:202)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
        at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113)
    

    Who can I redirect the user when the user session has timed-out and trap the exception in the server log ?

    Greetings, Chris.

    layout.xhtml

    <!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:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:rich="http://richfaces.org/rich">
    
        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <!-- Had no effect
            <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
            <meta http-equiv="Pragma" content="no-cache" />
            <meta http-equiv="Expires" content="0" />
            -->      
            <h:outputStylesheet name="css/default.css"/>
            <h:outputStylesheet name="css/cssLayout.css"/>
    
            <title>
                <h:outputText value="Partner Tapestry - " /> <ui:insert name="title">Browser Title</ui:insert>
            </title>
        </h:head>
    
        <h:body>
            <div id="top" >
                <ui:insert name="top">Top Default</ui:insert>
            </div>
    
            <div id="messages">
                <rich:messages id="messagePanel"/>
            </div>
    
            <div id="content">
                <ui:insert name="content">Content Default</ui:insert>
            </div>
        </h:body>
    </html>
    

    web.xml

    ...
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    
    <session-config>
        <session-timeout>
            2
        </session-timeout>
    </session-config>
    <error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/faces/resources/sessionExpired.xhtml</location>
    </error-page>
    ...
    

    login.xhtml

    <ui:composition template="/resources/masterLayout.xhtml"
                    xmlns="http://www.w3.org/1999/xhtml"
                    xmlns:ui="http://java.sun.com/jsf/facelets"
                    xmlns:h="http://java.sun.com/jsf/html"
                    xmlns:a4j="http://richfaces.org/a4j">
    
        <ui:define name="title">
            <h:outputText value="Login"></h:outputText>
        </ui:define>
        <ui:define name="top">
            <h:outputText value="Welcome" />
        </ui:define>
    
        <ui:define name="content">         
            <h:form>
                <h:panelGrid columns="3">
                    <h:outputLabel for="username" value="Username" />
                    <h:inputText id="username" value="#{userController.userAuthentication}" />
                    <br />
                    <h:outputLabel for="password" value="Password" />
                    <h:inputSecret id="password" value="#{userController.passwordAuthentication}" />
                    <br />
                    <h:outputText value=" " />
                    <a4j:commandButton action="#{userController.login()}" value="Login"/>
                </h:panelGrid>
            </h:form>
        </ui:define>
    </ui:composition>
    

    finally sessionExpire.xhtml

    <ui:composition template="/resources/masterLayout.xhtml"
                    xmlns="http://www.w3.org/1999/xhtml"
                    xmlns:ui="http://java.sun.com/jsf/facelets"
                    xmlns:h="http://java.sun.com/jsf/html"
                    xmlns:a4j="http://richfaces.org/a4j">
    
        <ui:define name="title">
            <h:outputText value="Session Exired"></h:outputText>
        </ui:define>
        <ui:define name="top">
            <h:outputText value="Session expired, please login again" />
        </ui:define>
    
        <ui:define name="content"> 
            <h:form>           
                <a4j:commandLink action="/resources/login?faces-redirect=true" value="Login" />
            </h:form>
        </ui:define>
    </ui:composition>