1

I have a JSF 2 application and configured the following in web.xml:

<error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/error.html</location>
</error-page>

For testing purposes I have the following code in a @SessionScoped class within an init Method annotated with @PostConstruct in order to let the session quickly expire:

ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession) ec.getSession(false);
session.setMaxInactiveInterval(5);

Now, when I have an h:commandButton with outcome = "somepage.jsf" then a click after the 5s will redirect to the error page.

When I instead call some bean action or putting the page name in action on the very same button using the action attribute , I see the ViewExpiredException in the server's log, but no redirection occurs.

Why is that so? And how to generally redirect to another page no matter which action took place after the session expires?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Alexander Rühl
  • 6,769
  • 9
  • 53
  • 96

1 Answers1

1

The behaviour is different because an asynchronous (ajax) request is been sent. Ajax requests require a special XML response. Exceptions on ajax requests needs to be handled by either the jsf.ajax.addOnError handler in JavaScript or a custom ExceptionHandler.

By default they have namely no single form of helpful feedback in the client side. Only in Mojarra with project stage set to Development you'll see a bare JavaScript alert message with the exception message. But that's it. There is no single form of feedback in Production stage.

With a custom ExceptionHandler you would be able to simulate exactly the same form of feedback as in synchronous requests. You could parse the web.xml to find the proper error page location, create a new UIViewRoot around it and force JSF to set ajax rendering to @all. Since that's after all relatively quite some work, the JSF utility library OmniFaces provides exactly such an exception handler out the box in flavor of FullAjaxExceptionHandler. You can find the showcase page here.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I tried to follow your showcase, but there is still no displaying of the error page. I do see a log message from `FullAjaxExceptionHandler` stating `Error page '/error.html' will be shown.`but it doesn't. My xhtml button looks like that: ` `. What may be missing? – Alexander Rühl Nov 20 '12 at 13:34
  • Maybe I need to add my runtime environment: Tomcat 7.0.32, JDK 1.6.0_37, Kubuntu Linux 12.10 – Alexander Rühl Nov 20 '12 at 13:44
  • It must be a Facelets page, not a plain HTML page. This is not checked, but explicitly mentioned in the javadoc of `FullAjaxExceptionHandler`. – BalusC Nov 20 '12 at 13:45
  • Ok, I missed that point, thank you. I was only thinking that an error page, especially when dealing with RuntimeExceptions should be very basic to avoid again errors in the error.xhtml. – Alexander Rühl Nov 20 '12 at 14:09
  • It can in turn just contain plain HTML though. – BalusC Nov 20 '12 at 14:10
  • I have to get back to my question - I don't know what causes it, but now the situation is as follows: I have configured the `FullAjaxExceptionHandler` and then distinguish between `ViewExpiredException` and error code 500 which each go to a different error page. But now, it only works for an ajax call, but not for an `h:commandButton`. Any idea what may cause this? – Alexander Rühl Dec 21 '12 at 11:58
  • You're not clear as to how exactly it fails, but perhaps you need the [`FacesExceptionFilter`](https://showcase-omnifaces.rhcloud.com/showcase/filters/FacesExceptionFilter.xhtml) as well (whose logic the `FullAjaxExceptionHandler` also is using under the covers). – BalusC Dec 21 '12 at 12:00
  • Hey, you are quick for sure...ok, so when I let the view expire (e.g. deleting JSESSIONID) and then click something which calls a method via `f:ajax`, then my page for view expiration gets displayed, which is configured first in `web.xml`for `ViewExpiredException`. When I do the same but clicking something which calls a method or another page directly via `h:commandButton` then I see the general error page which is configured second in `web.xml`for error code 500. – Alexander Rühl Dec 21 '12 at 12:08
  • Hey BalusC, I was surprised by your quickness of the last comment, but haven't heard something back on my addition - can you tell me more about what I may need to do with the more details? – Alexander Rühl Jan 01 '13 at 20:23
  • Yes, I added the part in the web.xml according to my faces servlet name, but still I don't see the page configured for view expiration. I'm sure there is something wrong in the whole conglomerate, but don't know what. On the other hand it's not the first time I ask myself why often achieving basic expected behaviour from a JSF2 Web application is very hard and requires gurus like you... – Alexander Rühl Jan 01 '13 at 20:59