`
zxingchao2005
  • 浏览: 76384 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

在Struts2下使用[拦截器]配合[session监听器]实现在线会员统计与防止重复登录

 
阅读更多

需求:

1.管理员后台可显示当前在线访客数以及在线会员数(在线会员要求列出详细清单).

2.某个客户端非法退出(直接关闭浏览器或断电啥的)后,接着他重新登录系统.在线统计上要做到保持登录统计的准确性与完整性.

3.防止多个客户端同时使用一个帐户异地登录(后登录者踢掉先登录者,并通知先登录者被迫下线).

1.监听器SessionListener (web.xml的代码略)

Java代码 复制代码收藏代码
  1. /**
  2. *创建session
  3. */
  4. publicvoidsessionCreated(HttpSessionEventse){
  5. OnlineStatistics.increase();
  6. }
  7. /**
  8. *服务器销毁session对象
  9. */
  10. publicvoidsessionDestroyed(HttpSessionEventse){
  11. OnlineStatistics.decrease();
  12. }
  13. /**
  14. *用户登录时
  15. */
  16. publicvoidattributeAdded(HttpSessionBindingEventse){
  17. if("memberInfo".equals(se.getName())){
  18. MemberInfomemberInfo=(MemberInfo)se.getValue();
  19. OnlineStatistics.addAttr(memberInfo);
  20. se.getSession().setMaxInactiveInterval(60*20);//失效时间SEC*MINS
  21. }
  22. }
  23. /**
  24. *用户退出登录(销毁session属性时)
  25. */
  26. publicvoidattributeRemoved(HttpSessionBindingEventse){
  27. if("memberInfo".equals(se.getName())){
  28. MemberInfomemberInfo=(MemberInfo)se.getValue();
  29. OnlineStatistics.removeAttr(memberInfo);
  30. memberInfo=null;
  31. }
  32. }
  33. /**
  34. *待实现
  35. */
  36. publicvoidattributeReplaced(HttpSessionBindingEventse){
  37. //tobeextended
  38. }
/**
	 * 创建session
	 */
	public void sessionCreated(HttpSessionEvent se) {
		OnlineStatistics.increase();
	}

	/**
	 * 服务器销毁session对象
	 */
	public void sessionDestroyed(HttpSessionEvent se) {
		OnlineStatistics.decrease();
	}

	/**
	 * 用户登录时
	 */
	public void attributeAdded(HttpSessionBindingEvent se) {
		if ("memberInfo".equals(se.getName())) {
			MemberInfo memberInfo = (MemberInfo) se.getValue();
			OnlineStatistics.addAttr(memberInfo);
			se.getSession().setMaxInactiveInterval(60 * 20);// 失效时间SEC * MINS
		}
	}

	/**
	 * 用户退出登录(销毁session属性时)
	 */
	public void attributeRemoved(HttpSessionBindingEvent se) {
		if ("memberInfo".equals(se.getName())) {
			MemberInfo memberInfo = (MemberInfo) se.getValue();
			OnlineStatistics.removeAttr(memberInfo);
			memberInfo = null;
		}
	}

	/**
	 * 待实现
	 */
	public void attributeReplaced(HttpSessionBindingEvent se) {
//to be extended
	}

2. 统计类OnlineStatistics

Java代码 复制代码收藏代码
  1. /**
  2. *@authorArantam
  3. */
  4. packagecom.farago.util;
  5. importjava.util.Date;
  6. importjava.util.HashSet;
  7. importjava.util.Iterator;
  8. importjava.util.Set;
  9. importcom.farago.vo.MemberInfo;
  10. /**
  11. *@authorArantam
  12. *
  13. */
  14. @SuppressWarnings("unchecked")
  15. publicclassOnlineStatistics{
  16. privatestaticintcount=0;
  17. privatestaticSetonlineMemberList=newHashSet();
  18. /**
  19. *统计在线总数(递增)
  20. */
  21. publicstaticvoidincrease(){
  22. count++;
  23. }
  24. /**
  25. *统计在线人数(递减)
  26. */
  27. publicstaticvoiddecrease(){
  28. count--;
  29. }
  30. /**
  31. *统计在线会员(添加)
  32. *
  33. *@parammemberInfo
  34. */
  35. publicstaticvoidaddAttr(MemberInfomemberInfo){
  36. //如果在线会员列表不为空,则迭代该列表,检查当前登录的会员id与列表中的记录id是否一致.
  37. Iteratoritr=onlineMemberList.iterator();
  38. while(itr.hasNext()){
  39. //先判断该会员是否已有session信息保存在统计对象中.若有,把旧的挤掉,再放入新的.
  40. MemberInfotemp=(MemberInfo)itr.next();
  41. StringmemberName=temp.getName();//保存在统计类中的用户名
  42. if(memberInfo.getName().equals(memberName)){
  43. itr.remove();
  44. }
  45. }
  46. onlineMemberList.add(memberInfo);
  47. }
  48. /**
  49. *统计在线会员(清除)
  50. *
  51. *@parammemberInfo
  52. */
  53. publicstaticvoidremoveAttr(MemberInfomemberInfo){
  54. onlineMemberList.remove(memberInfo);
  55. }
  56. /**
  57. *获取在线访客的数量
  58. *
  59. *@returnthecount
  60. */
  61. publicstaticintgetOnlineVisitors(){
  62. returncount-1;//除去管理员本身
  63. }
  64. /**
  65. *获取在线会员的列表
  66. *
  67. *@returntheonlineMemberList
  68. */
  69. publicstaticSetgetOnlineMemberList(){
  70. returnonlineMemberList;
  71. }
  72. /**
  73. *根据登录时间判断登录次序的先后
  74. *
  75. *@parammemberInfo
  76. *@return
  77. */
  78. publicstaticbooleanisOld(MemberInfomemberInfo){
  79. Iteratoritr=onlineMemberList.iterator();
  80. while(itr.hasNext()){
  81. MemberInfotemp=(MemberInfo)itr.next();
  82. StringmemberName=temp.getName();//保存在统计类中的用户名
  83. DateloginTime=temp.getLoginTime();//保存在统计类中的用户登录时间
  84. if(memberInfo.getName().equals(memberName)&&memberInfo.getLoginTime().before(loginTime)){
  85. //如果当前用户的登录时间比统计对象里保存的同名用户的登录时间要早,则返回true
  86. returntrue;
  87. }
  88. }
  89. returnfalse;
  90. }
  91. }
/**
 * @author Arantam
 */
package com.farago.util;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.farago.vo.MemberInfo;

/**
 * @author Arantam
 * 
 */
@SuppressWarnings("unchecked")
public class OnlineStatistics {
	private static int count = 0;
	private static Set onlineMemberList = new HashSet();

	/**
	 * 统计在线总数(递增)
	 */
	public static void increase() {
		count++;
	}

	/**
	 * 统计在线人数(递减)
	 */
	public static void decrease() {
		count--;
	}

	/**
	 * 统计在线会员(添加)
	 * 
	 * @param memberInfo
	 */
	public static void addAttr(MemberInfo memberInfo) {
		// 如果在线会员列表不为空,则迭代该列表,检查当前登录的会员id与列表中的记录id是否一致.
		Iterator itr = onlineMemberList.iterator();
		while (itr.hasNext()) {
			// 先判断该会员是否已有session信息保存在统计对象中.若有,把旧的挤掉,再放入新的.
			MemberInfo temp = (MemberInfo) itr.next();
			String memberName = temp.getName();// 保存在统计类中的用户名
			if (memberInfo.getName().equals(memberName)) {
				itr.remove();
			}
		}
		onlineMemberList.add(memberInfo);
	}

	/**
	 * 统计在线会员(清除)
	 * 
	 * @param memberInfo
	 */
	public static void removeAttr(MemberInfo memberInfo) {
		onlineMemberList.remove(memberInfo);
	}

	/**
	 * 获取在线访客的数量
	 * 
	 * @return the count
	 */
	public static int getOnlineVisitors() {
		return count - 1;// 除去管理员本身
	}

	/**
	 * 获取在线会员的列表
	 * 
	 * @return the onlineMemberList
	 */
	public static Set getOnlineMemberList() {
		return onlineMemberList;
	}

	/**
	 * 根据登录时间判断登录次序的先后
	 * 
	 * @param memberInfo
	 * @return
	 */
	public static boolean isOld(MemberInfo memberInfo) {
		Iterator itr = onlineMemberList.iterator();
		while (itr.hasNext()) {
			MemberInfo temp = (MemberInfo) itr.next();
			String memberName = temp.getName();// 保存在统计类中的用户名
			Date loginTime = temp.getLoginTime();// 保存在统计类中的用户登录时间
			if (memberInfo.getName().equals(memberName) && memberInfo.getLoginTime().before(loginTime)) {
				// 如果当前用户的登录时间比统计对象里保存的同名用户的登录时间要早,则返回true
				return true;
			}
		}
		return false;
	}

}

3. 拦截器代码片断

Java代码 复制代码收藏代码
  1. MapsessionMap=invocation.getInvocationContext().getSession();
  2. if(sessionMap.get("memberInfo")!=null){
  3. MemberInfomemberInfo=(MemberInfo)sessionMap.get("memberInfo");
  4. /**
  5. *
  6. */
  7. if(OnlineStatistics.isOld(memberInfo)){
  8. sessionMap.remove("memberInfo");//清除session
  9. faragoMessage="对不起,您的帐号["+memberInfo.getName()+"]已在别的地方登录,您已被迫退出。若有疑问请联系管理员,谢谢!";
  10. ctx.put("faragoMessage",faragoMessage);
  11. returnAction.ERROR;
  12. }
  13. ......
  14. ...
Map sessionMap = invocation.getInvocationContext().getSession();
		if (sessionMap.get("memberInfo") != null) {
			MemberInfo memberInfo = (MemberInfo) sessionMap.get("memberInfo");

			/**
			 * 
			 */
			if (OnlineStatistics.isOld(memberInfo)) {
				sessionMap.remove("memberInfo");// 清除session
				faragoMessage = "对不起,您的帐号[" + memberInfo.getName() + "]已在别的地方登录,您已被迫退出。若有疑问请联系管理员,谢谢!";
				ctx.put("faragoMessage", faragoMessage);
				return Action.ERROR;
			}
......
...

如果想在前台也显示当前在线人数,可以在sessionCreated和sessionDestroyed方法中处理,把统计数字放入ServletContext里面.然后使用S2的标签直接显示.这样来得方便.呵呵

分享到:
评论
1 楼 lushan_0312 2012-02-15  
我想问一个问题,我在监听的销毁方法里调用了数据访问层,这个需要怎么实现呢?

相关推荐

    拦截器和控制器的区别

    2、拦截器不依赖于servlet容器,通过动态代理实现,过滤器依赖于servlet容器 3、拦截器在方法前后,异常前后等调用,而过滤器只能在请求前和请求后各调一次。 4、拦截器可以利用依赖注入,因此在spring框架程序中,...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    10.8.2 使用专门的监听器实现回调 448 10.8.3 为全部实体配置默认监听器 450 10.8.4 排除监听器 452 10.9 本章小结 455 第11章 JPA的查询支持 456 11.1 查询API 457 11.1.1 面向对象的JPQL 457 11.1.2 查询API简介 ...

    java后台框架源码

    action:存放struts2控制类的包 dao:数据库访问封装 enm:系统中使用到的常量包,这里不是用的常量,用的是枚举替代常量 entity:hibernate对应的orm与数据库表一一对应的实体类 filter:Log4jFormatFilter(格式化...

    从J2SE到J2EE知识点介绍

    1. struts2的拦截器定义以及使用 153 2. struts标签 160 3. Struts 2 标签库说明及使用 160 4. set 描述 169 5. text 描述 170 6. property 描述 170 7. Struts的异常处理 171 8. Struts的上传与下载 178 五、 ...

    Spring中文帮助文档

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...

    Spring API

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.5.3.1. RedirectView 13.5.3.2. redirect:前缀 13.5.3.3. forward:...

    Java学习笔记-个人整理的

    \contentsline {chapter}{Contents}{2}{section*.1} {1}Java基础}{17}{chapter.1} {1.1}基本语法}{17}{section.1.1} {1.2}数字表达方式}{17}{section.1.2} {1.3}补码}{19}{section.1.3} {1.3.1}总结}{23}{...

    spring chm文档

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2....

    Spring 2.0 开发参考手册

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2....

Global site tag (gtag.js) - Google Analytics