MyFaces might throw a ViewExpiredException following a session timeout,
under certain conditions.
The issue arises in some servlet containers (e.g. WebSphere), with Server state-saving, and form-based login.
Here is the scenario:
- User logs in and starts using the MyFaces web application.
- The session expires due to inactivity.
- User clicks e.g. the 'Next' button on the page, triggering a POST.
- The servlet container detects that the session has expired, and redirects the user to the login page (as configured in web.xml).
- User logs in - and is automatically redirected to the page they were previously working on in 3.
- ViewExpiredException is thrown ('No saved view state could be found for view identifier: ...').
Why the ViewExpiredException in 6. ? The request is not a postback -
isn't the user just trying to view the page ?
When the servlet container detects the session expiry in 4., it stores the URL the user was trying to access, and the form's POST data for later use (e.g. in a cookie).
On login, the servlet container uses that data to redirect the user to the page they were trying to access, and to re-POST the form data.
This form data includes a javax.faces.ViewState (indicating that this is a postback) - however the view state referenced is no longer valid.
The solution ? If the servlet container you're using lets you configure
session expiry behaviour, then you can turn off redirecting and re-POSTing
form data after login.
Otherwise you will have to dive under the covers and clear the cookies storing the URL and form data.
On WebSphere, these cookies are WASReqURL and WASPostParam respectively.