session 之session混乱解决方法

知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:

1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);

2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?

3、如何限制不同的用户在同一台机器上登陆系统?

4、管理员如何踢人?

我们首先来分析上面的问题:

首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的IDsession对象。(记住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 users = null;





	private OnLineUserManager() {

		users = new Vector();//在构造函数中初始化

	}

	

	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 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;// 最后访问时间



}

你可能感兴趣的:(java,session,string,interceptor,服务器,class,struts)