Monday, April 28, 2014

How to redirect to custom page whenever session time out in ADF application ?


This blog explains about how to redirect to any custom page whenever session time out in an  ADF application.

This blog demonstrates about redirecting to www.google.com automatically whenever session time out occurs.

You need to understand about Implementing Page Phase Listener prior to implementing this.

Step1 : Create Page Phase Listener as shown below, This gets the value for Session time out interval from the web.xml and prepares dynamic java script call as shown below

       

  package com.atd.tirepro.view.filter;


import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import oracle.adf.controller.v2.lifecycle.Lifecycle;
import oracle.adf.controller.v2.lifecycle.PagePhaseEvent;
import oracle.adf.controller.v2.lifecycle.PagePhaseListener;

import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;


public class TimeOutListener implements PagePhaseListener {
    @SuppressWarnings("compatibility:-1406793285197613021")
    private static final long serialVersionUID = 1L;

    public TimeOutListener() {
        super();
    }

    /**
     * This method determines whether session timed out or not,
     * If session timed out , redirects to corresponding Apps Login page
     * based on configured properties file
     * @param phaseEvent
     */
    public void beforePhase(PagePhaseEvent phaseEvent) {
    }


    public void afterPhase(PagePhaseEvent pagePhaseEvent) {
        if (pagePhaseEvent.getPhaseId() == Lifecycle.PREPARE_RENDER_ID) {
            FacesContext facesCtx = FacesContext.getCurrentInstance();
            ExternalContext extCtx = facesCtx.getExternalContext();
            // Get HttpSession instance
            HttpSession session = (HttpSession)extCtx.getSession(false);
            // Get HttpServletRequest instance
            HttpServletRequest req =
                (HttpServletRequest)extCtx.getRequest();
            if (session != null) {
                int secsTimeout = session.getMaxInactiveInterval();
                if (secsTimeout > 0) {
                    String appURL ="http://www.google.com";
                    secsTimeout += 2;
                    String jsCall =
                        "document.acmeStartClientSessionTimers = function()\n" +
                        "{\n" +
                        "  if(document.acmeSessionTimeoutTimer != null)\n" +
                        "    window.clearTimeout(document.acmeSessionTimeoutTimer);\n" +
                        "\n" +
                        "  document.acmeSessionTimeoutTimer = window.setTimeout(\"document.acmeClientSessionTimeout();\", " +
                        secsTimeout * 1000 + ");\n" +
                        "\n" +
                        "}\n" +
                        "document.acmeStartClientSessionTimers();\n" +
                        "\n" +
                        "document.acmeClientSessionTimeout = function()\n" +
                        "{\n" +
                        "    window.location.href = '" + appURL + "' \n" +
                        "}";

                    ExtendedRenderKitService rks =
                        Service.getRenderKitService(facesCtx,
                                                    ExtendedRenderKitService.class);
                    rks.addScript(facesCtx, jsCall);
                }
            }
        }
    }

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

       
 

Step2 :  Configure above page Phase Listener in adf-settings.xml as shown below
Step3 : Configure session time out interval in web.xml as shown below

 <session-config>
    <session-timeout>2</session-timeout>
  </session-config>

This will automatically redirect to custom URL whenever session expires.

5 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Hello,

    Thanks a lot for your article, I found it very informative.
    I successfully managed to implement it.
    I would still have one question please: we are using the oracle.adf.view.rich.sessionHandling.WARNING_BEFORE_TIMEOUT parameter in web.xml in order to display a warning popup before the timeout occurs.
    This still works with your solution but the application now doesn't notify the user anymore that his session expired (as the page is automatically reloaded just 2 seconds after).

    Would you have any suggestion on how to keep having the "your session has expired" popup?

    Many thanks in advance,
    Jérémie

    ReplyDelete
    Replies
    1. Thank you for visiting my blog, what is the value you set for WARNING_BEFORE_TIMEOUT ? Can you try setting '60'

      Delete
    2. Hi Ravi,

      Thanks a lot for your quick reply.
      For debugging purposes, I am currently using:


      oracle.adf.view.rich.sessionHandling.WARNING_BEFORE_TIMEOUT
      120 //seconds


      5 //minutes


      As per Oracle documentation, WARNING_BEFORE_TIMEOUT will be ignored if lower than 120 (http://docs.oracle.com/cd/E25054_01/web.1111/b31973/ap_config.htm)

      I also noticed that even if the user clicks on OK when the warning popup appears (after 3min), the page will still be redirected after 5min.
      Would not it be possible to directly access the Javascript method which is automatically generated by ADF for the timeout handling?

      Delete
  3. I meant session timeout: 5 mins

    ReplyDelete