JSP+Servlet实现的一个图片分享网站5_避免多处同时登陆

思路

若密码验证成功,在context域(javaweb有四个域,context,session,request,page,范围依次从大到小)中加入一个Map<Integer, HttpSession>类型的map用于储存当前所有在线用户,key为独一无二的UID,value为用户登陆时的session对象。若已经登陆,则把之前的remove,然后再把当前session加入map中。
在登出方法中将改该session移除。

代码

login

//获取当前系统所有的在线用户
Map<Integer,HttpSession> onlineUserList=(Map<Integer, HttpSession>)request.getSession().getServletContext().getAttribute("ONLINE_USERS");
if(onlineUserList==null){
    onlineUserList = new HashMap<>();
}
//如果当前用户存在其他session信息,那么就让旧的session失效,保证同时只有一人登录
HttpSession oldSession=onlineUserList.get(user.getUid());
if(oldSession!=null){
    try {
        oldSession.invalidate();
    } catch (Exception e) {
        System.out.println("session已过期");
        e.printStackTrace();
    }
    onlineUserList.remove(user.getUid());
}
//记录新的session,并记录到所有用户下
onlineUserList.put(user.getUid(), session);
request.getSession().getServletContext().setAttribute("ONLINE_USERS",onlineUserList);

logout

Map<Integer,HttpSession> onlineUserList=(Map<Integer, HttpSession>)request.getSession().getServletContext().getAttribute("ONLINE_USERS");
HttpSession session = request.getSession();
if(onlineUserList != null && session.getAttribute("userDetails") != null){
    User user = (User)session.getAttribute("userDetails");
    onlineUserList.remove(user.getUid());
    session.invalidate();
}

要注意的坑

  • 刚开始没有用try-catch,是因为没有考虑到session过期的情况,默认30分钟无响应则session过期,此时用户没有通过logout按钮退出登录,因此session还在map中,但是这个session其实已经过期了,调用它的invalidate方法就会报错,又没有可以事先判断该session是否过期的方法,所以只能采用暴力且丑陋的try-catch。
  • 由于注册完之后是直接变成登录状态,没有经过正常的login进行登录,导致服务器中有在线用户但是没有那个map,若此时用户点击登出,会产生空指针错误,所以要先判断是否为null。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值