How to Handle ViewExpiredException in JSF

Here's the solution on how to handle the ViewExpiredException in JSF. This occurs when your session timed out or you tried to invalidate the session when you logged out. I've used this code to my 2 previous projects and it really worked fine.

First, you just need to add Spring 2.5 to your project libraries. Download Spring 2.5 here and just copy the code below.

import javax.faces.application.ViewExpiredException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.StringUtils;

public class SessionTimeoutFilter implements Filter {

private String homePage = "index.jsp";

@Override
public void init(FilterConfig filter) throws ServletException {
//Filter initialized
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException {
if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (isSessionCheckingNeeded(httpServletRequest)) {
if ((isInvalidSession(httpServletRequest))) {
String timeoutUrl = httpServletRequest.getContextPath() + "/faces/" + getHomePage();
httpServletResponse.sendRedirect(timeoutUrl);
return;
}
}
}

try {
chain.doFilter(request, response);
} catch (ViewExpiredException ve) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;

String timeoutUrl = httpServletRequest.getContextPath() + "/faces/" + getHomePage();
httpServletResponse.sendRedirect(timeoutUrl);

} catch (Exception e) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;

String timeoutUrl = httpServletRequest.getContextPath() + "/faces/" + getHomePage();

if (StringUtils.countOccurrencesOf(e.getMessage(), "could not be restored.") > 0) {
httpServletResponse.sendRedirect(timeoutUrl);
return;
}

httpServletResponse.sendRedirect(timeoutUrl);
return;
}
}

private boolean isInvalidSession(HttpServletRequest httpServletRequest) {

boolean sessionInValid = (httpServletRequest.getRequestedSessionId() != null)
&& !httpServletRequest.isRequestedSessionIdValid();
return sessionInValid;
}

private boolean isSessionCheckingNeeded(HttpServletRequest request) {

int counter = StringUtils.countOccurrencesOf(request.getRequestURL().toString(), getHomePage())
+ StringUtils.countOccurrencesOf(request.getRequestURL().toString(), getHomePage());

if (counter > 0) {
return false;
}
return true;
}

@Override
public void destroy() {
//Session destroyed
}

public String getHomePage() {
return homePage;
}

public void setHomePage(String homePage) {
this.homePage = homePage;
}
}

10 comments:

  1. I do the same thing but the ViewExpiredExcpetion is not be catched !!!

    ReplyDelete
  2. ViewExpiredException is encapsulaset as the cause in a ServletException

    ReplyDelete
  3. change the catch block to

    catch (ServletException e) {
    Throwable rootCause = e.getRootCause();
    // Handle only ViewExpiredException
    if (rootCause instanceof ViewExpiredException) {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    String timeoutUrl = httpServletRequest.getContextPath() + "/faces/" + getHomePage();
    httpServletResponse.sendRedirect(timeoutUrl);
    } else {
    throw e;
    }
    }

    ReplyDelete
  4. This is indeed a good solution... when using Firefox, Safari, Crome etc BUT Internet Explorer.
    This is so frustrating.
    When I found your post I was so thrilled that I will finally solve this ViewExpiredException, but unfortunately IE doesn't allow redirect and as rezult I get:

    Webpage error details

    Message: Permission denied
    Line: 28
    Char: 222
    Code: 0
    URI: http://localhost:8080/napa-office/a4j.res/org.ajax4jsf.framework.ajax.AjaxScript

    Did anyone encountered this issue?

    Roxana

    ReplyDelete
  5. Doesn't work because the response is already committed; Redirect results in IllegalStateException. At least for JSF [1.1.9].

    ReplyDelete
  6. is it works on ajax...??

    ReplyDelete
  7. Hello,

    in my case i ma invalidating the the session,
    session.invalidate();
    chain.doFilter(request, response);

    in this after this its not throwing any excpetion at all? and also its not redirecting to view Expired page, i am not able to find the solution, Please let us know how to redirect once the session is get invalidated from the filter.

    ReplyDelete
  8. I stil have the same problem.

    As session.invalidate() method called or if session timeout happens, then I am getting the ViewExpiredException.

    the exception occurs in xhtml page & hence not caught in Servlet

    ReplyDelete

  9. javax.faces.application.ViewExpiredException
    /HomePage.xhtml


    Paste this in ur web.xml page

    ReplyDelete
  10. if you get the solution of above then post it i am facing exact problem

    ReplyDelete