java session 数量_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 sessions;

static int delS = -1;

static boolean flag = false;

static {

if (sessions == null) {

sessions = Collections

.synchronizedList(new ArrayList());

}

}

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存放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";

}

页面捕获提示信息代码

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值