java web 限制同一個用戶在不同處登入


用到的技術:map集合,sessionListener監聽器,Fiter過濾器。

實現思路:

  一.利用一個全局的map集合來保存每個用戶sessionID的值的一個集合。一個用戶對應一個sessionID當相同的用戶登錄的時候判斷它在集合總有沒有值。(保存用戶所有登錄記錄)

  二.

    2.1.實現sessionListener在當一個session被銷毀的時候強制移除當前用戶所對應的sessionID

    2.2.實現Fiter來判斷每次請求map集合中是否有值。(實現強制退出)

代碼:代碼是復制別人的,做了些修改。

public class LoginUserMap {
  // ConcurrentHashMap這個集合是線程安全的而且性能方面比hasTable和hasMap都好。在高並發的條件下執行速度更快。
   private static Map<String, String> loginUsers = new ConcurrentHashMap<String, String>();
 
   /**
    * 將用戶和sessionId存入map
    * @param key
    * @param value
    */
   public static void setLoginUsers(String loginId, String sessionId) {
     loginUsers.put(loginId, sessionId);
   }
 
   /**
    * 獲取loginUsers
    * @return
    */
   public static Map<String, String> getLoginUsers() {
     return loginUsers;
   }
 
   /**
    * 根據sessionId移除map中的值
    * @param sessionId
    */
   public static void removeUser(String sessionId) {
     for (Map.Entry<String, String> entry : loginUsers.entrySet()) {
       if (sessionId.equals(entry.getValue())) {
         loginUsers.remove(entry.getKey());
         break ;
       }
     }
   }
 
   /**
    * 判斷用戶是否在loginusers中
    * @param loginId
    * @param sessionId
    * @return
    */
   public static boolean isInLoginUsers(String loginId, String sessionId) {
     return (loginUsers.containsKey(loginId) && sessionId.equals(loginUsers.get(loginId)));
   }
 
}
//登錄方法所在的地方
public void login(ttpServletRequest request) {
   try
       ...... //一系列登錄的方法
       HttpSession session = request.getSession();
       LoginUserMap.setLoginUsers(username, session.getId()); //保存sessionId到map中
     } catch (LoginException ex) {
       throw ex;
     }
}
//實現 HttpSessionListener
public class SessionListener implements HttpSessionListener {
   private Log log = LogFactory.getLog(SessionListener. class );
 
   /**
    * 創建session時候的動作
    * @param event
    */
   @Override
   public void sessionCreated(HttpSessionEvent event) {
 
   }
 
   /**
    * 銷毀session時候的動作
    * @param event
    */
   @Override
   public void sessionDestroyed(HttpSessionEvent event) {
     HttpSession session = event.getSession();
     String sessionId = session.getId();
     //移除loginUsers中已經被銷毀的session
     LoginUserMap.removeUser(sessionId);
     log.info(sessionId + "被銷毀!" );
     }
}
//xml配置
< listener >
   < listener-class >....SessionListener</ listener-class >
</ listener >
//實現過濾器
public class LoginLimitFilter implements Filter{
 
   private Log log = LogFactory.getLog(LoginLimitFilter. class );
 
   /**
    * 銷毀時的方法
    */
   @Override
   public void destroy() {
 
   }
 
   /**
    * 過濾請求
    * @param request
    * @param response
    * @param filterChain
    * @throws IOException
    * @throws ServletException
    */
   @Override
   public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain filterChain) throws IOException, ServletException {
     HttpServletRequest servletRequest = (HttpServletRequest) request;
     HttpServletResponse servletResponse = (HttpServletResponse) response;
     HttpSession session = servletRequest.getSession();
 
     //獲取項目路徑
     String path = servletRequest.getContextPath();
     String basePath = servletRequest.getScheme()+ "://" +servletRequest.getServerName()+ ":" +servletRequest.getServerPort()+path;
 
     try {
       //獲取登錄信息
       String loginId = session.getAttribute("yhid")
       //判斷當前用戶的sessionId是否在loginUsers中,如果沒有執行if后的操作
       if (!LoginUserMap.isInLoginUsers(loginId, session.getId())) {
         //當前用戶logout 注:退出登錄最好別用session銷毀的方法。
         logout(); //自己的logout方法
         //調到登錄頁面,並表明退出方式為擠下線
         servletResponse.sendRedirect(basePath + "?logoutway=edge" );
       }
     } catch (Exception e) {
       log.debug( "獲取當前用戶信息失敗,用戶未登陸!" , e);
     } finally {
       filterChain.doFilter(request, response);
     }
   }
 
   /**
    * 初始化方法
    * @param arg0
    * @throws ServletException
    */
   @Override
   public void init(FilterConfig arg0) throws ServletException {
 
   }
 
}
//xml
< filter >
   < filter-name >LoginLimitFilter</ filter-name >
   < filter-class >io.github.brightloong.loginlimite.LoginLimitFilter</ filter-class >
</ filter >
< filter-mapping >
   < filter-name >LoginLimitFilter</ filter-name >
   < url-pattern >/*</ url-pattern >
</ filter-mapping >
//前台頁面js放在首頁就可以了
window.onload = function(){
   if (window.parent != window){
     window.parent.location.href=window.location.href;
   } else {
     if (GetQueryString( 'logoutway' )) {
       alert('該用戶已在其他地方登錄,你已下線');      
       var url = window.location.href;
       window.location.href = url.substr( 0 ,url.indexOf( '?logoutway=edge' ));
    }
   }
}
 
function GetQueryString(name)
{
    var reg = new RegExp( "(^|&)" + name + "=([^&]*)(&|$)" );
    var r = window.location.search.substr( 1 ).match(reg);
    if (r!= null ) return unescape(r[ 2 ]); return null ;
}
 
原文鏈接:http://www.jianshu.com/p/24bc2bb1444e#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM