在springboot中实现同一个用户只能登陆一次 再次登陆顶下上一次登陆的用户
程序员文章站
2024-02-03 11:25:28
...
在springboot中实现同一个用户只能登陆一次 再次登陆顶下上一次登陆的用户
创建session管理器 上下文MySessionContext
public class MySessionContext {
private static MySessionContext context;
private Map<String, HttpSession> map;
private MySessionContext() {
map = new HashMap<>();
}
public static MySessionContext getSessionContext() {
if(context == null) {
context = new MySessionContext();
}
return context;
}
//添加
public synchronized void addSession(HttpSession session) {
if(session!= null) {
map.put(session.getId(), session);
}
}
//获取
public synchronized HttpSession getSession(String sessionId) {
if(sessionId == null) {
return null;
}
return map.get(sessionId);
}
//删除
public synchronized void delSession(HttpSession session) {
if(session!= null) {
map.remove(session.getId());
}
}
//获取map的个数
public synchronized String getSize() {
int size = map.size();
return String.valueOf(size);
}
}
创建session监听器SessionListener
@WebListener
public class SessionListener implements HttpSessionListener {
private MySessionContext context = MySessionContext.getSessionContext();
@Override
public void sessionCreated(HttpSessionEvent e) {
context.addSession(e.getSession());
}
@Override
public void sessionDestroyed(HttpSessionEvent e) {
// System.out.println("移除了sessionid是"+e.getSession().getId()); 删除map中的key value
context.delSession(e.getSession());
Session user = (Session) e.getSession().getAttribute(GlobalConstant.SESSION_NAME);
if (user!=null){
//获取service
GenericService genericService =(GenericService) getObjectFromApplication(e.getSession().getServletContext(),"genericService");
//获取用户的sessionId和用户在线状态
UserInfo tempUser = (UserInfo)genericService.findByid(UserInfo.class, user.getUid());
//如果用户在线且sessionId和e.getSession().getId()相同说明下线,不是更替。
//则修改用户的在线状态和session设置null。
if(tempUser.getOnlinestatus().equals(GlobalConstant.TRUE) && e.getSession().getId().equals(tempUser.getSessionid())) {
tempUser.setOnlinestatus(GlobalConstant.FALSE);
tempUser.setSessionid(null);
genericService.updateOne(tempUser);
/* //如果直接关闭浏览器的话可以直接杀死session 不用写 会直接杀死session的
e.getSession().invalidate();
System.out.println("session杀死了");*/
}
}
// context.delSession(e.getSession());
}
private Object getObjectFromApplication(ServletContext servletContext, String beanName){
//通过WebApplicationContextUtils 得到Spring容器的实例。
ApplicationContext application= WebApplicationContextUtils.getWebApplicationContext(servletContext);
//返回Bean的实例。
return application.getBean(beanName);
}
}
创建session的配置文件SessionConfiguration
@Configuration
public class SessionConfiguration extends WebMvcConfigurerAdapter{
//注册session监听器;
@Bean
public ServletListenerRegistrationBean<SessionListener> servletListenerRegistrationBean() {
ServletListenerRegistrationBean<SessionListener> slrBean = new ServletListenerRegistrationBean<SessionListener>();
slrBean.setListener(new SessionListener());
return slrBean;
}
}
调用session上下文
@Service("loginService")
public class LoginServiceImpl extends GenericServiceImpl<UserInfo, String> {
@Autowired
private GenericDao genericDao;
private MySessionContext context = MySessionContext.getSessionContext();
@Override
public Session login(String username, String password,HttpSession session) {
//判断账号密码是否正确 返回一个userinfo 对象
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("username", username);
map.put("password", password);
Session ses = new Session();
List<UserInfo> byMoreFiled = genericDao.findByMoreFiled(UserInfo.class, map);
if (byMoreFiled==null||byMoreFiled.size()==0){
return null;
}
UserInfo tempuser = byMoreFiled.get(0);
//删除上一个登录的session tempuser是从数据库中用户表查出来的用户对象 第一次登陆时候 在线状态为false sessionid为 null
if(tempuser.getOnlinestatus().equals(GlobalConstant.TRUE) && tempuser.getSessionid() != null) {
HttpSession oldSession = context.getSession(tempuser.getSessionid());
if(oldSession != null){
oldSession.invalidate();
context.delSession(oldSession);
}
}
tempuser.setOnlinestatus(GlobalConstant.TRUE);
tempuser.setSessionid(session.getId());
//修改用户对象的状态和sessionid置为空
genericDao.update(tempuser);
UserRole uid = (UserRole) genericDao.findByParams(UserRole.class, "uid", byMoreFiled.get(0).getSid());
ses.setRid(uid.getRid());
ses.setUid(byMoreFiled.get(0).getSid());
ses.setUsername(byMoreFiled.get(0).getUsername());
return ses;
}
}
调用的时候添加到类中作为变量引入
private MySessionContext context = MySessionContext.getSessionContext();
在springboot中配置session的自动销毁的时间
#配置的单位是秒
server:
servlet:
session:
timeout: 600s
上一篇: 小程序 wx:if 动态显示布局
下一篇: Request & Reponse学习