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.