经过监听Session对象的方式来实如今线人数的统计和在线人信息展现,而且让超时的自动销毁html
1. web.xmljava
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 统计在线人数--> <listener> <listener-class>com.wri.itmag.OnlineCounterListener</listener-class> </listener> <!-- session超时定义,单位为分钟 update by ChangPeng 2014-04-24 session超时时间设置为30分钟 --> <session-config> <session-timeout>30</session-timeout> </session-config> </web-app>
2.OnlineCounterListener.javaweb
对Session对象实现监听,首先必须继承HttpSessionListener类,该程序的基本原理就是当浏览者访问页面的时候一定会产生一个session对象;当关闭该页面的时候必然会删除该session对象。因此每当产生一个新的session对象就让在线人数加1,当删除一个session对象就让在线人数减1。还要继承一个HttpSessionAttributeListener,来实现对其属性的监听。分别实现attributeAdded方法,attributeReplace方法以及attributeRemove方法。json
sessionCreated//新建一个会话时候触发也能够说是客户端第一次和服务器交互时候触发浏览器
sessionDestroyed//销毁会话的时候 通常来讲只有某个按钮触发进行销毁 或者配置定时销毁 ( 不少文献中提到说浏览器关闭时候会销毁 可是楼主经过各类现行主流浏览器测试效果不尽如人意)服务器
HttpSessionAttributeListener有3个接口须要实现session
attributeAdded//在session中添加对象时触发此操做 笼统的说就是调用setAttribute这个方法时候会触发的app
attributeRemoved//修改、删除session中添加对象时触发此操做 笼统的说就是调用 removeAttribute这个方法时候会触发的jsp
attributeReplaced//在Session属性被从新设置时ide
1 package com.wri.itmag; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.HashSet; 6 import java.util.List; 7 import java.util.Map; 8 import java.util.Set; 9 10 import javax.servlet.http.HttpSessionAttributeListener; 11 import javax.servlet.http.HttpSessionBindingEvent; 12 import javax.servlet.http.HttpSessionEvent; 13 import javax.servlet.http.HttpSessionListener; 14 15 import com.wri.itmag.vo.personalInfo.UserVO; 16 17 public class OnlineCounterListener implements HttpSessionListener, 18 HttpSessionAttributeListener { 19 public static int onLineCount; // 用于统计在线人数 20 /** 21 * 查询在线人名称,用于前台页面对于在线人名称的展现 22 */ 23 public static Set<String> onLinePersonList = new HashSet<String>();//用于 24 /** 25 * 用于查询在线人详细信息 26 */ 27 private Map<String, Object> sessionMap = new HashMap<String, Object>(); 28 29 public void sessionCreated(HttpSessionEvent hse) { 30 // HttpSession session = hse.getSession(); 31 // sessionMap.put(session.getId(), session); 32 // onLineCount = sessionMap.size(); 33 } 34 35 public void sessionDestroyed(HttpSessionEvent hse) { 36 // onLineCount = sessionMap.size(); 37 } 38 39 public void attributeAdded(HttpSessionBindingEvent hsbe) { 40 41 String name = hsbe.getName(); 42 if ("userVO".equals(name)) { 43 UserVO userVO = (UserVO) hsbe.getValue(); 44 sessionMap.put(userVO.getId() + "", userVO); 45 onLineCount = sessionMap.size(); 46 onLinePersonList.add(userVO.getUser_name()); 47 } 48 } 49 50 public void attributeRemoved(HttpSessionBindingEvent hsbe) { 51 String name = hsbe.getName(); 52 if ("userVO".equals(name)) { 53 UserVO userVO = (UserVO) hsbe.getValue(); 54 sessionMap.remove(userVO.getId() + ""); 55 onLineCount = sessionMap.size(); 56 //System.out.println(userVO.getId() + "" + userVO.getUser_name()); 57 onLinePersonList.remove(userVO.getUser_name()); 58 } 59 60 } 61 62 public void attributeReplaced(HttpSessionBindingEvent hsbe) { 63 64 String name = hsbe.getName(); 65 if ("userVO".equals(name)) { 66 UserVO userVO = (UserVO) hsbe.getValue(); 67 sessionMap.remove(userVO.getId() + ""); 68 onLineCount = sessionMap.size(); 69 onLineCount++; 70 onLinePersonList.remove(userVO.getUser_name()); 71 } 72 } 73 74 }
3.LoginAction.java
实现用户登陆,登出,以及登陆成功页面跳转的功能
1 package com.wri.itmag.action.login; 2 3 import java.io.IOException; 4 import java.text.SimpleDateFormat; 5 import java.util.ArrayList; 6 import java.util.Arrays; 7 import java.util.Date; 8 import java.util.List; 9 10 import javax.servlet.ServletException; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 import javax.servlet.http.HttpSession; 14 15 import net.sf.json.JSONObject; 16 17 import com.wri.itmag.OnlineCounterListener; 18 import com.wri.itmag.action.BaseAction; 19 import com.wri.itmag.common.LoginUserLog; 20 import com.wri.itmag.service.personalInfo.UserInfoService; 21 import com.wri.itmag.service.syscfg.DataDictManageService; 22 import com.wri.itmag.vo.personalInfo.UserVO; 23 24 public class LoginAction extends BaseAction { 25 private UserInfoService userInfoService; 26 private String userAccount; 27 private String password; 28 29 /** 30 * 登陆操做 31 */ 32 public String login() throws Exception { 33 UserVO userVO = null; 34 HttpSession session = this.getSession(); 35 try { 36 userVO = userInfoService.checkUser(userAccount, password); 37 38 } catch (Exception e) { 39 e.printStackTrace(); 40 throw e; 41 } 42 try { 43 if (userVO != null) { 44 HttpServletRequest request = this.getRequest(); 45 // 登录信息 46 LoginUserLog loginUserLog = new LoginUserLog(userVO.getId(), 47 request.getRemoteAddr()); 48 // 放入session 49 session.setAttribute("loginUserLog", loginUserLog); 50 session.setAttribute("userVO", userVO); 51 session.setAttribute("userJson", JSONObject.fromObject(userVO)); 52 this.outJsonString("{success:true,message:'登录成功'}"); 53 } else { 54 this.outJsonString("{success:false,message:'请检查用户名和密码....'}"); 55 } 56 } catch (Exception ex) { 57 ex.printStackTrace(); 58 throw ex; 59 } 60 return null; 61 } 62 63 64 /** 65 * 用户退出 66 */ 67 public String logout() throws Exception { 68 HttpSession session = this.getSession(); 69 70 // 从session中获取用户信息 71 UserVO userVO = (UserVO) session.getAttribute("userVO"); 72 LoginUserLog loginUserLog = (LoginUserLog) session 73 .getAttribute("loginUserLog"); 74 if (loginUserLog != null) { 75 if (loginUserLog.isExist(loginUserLog.getUid())) { 76 session.setAttribute("loginUserLog", null); 77 session.setAttribute("userVO", null); 78 session.invalidate(); 79 } 80 } 81 82 // session.setAttribute("userVO", null); 83 // session.invalidate(); 84 85 this.outJsonString("{success:true}"); 86 return null; 87 } 88 89 /** 90 * 登陆成功操做 91 */ 92 public String loginSucc() throws ServletException, IOException { 93 // 传递角色 94 HttpSession session = this.getSession(); 95 UserVO userVO = (UserVO) session.getAttribute("userVO"); 96 this.outJsonString("{success:true,userVO:'" 97 + JSONObject.fromObject(userVO) + "',isMyDemand:'" + isMyDemand 98 + "'}"); 99 return null; 100 } 101 102 /** 103 * 登录成功后跳转到主界面 104 */ 105 public String jump() throws ServletException, IOException { 106 HttpSession session = this.getSession(); 107 HttpServletRequest request = this.getRequest(); 108 HttpServletResponse response = this.getResponse(); 109 if (session.isNew()) { 110 response.sendRedirect("login.html"); 111 } else { 112 UserVO userVO = (UserVO) session.getAttribute("userVO"); 113 if (userVO != null) { 114 request.setAttribute("userVO", userVO); 115 request.setAttribute("logTime", new SimpleDateFormat( 116 "yyyy-MM-dd").format(new Date())); 117 request.setAttribute("onlineCount", 118 OnlineCounterListener.onLineCount); 119 120 request.setAttribute("onLinePersonList", 121 OnlineCounterListener.onLinePersonList); 122 request.getRequestDispatcher("/WEB-INF/main.jsp").forward( 123 request, response); 124 } else { 125 response.sendRedirect("login.html"); 126 } 127 } 128 return null; 129 } 130 }
4.main.jsp 作页面展现 :在登录完成后跳转到主页面就会显示在线人数,鼠标移至人数上时候,就会显示全部在线人信息,鼠标移出就自动隐藏。
... <span title="" style="font-size: 13px; font-family: 宋体; position: absolute; right: 5px; width: 80px;" onmouseover="showOnLinePersonList()" onmouseout="hideOnLinePersonList()"> 在线:${onlineCount}人 </span> <span id="onlinePersonList" style="display:none;font-size: 13px; font-family: 宋体; position: absolute; top:10px ;right: 10px; width: 80px;"> <div id="firstDiv" align="center" style="backgroud-color:#8069ff ;border-style:solid;border-width:1px">全部在线人</div> <div id="secondDiv" align="center"> <c:forEach items="${onLinePersonList}" var ="list"> <ol ><c:out value="${list}"/> </ol> </c:forEach> </div> </span> ..... <script> function showOnLinePersonList(){ document.getElementById('onlinePersonList').style.display="block"; } function hideOnLinePersonList(){ document.getElementById('onlinePersonList').style.display="none"; } </script>
未解决的问题:以上的代码能够成功的实如今线人数的统计,可是对于在线展现在线人信息的时候,还有bug存在。出现的状况为:若是在同一个客户端,一个用户登陆以后,没有作登出的操做(即session没有销毁),此时再以另外一个用户登陆,这个时候就至关于session中的name为“uservo”的attribute被替换了,也就调用了OnlineCounterListener类中的attributeReplace方法,代码以下:onLinePersonList先要remove掉以前的用户,加入新的用户,可是attributeRemoved(HttpSessionBindingEvent hsbe)中hsbe.getValue()拿到的是以前的值,无法拿到新的用户的值,因此不知道如何把新登陆的这个用户加到set里面去,求解!!!
if ("userVO".equals(name)) {
UserVO userVO = (UserVO) hsbe.getValue(); sessionMap.remove(userVO.getId() + ""); onLineCount = sessionMap.size(); onLineCount++; onLinePersonList.remove(userVO.getUser_name()); }