java中使用session监听实现同帐号登录限制、登录人数限制

本文主要介绍了java中使用session监听实现同帐号登录限制、登录人数限制,具体代码如下:

问题域:

1、同帐号登录:若此帐号已登录,不可再次登录(与QQ模式相反)。

2、登录人数限制,超过、已达人数限制则提示:系统繁忙,稍后再试。

解决思路:使用HttpSessionAttributeListener监听器(虽然我同时使用了HttpSessionListener不过感觉不好操作)

知识储备:HttpSessionAttributeListener中有attributeAdd、attributeRemove、attributeReplace3个方法。

对session的setAttribute、removeAttribute将触发attributeAdd、attributeRemove方法,对同一个session的同一个attribute进行重复设置将触发attributeReplace方法。

HttpSessionListener不好操作的原因:只要访问jsp页面便会创建session(访问html并不会创建session,在server端,如servlet中调用HttpServletRequest.getSession(true)才会创建),jsp是动态页,本质就是个servlet。我的login.jsp显然是个jsp,当我在监听器中invalidate一个session,返回登录页,马上就又创建了一个session。这是我感觉不清楚的地方,功夫没到家。

具体实现:

监听器代码

public class OnlineListener implements HttpSessionListener,
    HttpSessionAttributeListener {
  private static List<SessionAndUser> sessions;
  static int delS = -1;
  static boolean flag = false;
  static {
    if (sessions == null) {
      sessions = Collections
          .synchronizedList(new ArrayList<SessionAndUser>());
    }
  }
  public void sessionCreated(HttpSessionEvent hse) {
    System.out.println(hse.getSession() + "-" + new Date());
    System.out.println(hse.getSession() + "-" + new Date());
  }
  public void sessionDestroyed(HttpSessionEvent hse) {
    System.out.println("-------------sessionDestroyed()-----------");
    System.out.println(hse.getSession() + " "
        + new Date(hse.getSession().getLastAccessedTime()));
    System.out.println(hse.getSession() + " " + new Date());
  }
  public void attributeAdded(HttpSessionBindingEvent e) {
    System.out.println("-------------*start added*-----------------------"
        + sessions.size());
    HttpSession session = e.getSession();
    ActionContext ctx = ActionContext.getContext();
    boolean newOne = true;
    String attrName = e.getName();
    // 登录
    if (attrName.equals(Constant.USER_NAME)) {
      // 检查登录人数
      if (sessions.size() >= Constant.USER_LIMIT) {
        newOne = false;
        ctx.put("timeoutMSG", "serverBusy");
      }
      String nowUser = (String) e.getValue();
      // 遍历所有session,检查是否已经登录,若是则提示已经登录
      for (int i = sessions.size() - 1; i >= 0; i--) {
        SessionAndUser tem = sessions.get(i);
        if (tem.getUserName().equals(nowUser)) {
          newOne = false;
          ctx.put("timeoutMSG", "beenLoged");// tem.getSession().invalidate();//
                            // 同账号顶替登录,自动调用remove
          break;
        }
      }
      // 新登录帐号添加进账户维护列表
      if (newOne) {
        SessionAndUser sau = new SessionAndUser();
        sau.setUserName(nowUser);
        sau.setSession(session);
        sau.setSid(session.getId());
        sessions.add(sau);
      }
    }
  }
  public void attributeRemoved(HttpSessionBindingEvent e)
      throws IllegalStateException {
    HttpSession session = e.getSession();
    System.out
        .println("-------------*start Removed*-----------------------"
            + sessions.size());
    if (delS > -1) {
      if (flag) {
        sessions.remove(delS);
        flag = false;
      }
    } else {
      // 登录
      String attrName = e.getName();
      if (attrName.equals(Constant.USER_NAME)) {
        String nowUser = (String) e.getValue();
        // 遍历所有session
        for (int i = sessions.size() - 1; i >= 0; i--) {
          SessionAndUser tem = sessions.get(i);
          if (tem.getUserName().equals(nowUser)) {
            sessions.remove(i);
            break;
          }
        }
      }
    }
  }
  public void attributeReplaced(HttpSessionBindingEvent e) {
    HttpSession session = e.getSession();
    System.out
        .println("-------------*start replace*-----------------------"
            + sessions.size());
    String attrName = e.getName();
    delS = -1;
    // 登录
    if (attrName.equals(Constant.USER_NAME)) {
      // User nowUser = (User) e.getValue();//old value
      String nowUser = (String) session.getAttribute(Constant.USER_NAME);// 当前session中的user
      // 遍历所有session
      for (int i = sessions.size() - 1; i >= 0; i--) {
        SessionAndUser tem = sessions.get(i);
        if (tem.getUserName().equals(nowUser)
            && !tem.getSid().equals(session.getId())) {
          System.out.println("Remove:invalidate 1!");
          delS = i;
          flag = true;
        } else if (tem.getSid().equals(session.getId())) {
          tem.setUserName(nowUser);
        }
      }
      if (delS != -1) {
        sessions.get(delS).getSession().invalidate();// 失效时自动调用了remove方法。也就会把它从sessions中移除了
      }
    }
  }
}

代码主要思路是定义一个静态List<SessionAndUser>存放session和帐号名称。

登录的Action中获得监听器返回值并处理的代码

session.setAttribute(Constant.USER_NAME, operator.getUsername());
    ActionContext ctx = ActionContext.getContext();
    if("serverBusy".equals(ctx.get("timeoutMSG"))){
      ctx.put("timeoutMSG", "服务器繁忙,请稍后再试");
      return "jump";
    }
    if("beenLoged".equals(ctx.get("timeoutMSG"))){
      ctx.put("timeoutMSG", "此账户在别处登录");
      return "jump";
    }

页面捕获提示信息代码

<%@taglib prefix="s" uri="/struts-tags"%>
<s:property value="#attr.timeoutMSG" />

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2016-10-17

JAVAEE中用Session简单实现购物车功能示例代码

Session简单实现购物车功能 这个小程序主要就3个页面,一个商品列表页面(HomeServlet),一个是提示加入购物车页面(AddCartTipServlet),一个是显示购物车清单页面(ShowCartServlet). HomeServlet页面: @WebServlet({ "/HomeServlet", "/home" }) public class HomeServlet extends HttpServlet { private static fi

JavaWeb Session 会话管理实例详解

Session会话简介 会话是指在一段时间内,用户使用同一个浏览器进程与Web应用之间的交互过程. 会话(Session)通常用来跟踪用户的状态,缓存用户在此浏览器进程中的信息. 当用户关闭浏览器,上一个Session也就无法再次获得了(Cookie的maxAge为-1的情况).再次打开新的浏览器,将开始一个新的会话. 类javax.servlet.http.HttpSession.每一个HttpSession代表用户的一个会话. 每一个Session的过期时间默认为30分钟. 当浏览器第一次访

Java Web基于Session的登录实现方法

本文实例讲述了Java Web基于Session的登录实现方法.分享给大家供大家参考,具体如下: package cn.com.login; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpSer

JavaWeb使用Session和Cookie实现登录认证

后台管理页面往往需要登录才可以进行操作,这时就需要Seession来记录登录状态 要实现起来也是非常简单,只需要自定义一个HandlerInterceptor就行了 自定义的HandlerInterceptor也只有短短几行代码 public class LoginInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpSer

Java设置session超时的几种方式总结

Java设置session超时的几种方式总结 1.      在web容器中设置(此处以tomcat为例) 在tomcat-5.0.28\conf\web.xml中设置,以下是tomcat 5.0中的默认配置: <!-- ==================== Default Session Configuration ================= --> <!-- You can set the default session timeout (in minutes) for

简介Java的Hibernate框架中的Session和持久化类

Session Session对象用于获取与数据库的物理连接. Session对象是重量轻,设计了一个互动是需要与数据库每次被实例化.持久化对象被保存,并通过一个Session对象中检索. 会话中的对象不应该保持开放很长一段时间,因为他们通常不被线程安全的,他们应该被创建并根据需要摧毁他们.这次会议的主要功能是提供创建,读取和删除操作映射的实体类的实例.实例中可能存在以下三种状态之一在给定时间点: 短暂性: 持久化类的未与会话相关联,并在数据库中没有代表性,没有标识值的新实例被Hibernate

cookie、session和java过滤器结合实现登陆程序

cookie.session和过滤器通常都是用在web应用中,cookie和session用来保存一定的数据,过滤器Filter则是在浏览器发出请求之后,而后台执行特定的请求之前发生一定的作用.之所以把这三个放一起,是因为有很多时候都会是把他们结合在一起使用,例如有些登陆程序. cookie是浏览器的机制,session是服务器的机制,但是实际上cookie也是由服务器生成的,之后返回给浏览器的,并不是浏览器本身生成.当浏览器发送某个请求时,如果拥有有效的cookie则会把这个cookie带在一

thinkPHP框架实现类似java过滤器的简单方法示例

本文实例讲述了thinkPHP框架实现类似java过滤器的简单方法.分享给大家供大家参考,具体如下: 写java web代码的时候,可以定义过滤器,对控制器进行过滤,可以实现权限验证等等 在thinkphp中也可以通过继承父类的方法,实现类似的需求 父类代码 <?php /** * Created by PhpStorm. * User: xieyicheng * Date: 2014/12/11 * Time: 14:43 */ namespace Admin\Controller; use

java 过滤器模式(Filter/Criteria Pattern)详细介绍

java 过滤器模式(Filter/Criteria Pattern) 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准. 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以

java 过滤器filter防sql注入的实现代码

实例如下: XSSFilter.java public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws IOException, ServletException { //flag = true 只做URL验证; flag = false 做所有字段的验证; boolean flag = true; if(flag){ //只

java过滤器中Filter的ChainFilter过滤链

1.什么是过滤器? 在客户端到服务器的过程中,当发送请求时,如果有不符合的信息将会被filter进行拦截,如果符合则会进行放行,在服务器给客户端响应时也会进行判断 如果有不符合的信息将会被filter进行拦截,如果符合则会进行放行. OOP:Java面向对象编程,抽象.封装.继承.多态. AOP:面向切面编程,过滤器就是一个面向切面的编程思想. AOP是sun公司srvlet2.3版本之后推出的新功能,在2.3之前的版本没有该功能,定义一个过滤器需要实现(implement)Filter接口,这

Java实现一个小说采集程序的简单实例

被标题吸引进来的不要骂我. 只是一个简单的实现,随手写了来下载一部喜欢的小说的.示例中的小说只是示例,不是我的菜. 使用了jsoup.挺好用的一个工具. 有需要的话,参考下自己改吧.挺简单的,是吧. 代码如下: package com.zhyea.doggie; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.n

java实现可安装的exe程序实例详解

java实现可安装的exe程序实例详解 通过编写Java代码,实现可安装的exe文件的一般思路: 1.在eclipse中创建java项目,然后编写Java代码,将编写好的Java项目导出一个.jar格式的jar包: 2.通过安装exe4j软件,将导出的.jar格式的文件制作成.exe格式的可执行的文件,(注意:此时的.exe文件只是可以执行,还不能够安装): 3.通过安装Inno setup软件,将可执行的.exe格式的文件..jar格式的文件以及其它需要的文件制作成一个可安装的.exe格式的文

java 矩阵乘法的mapreduce程序实现

java 矩阵乘法的mapreduce程序实现 map函数:对于矩阵M中的每个元素m(ij),产生一系列的key-value对<(i,k),(M,j,m(ij))> 其中k=1,2.....知道矩阵N的总列数;对于矩阵N中的每个元素n(jk),产生一系列的key-value对<(i , k) , (N , j ,n(jk)>, 其中i=1,2.......直到i=1,2.......直到矩阵M的总列数. map package com.cb.matrix; import stati

200行Java代码编写一个计算器程序

发现了大学时候写的计算器小程序,还有个图形界面,能够图形化展示表达式语法树,哈哈;) 只有200行Java代码,不但能够计算加减乘除,还能够匹配小括号~ 代码点评: 从朴素的界面配色到简单易懂错误提示,无不体现了"用户体验"至上的设计理念:代码异常处理全面合理.滴水不漏,代码缩进优雅大方,变量命名直观易懂:再结合长度适中简单明了的注释,程序整体给人一种清新脱俗之感.背后不难看出作者对学习的热爱以及对设计的苛求,工匠精神可见一斑,真可谓是大学数据结构学以致用的典范! 实现代码如下所示:

java仿windows记事本小程序

本文实例为大家分享了java仿windows记事本小程序的具体代码,供大家参考,具体内容如下 import java.awt.CheckboxMenuItem; import java.awt.Font; import java.awt.Frame; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.MenuShortcut; import java.awt.TextA