520也依旧勤奋的写着代码,我真是太勤勉了
实现了用户登录的监听器,实时监听session,以此控制数据库中用户的登录状态
本来在监听器上同时加入了@Component@WebListener,随后监听器便运行了两次,便去掉了@WebListener注解
以下是完整的监听器代码:
package com.video.listener;
import com.video.service.UserLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@Component
//@WebListener
public class UserLoginListener implements HttpSessionListener, ServletContextListener {
private ServletContext application = null;
@Autowired
private UserLoginService userLoginService;
public void contextDestroyed(ServletContextEvent s) {
System.out.println("context Destroyed");
}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("context init");
application = sce.getServletContext();
Set<String> onlineUserSet = new HashSet<>();
application.setAttribute("onlineUserSet", onlineUserSet);
}
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session create");
}
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
Set<String> onlineUserSet = (Set<String>)application.getAttribute("onlineUserSet");
String userId = (String)session.getAttribute("userId");
onlineUserSet.remove(userId);
application.setAttribute("onlineUserSet",onlineUserSet);
//设置离线状态
int rows = userLoginService.setOffline(userId);
if(rows>0){
System.out.println("离线成功");
}
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(formatter.format(date));
onlineUserSet = (Set<String>)application.getAttribute("onlineUserSet");
System.out.println("当前在线用户:"+onlineUserSet.toString());
System.out.println(userId + "-->超时退出");
}
}
这是登录功能代码:
@RequestMapping("/login")
@ResponseBody
public MsgResponse login(String number, String password,
Integer check, HttpServletRequest request){
User user = userLoginService.checkLogin(number,password,check);
//验证失败返回
if (user==null){
return MsgResponse.error("账号或密码错误");
}
HttpSession session = request.getSession();
ServletContext application = session.getServletContext();
//验证成功
//将用户信息添加到session当中
session.setAttribute("user",user);
String userId = user.getUserId();
//设置状态为离线
int rows = userLoginService.setOnline(userId);
//获取当前时间
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//将用户名信息加到application当中
session.setAttribute("userId", userId);
Set<String> onlineUserSet = (Set)application.getAttribute("onlineUserSet");
onlineUserSet.add(userId);
application.setAttribute("onlineUserSet", onlineUserSet);
//输出用户登录情况到控制台
System.out.println(formatter.format(date));
System.out.println("用户:"+userId+"已登录");
System.out.println("当前在线用户:"+onlineUserSet.toString());
return MsgResponse.success("登录成功",null);
}
同时还需要在启动器上加上@ServletComponentScan注解
配置文件properties中可以设置session的超时时间,为了测试效果,这里用了十秒钟
server.servlet.session.timeout=10s
这样便完成了监听器对session的在线离线状况的监控!
我真是太勤勉了,晚安!