参考:https://www.cnblogs.com/nyhhd/p/12684177.html
session存在服务端,session监听器可以用来跟踪session的生命周期。spring-boot项目越来越流行,我就记录下spring boot项目中使用session监听器的过程,以便以后参考。
spring boot使用监听器非常方便,使用这2个注解就可自动加载注册了:@WebListener和@ServletComponentScan
首先在springboot启动类SpringBootApplication 上使用@ServletComponentScan注解。然后使用@WebListener声明监听器。
SpringBootApplication
上使用@ServletComponentScan
注解后
Servlet
可以直接通过@WebServlet
注解自动注册
Filter
可以直接通过@WebFilter
注解自动注册
Listener
可以直接通过@WebListener
注解自动注册
在启动类上使用@ServletComponentScan,就可以自动扫描使用@WebServlet、@WebFilter和@WebListener注解的类完成自动注册。
1.编写session监听器类实现HttpSessionListener接口,并加上@WebListener注解,声明此类是一个监听器。
@WebListener
public class OpOnlineUserSessionListener implements HttpSessionListener {
/**
* session被销毁时触发,如下情况
* 1.主动调用session.invalidate()
* 2.session超时
*/
@Override
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
//获取当前用户信息
Params params = (Params)session.getAttribute("userName");
//移除在线用户
if(params!= null && StringUtils.isNotEmpty(params.getUsername())){
LoginOperateInfo loginInfo = new LoginOperateInfo();
//为0代表不是登录状态
loginInfo.setIsLogin(LoginStatusEnum.OFF_LINE.getCode());
loginInfo.setSessionId(session.getId());
//为2代表操作类型为登出
loginInfo.setOperateType(LoginStatusEnum.LOGIN_OUT.getCode());
loginInfo.setUserId(params.getUserId());
loginInfo.setUserNo(params.getUsername());
loginInfo.setUserName(params.getUserNameCN());
int count = updateIsLogin(session.getId());
if(count>0){
insertLoginOperateInfo(loginInfo);
}
}
}
//session被创建时触发
@Override
public void sessionCreated(HttpSessionEvent event) {
/*HttpSession session = event.getSession();
Params params1 = (Params)session.getServletContext().getAttribute("userName");
//获取当前用户信息
Params params = (Params)session.getAttribute("userName");
//添加在线登录记录
if(params!= null && StringUtils.isNotEmpty(params.getUsername())){
LoginOperateInfo loginInfo = new LoginOperateInfo();
//为1代表是登录状态
loginInfo.setIsLogin(1);
loginInfo.setSessionId(session.getId());
//为1代表操作类型为登陆
loginInfo.setOperateType(1);
loginInfo.setUserId(params.getUserId());
loginInfo.setUserNo(params.getUsername());
loginInfo.setUserName(params.getUserNameCN());
insertLoginOperateInfo(loginInfo);
}*/
}
/**
* 登录登出操作记录表
* @param loginInfo
*/
private void insertLoginOperateInfo(LoginOperateInfo loginInfo){
loginInfo.setOperateTime(new Date());
loginInfo.setCreateTime(new Date());
ICASUserDao userDao = SpringContextUtil.getBean(ICASUserDao.class);
userDao.insertLoginOperate(loginInfo);
}
/**
* 根据sessionId更新用户登录状态
* @param sessionId
*/
private int updateIsLogin(String sessionId){
ICASUserDao userDao = SpringContextUtil.getBean(ICASUserDao.class);
return userDao.updateIsLogin(sessionId);
}
}
2.启动类上使用@ServletComponentScan,自动扫描带有(@WebServlet, @WebFilter, and @WebListener)注解的类,完成注册。
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})//无数据库运行
@ServletComponentScan //scans from the package of the annotated class (@WebServlet, @WebFilter, and @WebListener)
public class WebApp{
public static void main(String[] args) {
System.out.println(" springApplication run !");
SpringApplication.run(WebApp.class,args);
}
}
只用简单的2个注解就完成了session监听器的注册。这样就能监听到容器session的生命周期了。
注意:HttpServletRequest的getSession()方法,如果当前请求没有对应的session会自动创建session。
使用getSession(false)就不会创建session,如果没有当前请求对应的session就返回null.