Java项目控制用户不能同时登录
目标:控制一个账户不能同时在两个地方登录
最近在练习做一个网上商城的项目,遇到了个问题,就是一个User(账号)可以同时登录,导致账号数据交互异常,就想办法做到一个账户只能在一个地方(session)登录,并且后边登录的顶掉前边的。
想法:通过sessionId来锁定并销毁上一位登录者的session
刚开始整理了一下逻辑思绪,如果想得到账户的登录状态就要在数据库里设置一个变量来储存登陆状态(0或者1),或者把状态存到Application(ServletContext)作用域当中,然后登录方法处理中核对下登录状态,并返回前端相应的值,如果账号无人登录就直接登录,如果有人登录就把上一个登录的session销毁。这是我刚开始的想法,想通过sessionId来销毁某一个session,但是查阅了好多资料都没有找到我想找到的方法。
方法:绑定HttpSessionBindingListener监听器
然后我自己想了个办法,直接让User这个实体类实现HttpSessionBindingListener这个接口就可以
public class User implements HttpSessionBindingListener{
private int id;
private String loginName;
private String userName;
private String password;
private int sex;
private String identityCode;
private String emai;
private String mobile;
private int type;
private int setQuestion;
}
这个监听器的作用大家也肯定都知道,就是当实现这个监听器的实体类实例化出的对象放入session作用域的时候,就会触发valueBound()这个方法。
@Override
public void valueBound(HttpSessionBindingEvent arg0) {
ServletContext servletContext = arg0.getSession().getServletContext();
Object attribute = servletContext.getAttribute(String.valueOf(this.id));
if(attribute==null){
servletContext.setAttribute(String.valueOf(this.id), arg0.getSession());
System.out.println("账号无人登录");
}else{
System.out.println("账号有人登录");
((HttpSession)servletContext.getAttribute(String.valueOf(this.id))).removeAttribute("User");;
servletContext.setAttribute(String.valueOf(this.id), arg0.getSession());
}
}
通过方法传进来的形参arg0得到User被放进的session对象,然后再通过session对象的getServletContext方法得到application对象,我们可以以User的唯一标识符id或者loginame作为键,以当前的session对象为值,放入application作用域中,这是application作用域中就会存储着每个用户id相对应的session对象。
在触发valueBound()方法时,我们可以先试图以User的id作为键从application中获取相对应的session,如果得到的对象为空,此时说明没有人登录此账户。
如果得到的对象不为空,此时说明账号有人登录,我们就将得到的对象强转为session对象,这是就得到了上一位登录者的session对象,将上一位登录者的session中的“User”对象remove掉,并把后登录的session替换掉上一位登录者的session,由此可以实现后登录的顶掉前边登录的。
本人对Java并不是精通,可能此方法在各位大神面前很小儿科,但是我想把问题的一种解决方法分享出来,帮助一些像我一样的初学者。