I’ve put the following into my web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/expiredIndex.jsf</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsf</location>
</error-page>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
When I start my app, and wait for 1 minute, if I then attempt to interact with it (JSF 1.2, h:commandButton) I get the error
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
javax.faces.application.ViewExpiredException: viewId:/index.jsf - View /index.jsf could not be restored.
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:185)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:103)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
Can someone tell me why it is the javax.faces.application.ViewExpiredException is not being picked up? I’m looking for the most basic expiry setup possible and surely that’s all that is necessary in the web descriptor.
Thanks
EDIT
I now have in my web.xml the following:
<filter>
<filter-name>Error</filter-name>
<filter-class>myClient.ErrorFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Error</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<exception-type>javax.servlet.ViewExpiredException</exception-type>
<location>/expiredIndex.jsf</location>
</error-page>
(these entries are the last filter entries in the web.xml) and a new filter with the doFilter method as described in this post. What should be happening now is the rootCause should unwrap the ViewExpiredException which should thus redirect the user to my expiredIndex page when the servlet session times out. Instead I get a 500. I can’t see what else to I need to do the correct redirect in this situation. Help!
EDIT 2
Error from the 500 is:
javax.faces.application.ViewExpiredException: viewId:/index.jsf - View /index.jsf could not be restored.
com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:185)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:103)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
prismClient.ErrorFilter.doFilter(Unknown Source)
which I guess is the standard one.
This is because the
ViewExpiredException-as every otherFacesException– is under the covers been wrapped in aServletException. This one is been used to find matches in the declared error pages. The closest match isjava.lang.Throwableand thus the associated error page is been shown.If no match would have been found, then the root cause of the
ServletExceptionwould have been unwrapped and a second pass through the declared error pages will be made with the unwrapped exception. If you remove thejava.lang.Throwableentry, you’ll see that this will work.If you want to keep the
java.lang.Throwable, then best what you can do is to create aFilterwhich unwraps anyFacesExceptionfrom theServletExceptionand rethrows it.See also:
ViewExpiredExceptionand multiple error page definitions