大概就是要像QQ一样的,同一账号在另一地点登录后,原先登录的就被迫下线,要怎么实现呢?希望大家给点建议!

解决方案 »

  1.   

    记录ip+账号+最后操作时间,组合成对象,装在application里
    如果出现了同样账号,不同IP,且操作时间间隔小于n秒的情况,把前一个的对象从这里抹去,下次再操作时就找不到对象,提示他自动登出了。
    不过这似乎可能会涉及到竞争资源的问题。
      

  2.   

    我之前做的权限判断都只是用session,假如用户登录成功后就
    request.getSession.setAttribute("username",username);
     如何实现你说的将信息组合成对象放到application中呢?
      

  3.   


    你可以使用一个sessionMap<String,HttpSession> 使用用户ID作为key 
      

  4.   

    在数据库写入一个字段lastlogintime.登陆的时候时间数据写入session..一段时间和数据库验证一下..如果不同自动登陆!
      

  5.   

    在applicationContext里面方一个Map,key为账户id,value为session。
    用户在登录的时候,应在session里存上该账户id,以做为该用户已经登录的标记,并在applicationContext的Map里面利用contains()方法来判断Map里面是否已经包含了此id的key,如果包含了,则把value(即session)取出,从这个session里面将记录的账户id删除,然后把新的session存进Map。
    这样原来的那个session里就没有账户id了,也就相当于原来登录的那个用于从登录状态转为了未登录状态。对于如果一个人在同一客户端使用同一账号登陆两次,这个我们不用考虑,因为一个客户端使用的是一个session,在登录的action里面我们本来就要判断session里是否已经含有账户id,如果有,上面那段操作无需执行,并且告知用户已经登录(即转到一个告知的页面,或使用其他途径)。难点在于这还没完,我们还要告诉原来登录的那个用户,“已经有人使用此账号在他处登录!”这么一个消息,这就有困难,没有request哪来responce啊?这个时候就要使用JS了,用JS写一个函数,该函数定时的向服务器发送请求(即使用了AJAX),并接受返回信息,如果接受到的返回信息文本是"false"或其他具有标识性的字符串,则表明有人在他处使用同一账号登录,即刻将浏览器跳转到其他页面,或弹出个警告框后再跳转。这个功能看起来似乎很简单,实现起来不是几行代码就能搞定的!
    不知道大家有没有更好的方法!
      

  6.   

    登陆的时候,把登陆信息的SESSION放到一个静态变量里面(比如HASHMAP),然后每次登陆,都和HASHMAP里面的值比较,如果相同,则把原来的SESSION清空,跳转到登陆页面。中间采用一个过滤器。
      

  7.   

    一个比较原始的方法,用IFRAME引入一个页面,用JS写一个定时刷面页面的方法.再把SESSION 和数据库交互的的方法写在页面里面,据结果考虑登陆或登出!
    当然如果你用struts等框架的话,就写在类里面通过js引发action.原理同上
      

  8.   

    session无法完成这样的事,客户登录后就有一个自己的session,应该存到application变量里面这样才能共享到。
      

  9.   

    http://www.lifeispig.cn/article.asp?id=127 这有一个用STRUTS2做的.不知道对你有帮助吗?
      

  10.   

    将已登录信息持久化或者放入application中,新请求用户访问的时候首先判断application中或者持久化(数据库)中有没有这个用户,如果有,清除即可。
      

  11.   

    很感谢各位提出的建议,对我启发很大!尤其是11楼的shanhenvgui说的很详细,还有gm66589160的iframe的方法,我也很有启发!我先试着弄弄,看看其他人还有什么看法么?
      

  12.   

    监听器package filter;import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;import vo.UsersInfo;public class SsoFilter implements Filter {
    private static final String PARAM_PWD = "pwd"; // request发来的参数
    private static final String PARAM_UID = "uid";
    private static final String USERS_MAP = "userList"; // application中保存的用户列表
    private static final String USER_INFO = "userInfo"; // session中保存用户时,作键
    private static final String MSG = "msg"; // request中保存提示信息时,作键
    // private static final String MSG_USEING = "该账号正在使用中"; // 提示信息的值
    private static final String MSG_NOTLOGIN = "您尚未登录";
    private static final String MSG_BADLOGIN = "用户名或密码出错";
    private static final String JSP_MAIN = "main.jsp"; // 重定向的页面
    private static final String JSP_LOGIN = "login.jsp"; private HttpServletResponse response = null; // response
    private HttpServletRequest request = null; // request
    private HttpSession session = null; // session
    private ServletContext application = null; // application public void doFilter(ServletRequest arg0, ServletResponse arg1,
    FilterChain arg2) throws IOException, ServletException {
    // 初始化三个参数
    request = (HttpServletRequest) arg0;
    response = (HttpServletResponse) arg1;
    session = request.getSession(); // 1.session已登录,则可以到任何页面
    if (session.getAttribute(USER_INFO) != null) {
    arg2.doFilter(arg0, arg1);
    } else {
    // 2.1尝试登录
    if (request.getRequestURI().indexOf(JSP_MAIN) != -1) {
    tryLogin();
    } else {
    // 2.2尝试越权访问,前往登录页
    request.setAttribute(MSG, MSG_NOTLOGIN);
    request.getRequestDispatcher(JSP_LOGIN).forward(arg0, arg1);
    }
    }
    } /**
     * 尝试登录
     */
    private void tryLogin() throws ServletException, IOException {
    String uid = request.getParameter(PARAM_UID);
    String pwd = request.getParameter(PARAM_PWD); // 直接访问主界面,视为未登录,返回登录页
    if (uid == null || pwd == null || uid.equals("") || pwd.equals("")) {
    request.setAttribute(MSG, MSG_BADLOGIN);
    request.getRequestDispatcher(JSP_LOGIN).forward(request, response);
    return;
    } // 尝试登录
    boolean b = uid.equals(pwd);
    if (b) {
    saveUserVariable(uid);
    request.getRequestDispatcher(JSP_MAIN).forward(request, response);// 登录成功,主界面
    } else {
    request.setAttribute(MSG, MSG_BADLOGIN); // 用户名或密码出错
    request.getRequestDispatcher(JSP_LOGIN).forward(request, response);// 登录失败,登录页
    }
    } // 登录成功,两个步骤
    // 1. session中保存用户身份 [key:USER_INFO, value:u]
    // 2. 更新application中的[在线用户列表]
    @SuppressWarnings("unchecked")
    private void saveUserVariable(String uid) {
    // 1.1
    UsersInfo u = new UsersInfo(request.getRemoteAddr(), 
    uid,
    session.getId());
    session.setAttribute(USER_INFO, u);
    session.setMaxInactiveInterval(9000000); // 1.2
    Map<String, HttpSession> map = application.getAttribute(USERS_MAP) == null 
    ? new HashMap<String, HttpSession>()
    : (Map<String, HttpSession>) application.getAttribute(USERS_MAP);
    // 先判断是否有相同的人已经登陆了,如果有就把已经登陆的Session注销
    if (map.size() > 0 && map.containsKey(uid)) {
    map.remove(uid).invalidate();
    }
    map.put(uid, session);
    application.setAttribute(USERS_MAP, map);
    }// /**
    //  * 是否已存在该用户的登录
    //  * 
    //  * @return
    //  */
    // @SuppressWarnings("unchecked")
    // private boolean isExist() {
    // // 表单中的用户名
    // String uid = request.getParameter(PARAM_UID);
    // // application中,用户名表列表
    // Set set = (Set) application.getAttribute(USERS_MAP) == null ? new HashSet()
    // : (Set) application.getAttribute(USERS_MAP);
    //
    // if (set.contains(uid)) {
    // request.setAttribute(MSG, MSG_USEING);
    // return true;
    // } else {
    // return false;
    // }
    // } /**
     * 初始化,赋值application
     */
    public void init(FilterConfig config) throws ServletException {
    this.application = config.getServletContext();
    } public void destroy() {
    }
    }
      

  13.   

    楼上的乱七八糟的刷屏啊。我给楼主的方案。通过Session的监听类 ,获取用户的登出,登入,把登入的用户信息  通过 用户编号 和 sessionId 两个值放到HashMap 中,可以存到 application中,也可以放到静态变量里面。当用户登出的时候,就把登陆信息从 HashMap中移除。等用户登入的时候,把用户编号和sessionId 压入 HashMap中,那么已登录的用户的SessionId就会被覆盖掉。然后你做个过滤器,在过滤器里面,获取当前的Session信息,到HashMap里面获取 用户信息,然后比对SessionId是否一致,如果不一致,说明已经有新的登录了,就把这个Session删除,也就是踢出这丫的了。
      

  14.   

    这个问题很好解决其实,用户登录之后session中把用户名和sessionid保存起来,当再次登陆的时候判断这个用户凭是否存在以保存的列表中,如果不存在那么久登录,如果存在说明已经有人用这个账户登录,那么删除之前的sessionid,那么之前的就推出了
      

  15.   

    http://download.csdn.net/source/1525256我上传的一个JSP实例,里面有类似你说的功能,不过他只能不同用户不能重复登录,不能把之前那个登录得挤下去,只能是后面一个不能登录,使用监听器实现的