session 之session混乱解决方法(转)
知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:
1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);
2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?
3、如何限制不同的用户在同一台机器上登陆系统?
4、管理员如何踢人?
我们首先来分析上面的问题:
首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的ID,session对象。(记住session的ID极其重要,因为服务器识别session是根据id,只要id相同,服务器就认为是同一个用户);
(上面解决了问题1)
这样当用户登陆系统的时候我们首先根据帐号判断用户是否登陆了,如果已经登陆,提示用户;(这样就解决了问题2)
如果未登陆,判断用户的session的id是否已经在用户的信息OnLineUserManager里面了,如果是提示用户
关闭当前窗口,重新点击IE打开一个新的浏览器窗口。(这样session就不会混乱了)。
如果要限制不同的用户在同一台机器上登陆系统?这个就要根据IP地址来判断了。如果OnLineUserManager中
有通过这个机器登陆系统的用户,那么就提示用户同一台机器只能够一个帐号登陆;
(问题3也就解决了,注意:如果用户使用了代理服务器,那么此方法失效。这个方法适用于管理规范的用户,客户在局域网内使用,每个客户有固定的ip。)
问题4如何踢人?你想想OnLineUserManager中记录了用户session对象,只要根据用户的帐号找到对应的
session对象,然后session.invalidate();这样就可以彻底的将捣乱的人提出系统了。
===============需要注意的是OnLineUserManager必须是线程安全的=我的实现如下==============
- package com.work.qxgl.login;
- import java.util.Vector;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import com.work.util.DateUtil;
- /**
- * 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。
- * TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制!
- * 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录!
- *
- * @author wangmingjie
- *
- */
- public class OnLineUserManager {
- private static Log log = LogFactory.getLog(OnLineUserManager.class);
- private Vector<OnLineUser> users = null;
- private OnLineUserManager() {
- users = new Vector<OnLineUser>();//在构造函数中初始化
- }
- static class SingletonHolder {
- static OnLineUserManager instance = new OnLineUserManager();
- }
- /**
- * 单例模式。这样简单而且能够保证线程安全。
- *
- * @return
- */
- public static OnLineUserManager getInstance() {
- return SingletonHolder.instance;
- }
- /**
- * 获取到登录用户的数量。
- *
- * @return
- */
- public synchronized int getCount() {
- users.trimToSize();
- return users.capacity();
- }
- /**
- * 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。
- *
- * @param userAccount
- * @return
- */
- public synchronized boolean existUser(String userAccount) {
- users.trimToSize();
- boolean existUser = false;
- for (int i = 0; i < users.capacity(); i++) {
- if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
- existUser = true;
- break;
- }
- }
- return existUser;
- }
- /**
- * @param sessionid
- * @return
- */
- public synchronized boolean existSession(String sessionid) {
- users.trimToSize();
- boolean existUser = false;
- for (int i = 0; i < users.capacity(); i++) {
- if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {
- existUser = true;
- break;
- }
- }
- return existUser;
- }
- /**
- * 删除用户
- *
- * @param userAccount
- * @return
- */
- public synchronized boolean deleteUser(String userAccount) {
- users.trimToSize();
- if (existUser(userAccount)) {
- int currUserIndex = -1;
- for (int i = 0; i < users.capacity(); i++) {
- if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
- currUserIndex = i;
- break;
- }
- }
- if (currUserIndex != -1) {
- users.remove(currUserIndex);
- users.trimToSize();
- log.debug("用户" + userAccount + "退出系统"
- + DateUtil.getCurrentDateTime());
- log.debug("在线用户数为:" + getCount());
- return true;
- }
- }
- return false;
- }
- /**
- * 根据用户帐号,获取在线用户信息
- * @param userAccount
- * @return
- */
- public synchronized OnLineUser getUser(String userAccount) {
- users.trimToSize();
- if (existUser(userAccount)) {
- int currUserIndex = -1;
- for (int i = 0; i < users.capacity(); i++) {
- if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {
- currUserIndex = i;
- break;
- }
- }
- if (currUserIndex != -1) {
- return users.get(currUserIndex);
- }
- }
- return null;
- }
- /**
- * 获取到在线用户的信息。
- *
- * @return
- */
- public synchronized Vector<OnLineUser> getOnLineUser() {
- return users;
- }
- public synchronized void addUser(OnLineUser onLineUser) {
- users.trimToSize();
- if (!existUser(onLineUser.getUserAccount())) {
- users.add(onLineUser);
- log.debug(onLineUser.getUserAccount() + "/t登录到系统/t" + DateUtil.getCurrentDateTime());
- // 通过request才能够获取到用户的ip等信息
- } else {
- log.debug(onLineUser.getUserAccount() + "已经存在");
- }
- log.debug("在线用户数为:" + getCount());
- }
- }
==================OnLineUser.java============================
- package com.work.qxgl.login;
- import java.io.Serializable;
- import javax.servlet.http.HttpSession;
- /**
- * @author wangmingjie
- * @date 2008-6-30下午04:56:37
- */
- public class OnLineUser implements Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 5461473880667036331L;
- private String userId; //用户id
- private String userAccount; //用户帐号
- private String userName; //用户名称
- private String loginTime; //登陆时间戳
- private String sessionId; //session的ID
- private String userIp ;//ip地址
- private HttpSession session; //记住session对象,测试能否用来将人员踢出系统
- public String getUserId() {
- return userId;
- }
- public void setUserId(String userId) {
- this.userId = userId;
- }
- public String getUserAccount() {
- return userAccount;
- }
- public void setUserAccount(String userAccount) {
- this.userAccount = userAccount;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public String getSessionId() {
- return sessionId;
- }
- public void setSessionId(String sessionId) {
- this.sessionId = sessionId;
- }
- public String getUserIp() {
- return userIp;
- }
- public void setUserIp(String userIp) {
- this.userIp = userIp;
- }
- public HttpSession getSession() {
- return session;
- }
- public void setSession(HttpSession session) {
- this.session = session;
- }
- public String getLoginTime() {
- return loginTime;
- }
- public void setLoginTime(String loginTime) {
- this.loginTime = loginTime;
- }
- public String toString(){
- return "OnLineUser{userId="+userId+",userAccount="+userAccount
- +",userName"+userName+",loginTime="+loginTime+",userIp="+userIp+",sessionId="+sessionId+"}";
- }
- //===============下面的数据只有在系统登陆日期中记录==================================
- // private String logoutTime;//退出时间戳;
- // private String logoutType;//退出方式 “session超时退出”;“1主动退出”
- // private String lastAccessedTime;// 最后访问时间
- }
session 之session混乱解决方法(转)的更多相关文章
- hibernate中一种导致a different object with the same identifier value was already associated with the session错误方式及解决方法
先将自己出现错误的全部代码都贴出来: hibernate.cfg.xml <?xml version="1.0" encoding="UTF-8"?> ...
- Response.Redirect("x.aspx);跳转后session为null的解决方法
通常我们做登陆的时候都是登录成功后为管理员保存一些信息,一般都会写类似下面的代码 if(登录成功) { Session["xx"] = "user"; Resp ...
- php在客户端禁用cookie时让session不失效的解决方法
cookie固然好,不过有些客户端浏览器会禁用cookie,这就会导致你所依赖cookies的程序会失效或出错,那么若真出现用户关闭cookies的情况,PHP应该如何再次使用session?方法还是 ...
- php 不能取得session值的一个解决方法
1.确认下<?php session_start(); ?> 这句话是不是在<HTML> 标志之前. 不在的话,请放到<HTML> 标志之前. 2.如果上面操作后 ...
- session阻塞机制,解决方法
session从生成到读取,或从生成到写入都出现锁定的情况. 1.session_start();session_commit(); 2.session_start();session_write_c ...
- 重启tomcat但是session仍然有效的解决方法
参考:http://www.blogjava.net/freeman1984/archive/2010/03/30/316901.html server.xml,在你的webapp的Context节点 ...
- hibernate open session in view 抛出异常解决方法
在使用open-session-in-view的时候,如果使用不当,有可能抛出两种异常1,NonUniqueObjectException2,在配合spring使用的时候会可能会抛出org.sprin ...
- 网站启动SSL, http变为https后,session验证码错误解决方法
网站启动SSL, http变为https后,session验证码错误解决方法 最近公司需要后台启动安全证书,证书安装完毕后,后台老提示 验证码错误,经过几天的研究,此问题已经得到有效解决,现把方法 ...
- session在本地可以正常使用,而在sae上却无法使用或者值为空的解决方法
session在本地可以正常使用,而在sae上却无法使用或者值为空的解决方法: session_start()放在当前页代码的第一行即可解决该问题. 在本地上session_start()如果不是放在 ...
随机推荐
- Spring Boot的listener简单使用
监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public ServletListene ...
- log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.o
上面的报错是在本地java调试(windows) hadoop集群 出现的 解决方案: 在resources文件夹下面创建一个文件log4j.properties(这个其实hadoop安装目录下的 e ...
- [转]ASP.NET Core 十种方式扩展你的 Views
http://www.cnblogs.com/savorboard/p/aspnetcore-views.html
- 【jQuery源码】jQuery对象初始化
看了一下午还是有很多地方没弄明白,jQuery的一些工具方法的原理也不完全清楚,这篇文章会随着我深入阅读jQuery源码的同时不断更新. // Initialize a jQuery object / ...
- 数据库学习---SQL基础(二)
数据库学习---SQL基础(一) 数据库学习---SQL基础(二) 数据库学习---SQL基础(三) 上篇复习的sql的增删改查,and ,or ,>=, <=,!=等逻辑运算符,还有in ...
- 机器学习--boosting家族之XGBoost算法
一.概念 XGBoost全名叫(eXtreme Gradient Boosting)极端梯度提升,经常被用在一些比赛中,其效果显著.它是大规模并行boosted tree的工具,它是目前最快最好的开源 ...
- Global Embedding 理解
1.Attention-based seq2seq e(t,i):求上一时刻的输出和这一时刻编码器的输出的相似度 a(t,i):求这个词在整个文本中占多大的比重,每个时刻都存在着一个值,这个只是求一个 ...
- Ceph 块设备 - 命令,快照,镜像
目录 一.Ceph 块设备 二.块设备 rbd 命令 三.操作内核模块 四.快照基础 rbd snap 五.分层快照 六.镜像 rbd mirror 七.QEMU 八.libvirt 九.Openst ...
- 玩转mongodb(六):索引,速度的引领(普通索引篇)
数据库索引与书籍的索引类似,有了索引就不需要翻整本书,数据库可以直接在索引中查找,在索引中找到条目后,就可以直接跳到目标文档的位置,这可以让查找的速度提高几个数量级. 一.创建索引 我们在person ...
- IOS bug之cannot be opened because the project file cannot be parsed
刚才用Cornerstone更新代码后,再次打开项目时,不能打开,提示cannot be opened because the project file cannot be parsed后来在网上查了 ...