一、session简单介绍
在做在线统计人数监听器前,需要先简单了解一下session。
Session存储在服务器端,一般放置在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。
二、注意事项
1、一个浏览器只能创建一个session对象,也就是说多用户会覆盖session。
2、同一用户不用浏览器登录,会产生多个session,这时候需要判断用户是否已登录,将新session替换就session。
三、实现部分
这里的在线人数统计主要继承了HttpSessionListener接口,它的两个方法能够对服务器session的创建以及销毁进行监听。
package com.shenofusc.utils;
import java.util.ArrayList;
import java.util.HashSet;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class SessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
HttpSession session=event.getSession();
ServletContext context=session.getServletContext();
//用set集合来存储session对象
HashSet<HttpSession> sessionSet=(HashSet<HttpSession>) context.getAttribute("sessionSet");
if(sessionSet==null){
sessionSet=new HashSet<HttpSession>();
context.setAttribute("sessionSet", sessionSet);
}
//这里主要是为了检验用户是否登录,登录的话强制移除该session,加入新session
for(HttpSession s : sessionSet){
if(session.getAttribute("nickname")==s.getAttribute("nickname")){
sessionSet.remove(s);
}
}
sessionSet.add(session);
//存储在线人数,利用了set集合不重复的特性,避免了重复登录
context.setAttribute("lineCount", sessionSet.size());
}
//session的销毁监听
public void sessionDestroyed(HttpSessionEvent event) {
ServletContext context = event.getSession().getServletContext();
if (context.getAttribute("lineCount") == null) {
context.setAttribute("lineCount", 0);
} else {
int lineCount = (Integer) context.getAttribute("lineCount");
if (lineCount < 1) {
lineCount = 1;
}
context.setAttribute("lineCount", lineCount - 1);
}
HttpSession session = event.getSession();
HashSet<HttpSession> sessionSet = (HashSet<HttpSession>)context.getAttribute("sessionSet");
if(sessionSet!=null){
sessionSet.remove(session);
}
}
}
Controller的方法
/**
* 登录操作
* @param request
* @param email
* @param password
* @return
*/
@ResponseBody
@RequestMapping(value="/toLogin")
public int toLogin(HttpServletRequest request ,String email,String password) {
User user=userService.login(email,password);
if(user!=null){
HttpSession session = request.getSession();
session.setAttribute("nickname", user.getNickname()); //将用户名存入session
ServletContext context = session.getServletContext();
//打印在线人数
System.out.println("在线人数:"+context.getAttribute("lineCount"));
return 1;
}
return 0;
}
/**
* 注销操作,不是销毁session,因此不会触发sessionDestroyed方法,需要我们自己实现移除session操作
* @param session
* @return
*/
@RequestMapping("/outLogin")
public ModelAndView outLogin(HttpSession session) {
ServletContext context = session.getServletContext();
int lineCount = (Integer) context.getAttribute("lineCount");
context.setAttribute("lineCount", lineCount - 1);
HashSet<HttpSession> sessionSet = (HashSet<HttpSession>) context.getAttribute("sessionSet");
if(sessionSet!=null){
sessionSet.remove(session);
}
ModelAndView mv=new ModelAndView("login");
return mv;
}
最后记得要去web.xml里配置监听
<listener>
<listener-class>com.shenofusc.utils.SessionListener</listener-class>
</listener>