Wednesday, March 27, 2013

Closing Browser When User Clicked On Logout


When user clicked on Logout button/link in JSF page, we can call Javascript to close browser window.

This can be achieved through 2 different ways.
1. We can directly call JavaScript using clientlistener for command button. This method more faster.
2. We can call Java method to execute Javascript using RenderKitService API. This method allows to perform any logic on server side during logout.

Following Sample Code Snippets will help you to do it.


JSF Page Source:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1">
      <af:resource type="javascript">
        function closeWindow(evt) {
            window.close();
        }
      </af:resource>
      <af:form id="f1">
        <af:panelStretchLayout id="psl1">
          <f:facet name="center">
            <!-- id="af_one_column_stretched"   -->
            <af:panelGroupLayout layout="vertical"
                                 xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
                                 id="pgl1">
              <af:outputText value="Hello There! This is a Sample Page to test browser close on clicking Logout button"
                             id="ot1"
                             inlineStyle="font-weight:bolder; font-size:small;"/>
              <af:spacer id="s1" height="30" width="20"/>
              <af:outputText value="Clicking on --Logout1-- Button will call Java bean method to execute Javascript uisng Renderkit"
                             id="ot2" inlineStyle="color:Green;"/>
              <af:commandButton text="Logout1" id="cb1"
                                action="#{pageFlowScope.signOutBean.logOutApp}"
                                partialSubmit="true"/>
              <af:spacer id="s2" height="20" width="20"/>
              <af:outputText value="Clicking on --Logout2-- Button will call Javascript written on page"
                             id="ot3" inlineStyle="color:Maroon;"/>
              <af:commandButton text="Logout2" id="cb2" immediate="true">
                <af:clientListener method="closeWindow" type="action"/>
              </af:commandButton>
            </af:panelGroupLayout>
          </f:facet>
        </af:panelStretchLayout>
      </af:form>
    </af:document>
  </f:view>
</jsp:root>

Managed Bean Source:

import java.io.IOException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;
import weblogic.servlet.security.ServletAuthentication;

public class signOut {
    public signOut() {
        super();
    }

    public String logOutApp() {
        // Add event code here...
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext ectx = facesContext.getExternalContext();
        //String url = ectx.getRequestContextPath() + "/adfAuthentication?logout=true&end_url=/faces/logout.jspx";

        ExtendedRenderKitService service = Service.getRenderKitService(facesContext,ExtendedRenderKitService.class);
        service.addScript(facesContext, "window.close();");  

        HttpSession session = (HttpSession)ectx.getSession(false);
        session.invalidate();
        
        HttpServletRequest request = (HttpServletRequest)ectx.getRequest();
        ServletAuthentication.logout(request);
        ServletAuthentication.invalidateAll(request);
        ServletAuthentication.killCookie(request);

//        try {
//           ectx.redirect(url);
//        } catch (IOException e) {
//           e.printStackTrace();
//        }
//        facesContext.responseComplete();
        return null;
    }

}

5 comments:

  1. Hi,

    That was a interesting scenario. Well we have just the opposite requirement. i.e calling a method(which will logout & clear all the resources held) when the user clicks Windows close button..

    Do u think, its possible in any way?


    -Neha

    ReplyDelete
    Replies
    1. This is a scenario which has got no solution ideally.

      Delete
    2. logoutTarget("/faces/Frm_login");//login page

      public String logoutTarget(String aTarget) {
      ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
      HttpServletResponse response = (HttpServletResponse)ectx.getResponse();
      String url = ectx.getRequestContextPath() + aTarget;
      HttpSession session = (HttpSession)ectx.getSession(false);
      //close session
      session.invalidate();
      try {//@TODO log
      Utils.sysout("usuario cerro sesion");
      response.sendRedirect(url);
      FacesContext.getCurrentInstance().responseComplete();
      } catch (IOException e) {
      e.printStackTrace();
      }
      return null;
      }

      Delete
  2. Hi I am using both Logics but i am not able to close on fire fox
    and once i am login into my application i am not able to close on chrome Browser , but chrome will working before login into the application

    Please let me suggest on this thanks in advance

    ReplyDelete
  3. Hi team,.1) Session Invalidation on browser exit ,Pls guide how to achieve this in ADF/JSF

    ReplyDelete

Provide your thoughts !