java-web - JavaWeb 如何设计用户多个浏览器登陆时只有最新的登陆的有效
ringa_lee
ringa_lee 2017-04-18 09:25:30
[Java讨论组]

例如用户在A浏览器上登陆了,然后用手机打开B浏览器又登陆了,要让A浏览器上的用户退出(用户再次操作时提示登陆即可)
我的设计如下,这样设计有什么问题吗?因为有时候会报错

java.lang.IllegalStateException: getAttribute: Session already invalidated

我的代码:

    //登陆方法
    private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        //验证用户通过
        ....
        //判断当前用户是否已经登陆,如果已经登陆,清掉之前的登陆信息(上次登陆失效);
        if(isAlreadyLogin(user.getId(),request)){
            Map sessionMap = (Map)request.getServletContext().getAttribute("sessionMap");
            try {
                sessionMap.get(user.getId()).removeAttribute("userID");**//这句报错**
                sessionMap.get(user.getId()).removeAttribute("user");
            } catch (Exception e) {
                // TODO Java.lang.IllegalStateException: getAttribute: Session already invalidated
            }
        }
        //登陆成功 ,设置session 
        request.getSession(true).setAttribute("user", user);
        request.getSession(true).setAttribute("userID", user.getId());
        addSessionToMap(user.getId(), request);
        ....
    }
    
    //退出方法
    private void logOut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String userId = (String)request.getSession().getAttribute("userID");
        removeSessionToMap(userId,request);
        request.getSession().removeAttribute("userID");
        request.getSession().removeAttribute("user");
        //返回信息
        ......
    }
    
    /**
     * 判断用户是否已经登录
     */
    private static boolean isAlreadyLogin(String userId,HttpServletRequest request){
        ServletContext application = request.getServletContext();
        Map sessionMap = (Map)application.getAttribute("sessionMap");
        if(sessionMap==null||sessionMap.get(userId)==null){
            return false;
        }
        return true;
    }

    private static void addSessionToMap(String userId,HttpServletRequest request){
        ServletContext application = request.getServletContext();
        Map sessionMap = (Map)application.getAttribute("sessionMap");
        if(sessionMap==null){
            sessionMap = new HashMap();
        }
        sessionMap.put(userId, request.getSession());
        application.setAttribute("sessionMap", sessionMap);
    }
    
    private static void removeSessionToMap(String userId,HttpServletRequest request){
        ServletContext application = request.getServletContext();
        Map sessionMap = (Map)application.getAttribute("sessionMap");
        if(sessionMap==null){
            sessionMap = new HashMap();
        }
        sessionMap.remove(userId);
        application.setAttribute("sessionMap", sessionMap);
    }

请大牛指教,谢了。

ringa_lee
ringa_lee

ringa_lee

全部回复(3)
PHP中文网

可以redis来存储token.key为userId,value是token,之后只要每次检查userId和token是否可以对上就行了.

阿神

你好!我同意HelloWorld的说法,你的session失效了,并不是说你的代码有问题。我感觉如果你登陆完浏览器1后立即登陆浏览器2,应该没有问题。

高洛峰

最后登录的会话保持有效token,判断请求所带token是否有效即可

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号