网上有很多关于重复登录的文章,我总结了一下,然后根据自己的业务做了一个:但是我觉得应该还有更好的解决办法
如果有同志有其他的办法的话欢迎留言哦!
原理也很简单:首先需要实现一个Session监听类SessionListener 使用HttpSessionListener接口实现 sessionCreated 和 sessionDestroyed方法:记得需要写上@WebListener注解
@WebListener
public class SessionListener implements HttpSessionListener {
public static boolean isExpired = false;
public static SessionManagement sessionManagement = SessionManagement.getInstance();
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("------------ sessionCreated");
//session被创建 添加到HashMap
sessionManagement.addSession(httpSessionEvent.getSession().getId(), httpSessionEvent.getSession());
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("------------ sessionDestroyed");
isExpired = true; //标记 判断session是否过期
sessionManagement.removeSession(httpSessionEvent.getSession().getId());
}
}
第二步:创建一个Session管理类SessionManagement 和 HashMap<string, HttpSession>
public class SessionManagement {
private static SessionManagement sessionManagement;
private HashMap<String, HttpSession> sessionHashMap;
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //线程同步
private SessionManagement() {
sessionHashMap = new HashMap<>();
}
public static SessionManagement getInstance() {
if (sessionManagement == null) {
sessionManagement = new SessionManagement();
}
return sessionManagement;
}
public void addSession(String id, HttpSession httpSession) {
readWriteLock.writeLock().lock();
try {
if (httpSession != null && id != null && id.length() > 0) {
sessionHashMap.put(id, httpSession);
}
} finally {
readWriteLock.writeLock().unlock();
}
}
public void removeSession(String id) {
readWriteLock.writeLock().lock();
try {
if (id != null && id.length() > 0) {
sessionHashMap.remove(id);
}
} finally {
readWriteLock.writeLock().unlock();
}
}
public HttpSession getSession(String sessionId) {
readWriteLock.readLock().lock();
try {
if (sessionId == null) {
return null;
}
return sessionHashMap.get(sessionId);
} finally {
readWriteLock.readLock().unlock();
}
}
public HashMap<String, HttpSession> getSessionHashMap() {
return sessionHashMap;
}
public void setSessionHashMap(HashMap<String, HttpSession> sessionHashMap) {
this.sessionHashMap = sessionHashMap;
}
}
第三:在登录接口处理业务逻辑
//已登录 && session未过期
HttpSession session_old = SessionManagement.getInstance().getSession(userID);
if (!SessionListener.isExpired && session_old != null) {
//强制过期
session_old.invalidate();
SessionManagement.getInstance().removeSession(String.valueOf(accountEntity.getId()));
//更新 -- 将sessionId 更换为 userID
SessionManagement.getInstance().removeSession(session.getId());
SessionManagement.getInstance().addSession(String.valueOf(userID), session);
}
//未登录
else {
HttpSession session_admin = SessionManagement.getInstance().getSession(session.getId());
if (session_admin == null) {
throw new ControllerException("业务异常");
}
//替换id - session
SessionManagement.getInstance().addSession(userID), session_admin);
SessionManagement.getInstance().removeSession(session.getId());
}
这样可以实现效果。如果有更好的办法欢迎大家留言 大家一起交流。