Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

JSF uses a stateful UI component model. Therefore, it must save the state between requests so that it can process UI events triggered by the user. There are approaches to state saving in JSF, client and server.

State saving refresher

In client-side state saving, the state is serialized and stored in a hidden form field in the web page. Any time the user submits a form on the web page (possibility as a result of an event), the component tree can be restored. This is not the case with server-side state saving.

In server-side state saving, the state is stored in the HTTP session. If the session were to end, all the stored component trees would be discarded. Furthermore, the size of the HTTP session must be careful managed so that it does not consume too many resources. Therefore, JSF implementations typically only allow a fixed number of component trees to be stored in the HTTP session.

If the component tree is no longer available when the user submits a form, a ViewExpiredException is thrown. This exception is essentially saying that the component tree being requested isn't there. Unfortunately, there is no good way to deal with this situation because what is gone is gone.

Workarounds

There are two workarounds to prevent the user from ever getting this exception when using server-side state saving.

Stateless views

If you have a page that contains a form that the user may wait more than a day to submit, then you have a stateless view. In this case, you should make the form a regular HTML form (not <h:form>) and process the form result as though it were a GET request. You can either invoke a page action that processes the input before rendering or you can use Seam's bookmarkable command components (<s:link> or <s:button>) with an action. Page actions are the preferred approach, although make sure your application is not vulnerable to Cross Site Request Forgery.

Redirecting the user

Another approach is to simply redirect the user back to the current page with a message informing them that the session timed out and they have to resubmit the request.

You can setup this redirect using the following exception configuration in pages.xml:

<exception class="javax.faces.application.ViewExpiredException">
   <redirect view-id="#{org.jboss.seam.handledException.viewId}">
      <message severity="warn">Your session has timed out. You were redirected to the current page with a new session.</message>
   </redirect>
</exception>