3

I am having issues with the Omnifaces FullAjaxExceptionHandler (http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler). It does not redirect to the specified error page after the session is invalidated.

I have the following in my faces-config:

<factory>
    <exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>

And the following in my web.xml:

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

After I invalidate the session, from a user's perspective nothing seems to happen. The application is just 'dead'. In my console I see the following Ajax request:

  • A POST to the original facelet page with a response code of 302
  • a GET to the login page with a code 200 (but nothing happens because it's requested via Ajax)

I am running MyFaces 2.1.10, Primefaces 3.5, Primefaces Extension 0.6.3 & Omnifaces 1.4.1 on WebLogic 12c

Could anyone help me in the right direction? How do I get the FullAjaxExeptionHandler to work properly?

Thanks

Waterstraal
  • 399
  • 4
  • 16

1 Answers1

3

A POST to the original facelet page with a response code of 302

This is not right. A redirect on a JSF ajax request must have a response code of 200 with a special XML response with a <redirect> element with target URL in its url attribute.

This thus indicates that you manually used HttpServletResponse#sendRedirect() somewhere long before JSF has the chance to deal with ViewExpiredException.

Perhaps you've somewhere a servlet filter which checks some session attribute and sends a redirect based on its presence/state? That filter should then be manipulated based on the following answer: JSF Filter not redirecting After Initial Redirect in order to recognize JSF ajax requests and return a special XML response instead of a 302 response.

E.g.

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
    response.setContentType("text/xml");
    response.getWriter()
        .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
        .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
    response.sendRedirect(loginURL);
}

This all is completely unrelated to the FullAjaxExceptionHandler. JSF didn't have any chance to throw a ViewExpiredException because you're already sending a redirect yourself beforehand.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for your answer. I am certain that I am not sending a redirect manually... Could this be a weblogic specific issue? And would it be possible to write my own filter with your implementation code to fix this? – Waterstraal Apr 16 '13 at 13:17
  • Yes, that would very well happen if you're using container managed authentication. I'm however not that familiar enough with Weblogic in order to propose the right solution; OmniFaces has a builtin solution in `OmniPartialViewContext` which should cover this specific case, however that only works when a forward is performed (as done by Tomcat, JBoss and Glassfish) instead of a redirect. As first step, explore all request attributes to see if WebLogic hasn't set some specific request attribute indicating that the container managed authentication has kicked in. – BalusC Apr 16 '13 at 13:22
  • See also this related question: http://stackoverflow.com/questions/12504131/viewexpiredexception-not-thrown-on-ajax-request-if-jsf-page-is-protected-by-j-se/ – BalusC Apr 16 '13 at 13:23
  • Yes we are using Container Managed Authentication. Does this mean I could not use the FullAjaxExceptionHandler? Would you be able to point me in a direction to get this to work without the use of your FullAjaxExceptionHandler? Thank you in advance! – Waterstraal Apr 16 '13 at 13:40
  • You need to understand that your particular problem is completely unrelated to `FullAjaxExceptionHandler`. It didn't even had the chance to run, because the container has redirected the restricted request to a login page upon session expiration. It would only work the way *you* expected if the request wasn't blocked by container managed authentication because the user was logged out due to session expiration. – BalusC Apr 16 '13 at 14:00
  • So the only way is not to use container managed authentication? – Waterstraal Apr 16 '13 at 14:05
  • Depends on the concrete functional requirement. From the other way round, it can also just be that you're just looking in the wrong direction for the solution to the concrete problem. The `FullAjaxExceptionHandler` only intercepts on exceptions thrown during JSF ajax requests. In your particular case, there's no means of any exception. WebLogic has redirected the request to the login page because the user is not logged-in anymore. Even if you used normal request instead of ajax request, you would still not have gotten a `ViewExpiredException` and thus never hit the `` at all. – BalusC Apr 16 '13 at 14:28
  • I found a solution - the problem was in FullAjaxExceptionHandler I replaced the "renderErrorPageView" Method with ` String viewId = getViewIdAndPrepareParamsIfNecessary(context, errorPageLocation); ViewHandler viewHandler = context.getApplication().getViewHandler(); String actionURL = viewHandler.getRedirectURL(context, viewId, null, false); context.getExternalContext().redirect(actionURL);` – DCO Jul 30 '14 at 15:06
  • 1
    @Dan: You're sending a HTTP redirect instead of rendering the view. This is not conform standard servlet spec and does not work for error pages in `/WEB-INF`. – BalusC Jul 30 '14 at 15:11