How to solve ViewExpiredException: View could not be restored

The javax.faces.application.ViewExpiredException is a common exception in JavaServer Faces (JSF) applications that occurs when the user’s view state, which is used to maintain the state of components across requests, becomes invalid or expired. This typically happens when a user submits a form or performs an action on a JSF page after the view state has expired on the server.

how to solve javax.faces.application.ViewExpiredException

Root cause of the Issue

What is a View State: In JSF, the view state is a piece of data that’s associated with each user session and is used to keep track of the state of the components and values on a specific page. It’s a critical part of JSF’s mechanism for ensuring that the user’s interactions with the page are maintained across requests.

Why the Exception Occurs: The ViewExpiredException occurs when the server receives a request from the user, but the associated view state for that request is either missing or has expired on the server. This usually happens when a user interacts with a page after a certain period of inactivity, causing the view state to expire on the server.

Possible Causes:

  • Session Timeout: If a user’s session expires due to inactivity, the view state associated with that session will also expire. Any subsequent requests from the user will result in a ViewExpiredException.
  • Back or Refresh: If a user navigates back or refreshes a page after a view state has expired, the server might not have the necessary view state to process the request, leading to the exception.
  • Bookmarking: If a user bookmarks a page and tries to access it later, the view state might have expired by the time the user tries to access it.

How to handle the ViewExpiredException

To handle the ViewExpiredException, you can implement error handling mechanisms in your JSF application. This might involve redirecting users to a friendly error page, displaying a message, or possibly allowing them to navigate back to a non-expired page.

For example:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/WEB-INF/errorpages/expired.xhtml</location>
</error-page>

In the above snippet from web.xml, replace javax with jakarta if you are running Jakarta EE 9/10 or newer applications.

Then, within your expired.xhtml page you can handle the exception allowing the user to redirect to the login page to force a page refresh:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Session expired</title>
        <meta http-equiv="refresh" content="0;url=#{request.contextPath}/login.xhtml" />
    </head>
    <body>
        <h1>Session expired</h1>
        <h3>You will be redirected to login page</h3>
        <p><a href="#{request.contextPath}/login.xhtml">Click here if redirect didn't work or when you're impatient</a>.</p>
    </body>
</html>

How to enableRestoreView11Compatibility

In a JavaServer Faces (JSF) application, developers use the com.sun.faces.enableRestoreView11Compatibility attribute to actively control the compatibility mode for restoring the JSF view within the context of the JSF lifecycle. This attribute specifically pertains to the Mojarra JSF implementation (developed by Oracle) and proactively addresses specific behavior changes introduced in JSF 2.2.

By setting this attribute to true, you can enable compatibility with the older view state restoration process.

<context-param>
   <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
   <param-value>true</param-value>
</context-param>

By setting the above attribute will prevent JSF from throwing the exception when the view is expired and simply continue the request. On the other hand, JSF still won’t be able to restore the view state nor find any associated view scoped beans.

Your application code should be able to restore the view state by resubmitting the POST request parameters to avoid to propagate errors on the back-end.

Finally, note that if using the OmniFaces <o:enableRestorableView> you can apply this setting at view level instead of an application wide context parameter.

Conclusion

In conclusion, understanding and effectively addressing the javax.faces.application.ViewExpiredException is vital for maintaining a seamless user experience within your JavaServer Faces (JSF) applications. By grasping the root causes of this error and implementing appropriate strategies, you can ensure that users encounter fewer disruptions due to expired view states. F

Found the article helpful? if so please follow us on Socials