用到的技术: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#
浙公网安备 33010602011771号