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<String,HttpSession> sessionMap = (Map<String, HttpSession>)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<String,HttpSession> sessionMap = (Map<String,HttpSession>)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<String,HttpSession> sessionMap = (Map<String,HttpSession>)application.getAttribute("sessionMap");
        if(sessionMap==null){
            sessionMap = new HashMap<String,HttpSession>();
        }
        sessionMap.put(userId, request.getSession());
        application.setAttribute("sessionMap", sessionMap);
    }
    
    private static void removeSessionToMap(String userId,HttpServletRequest request){
        ServletContext application = request.getServletContext();
        Map<String,HttpSession> sessionMap = (Map<String,HttpSession>)application.getAttribute("sessionMap");
        if(sessionMap==null){
            sessionMap = new HashMap<String,HttpSession>();
        }
        sessionMap.remove(userId);
        application.setAttribute("sessionMap", sessionMap);
    }

请大牛指教,谢了。

ringa_lee
ringa_lee

ringa_lee

全部回复(4)
PHP中文网

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

阿神

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

PHP中文网

removeAttribute 方法说明

void removeAttribute(java.lang.String name)
Removes the object bound with the specified name from this session. If the session does not have an object bound with the specified name, this method does nothing.
After this method executes, and if the object implements HttpSessionBindingListener, the container calls HttpSessionBindingListener.valueUnbound. The container then notifies any HttpSessionAttributeListeners in the web application.

Parameters:
name - the name of the object to remove from this session
Throws:
IllegalStateException - if this method is called on an invalidated session

很显然session超时失效了,你在失效的session上调用方法就会出现你说的问题了。

高洛峰

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

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

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