Question

I've already searched via google and on stackoverflow, but could not find any similar problem to mine.

In my project I'm handling a ViewExpiredException properly and show a custom page to the user that the current session has timed out. This works great, but I want to do something BEFORE this message gets shown to the user. Actually I'm working with 2 different sessions here, one on the frontend side and one on the backend, so the idea is to NOT start a new backend session when the current one timed out. Is there any possibility to fetch the ViewExpiredException while I'm inside the doFilter method, so I do not start a new backend session (simply because it is not needed)? Or is there any other way?

I already tried to fetch the current context via

FacesContext fc = FacesContext.getCurrentInstance();

But obviously the context is null, because the session timed out. Inside the ExceptionHandlerWrapper I have access to the UnhandledExceptionQueuedEvents, but this does not help me here since I need this information earlier.

I hope I made my problem clear enough.

Thanks in advance for any help!

Regards Sebastian

Was it helpful?

Solution

Generally ViewExpiredException is thrown when a POST request is fired while the session is timed out. So, this should do in the filter:

boolean post = "POST".equals(request.getMethod());
boolean timedout = request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid();

if (post && timedout) {
    // JSF will guaranteed throw ViewExpiredException when state saving is set to server.
}

But this does not cover all possible cases. ViewExpiredException can also occur when the session hasn't timed out. For example, when the client has passed an invalid javax.faces.ViewState parameter, or when the associated view has been pruned from the LRU map which can by default hold 15 views. This is however not detectable inside a servlet filter before FilterChain#doFilter() is called. You really need to be inside the JSF context. You could do the backend session creating job in a PhaseListener. E.g. in beforephase of apply request values phase, which is guaranteed to be invoked only when there's a vaild view.

By the way, the FacesContext is not null in the filter because the session has timed out, but because the FacesServlet, the one responsible for creating it, hasn't been invoked yet at that point. You know, filters run before servlets.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top