0

在我使用 Java EE 和 JSF 2.0 的应用程序中,我希望当用户关闭应用程序的选项卡时会话结束。如果此用户在应用程序中打开了另一个选项卡,则不应关闭此另一个选项卡的会话。这样就不会干扰应用程序的管理。

要结束我使用的会话:

public String deconnecter() {
    //invalidate user session
    FacesContext context = FacesContext.getCurrentInstance();
    HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
    session.invalidate();
    return "login";
}
4

2 回答 2

2

这不可能是你想要的方式。同一浏览器实例的所有窗口/选项卡共享同一会话。

无论如何,要实现这一点,您需要创建一个具有条件渲染包含的单个视图和一个视图范围 bean,您可以在其中存储与视图相关的所有内容,并始终返回voidnull从操作方法返回。这样,您根本不需要会话范围。要创建一个新视图,只需发送一个新的 GET 请求(如一个新选项卡)或null从操作方法返回一个非字符串。

于 2012-08-01T18:08:50.533 回答
1

可能为时已晚,但由于我在网上看到了许多与此相关的问题,我可能只是把我的解决方案放在这里,我已经在 chrome 和 firefox 上进行了测试(尽管所有最新版本)

设置:更优雅的解决方案是使用过滤器,但我使用了预渲染事件(对我的整个网站使用单个模板,因此我可以跟踪每个页面的加载时间,并且我已经在模板上指定了预渲染事件)

Javascript部分:

    window.onbeforeunload = function(){
      //log out of the server too.
      var xmlhttp;
      if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
      }
      else
      {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
      var url = '/context/index.xhtml?onunload=true';
      xmlhttp.open('GET', url, true);
      xmlhttp.send();
    }
     window.onload = function(){
      console.log('window name: '+window.name);
      if(window.name != '#{controller.sessionId}'){
        window.name = '#{controller.sessionId}';
        var xmlhttp;
        if (window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari
          xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
          xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        var url = '/context/index.xhtml?onload=true';
        xmlhttp.open('GET', url, true);
        xmlhttp.send();
      }
    }
    //Called when user logs out.
    function onLogout(){
      console.log('logging out: '+window.name);
      window.name = '';
      console.log('logged out: '+window.name);
    }

服务器端代码:

该方法在视图在 prerender 事件上渲染之前被调用

public void trackUserTabs() {
String onload = Controller.getParameter(ONLOAD_ID);
if (onload != null && onload.trim().equals("true")) {
  openedTabs++;
  System.err.println("onload: " + controller.getCurrentPrinciple() + "..........." + openedTabs);
}
String onunload = Controller.getParameter(ONUNLOAD_ID);
if (onunload != null && onunload.trim().equals("true")) {
  openedTabs--;
  System.err.println("onunload: " + controller.getCurrentPrinciple() + ".............." + openedTabs);
}
if (openedTabs <= 0 && controller.getCurrentProfile() != null) {
  /**
   * All tabs are closed, log out current user.
   */
  controller.logoutCurrentProfile();
}

}

ajax 请求的 javascript 代码由 Stackoverflow 中的答案提供。

于 2012-12-05T06:02:13.113 回答