JSF Session Timeout Handling

Here's my solution for session handling. When your session timed out, you will be redirected to the index page which is commonly the login page to login again.

package com.mypackage.web.session;

import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpSession;

public class SessionPhaseListener implements PhaseListener {

private static final String homepage = "index.jsp";

@Override
public void afterPhase(PhaseEvent event) {
//Do anything
}

@Override
public void beforePhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
ExternalContext ext = context.getExternalContext();
HttpSession session = (HttpSession) ext.getSession(false);
boolean newSession = (session == null) || (session.isNew());
boolean postback = !ext.getRequestParameterMap().isEmpty();
boolean timedout = postback && newSession;
if (timedout) {
Application app = context.getApplication();
ViewHandler viewHandler = app.getViewHandler();
UIViewRoot view = viewHandler.createView(context, "/" + homepage);
context.setViewRoot(view);
context.renderResponse();
try {
viewHandler.renderView(context, view);
context.responseComplete();
} catch (Throwable t) {
throw new FacesException("Session timed out", t);
}
}
}

@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}

Once you created the class above that implements the PhaseListener, add this to you faces-config.xml. Note that the package name depends on your own Java packaging.
<lifecycle>
<phase-listener>com.mypackage.web.session.SessionPhaseListener</phase-listener>
</lifecycle>

16 comments:

  1. Thanks a lot man, you are the first one who really helped me in this annoying ViewState

    ReplyDelete
  2. Thanks a lot! this really did help me!

    ReplyDelete
  3. This helped me a lot... thank you for sharing this globally!

    ReplyDelete
  4. This is what i am looking for a long time. Thanks for such a great help. Now it is working fine.

    ReplyDelete
  5. This solutions is not working for me If tomcat security-constraint is setup

    ReplyDelete
  6. good code..problem here is the first request which is new is going to the time out page.

    And another problem is the the request parameter map which is true for both the cases. how can't affect session timeout??

    ReplyDelete
  7. want discription for the code please

    ReplyDelete
  8. Thanks man!!!!! you are amazing.....this help me alot.

    System.out.println("Thank You");

    ReplyDelete
  9. Nice, thanks a lot.

    ReplyDelete
  10. I have added this code into my application, however when I load the application it doesn't recognize it as a new session. Do you have any idea why it wouldn't recognize it as a new session? After it times out, it's the same thing, so it doesn't recognize that it's timed out. Any ideas? Thanks!

    ReplyDelete
    Replies
    1. this works fine in glassfish, whats your server?

      Delete
  11. Good blog which has provided me a good knowledge for session

    ReplyDelete
  12. viewHandler.renderView(context, view) throws the following error:

    java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
    at com.sun.faces.application.view.JspViewHandlingStrategy.executePageToBuildView(JspViewHandlingStrategy.java:345)
    at com.sun.faces.application.view.JspViewHandlingStrategy.buildView(JspViewHandlingStrategy.java:154)
    at com.sun.faces.application.view.JspViewHandlingStrategy.renderView(JspViewHandlingStrategy.java:194)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
    at cra.sec.SessionPhaseListener.beforePhase(SessionPhaseListener.java:41)
    at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)


    ReplyDelete
  13. Hi its not working for me,mine is tomcat server and jsf2,primefaces5

    ReplyDelete