1. 程式人生 > >Session防止重複登入

Session防止重複登入

網上有很多關於重複登入的文章,我總結了一下,然後根據自己的業務做了一個:但是我覺得應該還有更好的解決辦法

如果有同志有其他的辦法的話歡迎留言哦!

原理也很簡單:首先需要實現一個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());
        }
這樣可以實現效果。如果有更好的辦法歡迎大家留言 大家一起交流。