Session的监听以及单点登录整合

本文介绍了一个用于跟踪和管理网站在线用户的Java监听器实现。通过维护一个包含所有活动HTTP会话的列表,并利用ServletContext来存储这些会话,可以有效地监控在线用户数量。此外,还提供了根据用户名检查重复登录的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class OaSessionListener implements HttpSessionListener {

	/** 存储session的map对应的key */
	private static final String KEY_SESSIONS = "onlineUserList";

	// 保存UserName和sessionId的映射
	private static HashMap<String, String> OnlineUserMap = new HashMap<>();

	@Override
	public void sessionCreated(HttpSessionEvent event) {
		HttpSession session = event.getSession();
		ServletContext application = session.getServletContext();

		// 把用户名放入在线列表,在application范围有一个List集保存所有的Session
		List<HttpSession> onlineUserList = (List<HttpSession>) application.getAttribute(KEY_SESSIONS);

		// 第一次使用前,需要初始化
		if (onlineUserList == null) {
			onlineUserList = new ArrayList();
			application.setAttribute(KEY_SESSIONS, onlineUserList);
		}
		// System.out.println(session);
		// 新创建的session均添加到List集中
		onlineUserList.add(session);
		// 此时用户未登录,应将session超时时间设置的短一些
		// session.setMaxInactiveInterval(30 * 60);
		System.out.println("当前在线人数:" + onlineUserList.size() + "人");
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent event) {
		HttpSession session = event.getSession();
		ServletContext application = session.getServletContext();
		List<HttpSession> onlineUserList = (List<HttpSession>) application.getAttribute(KEY_SESSIONS);
		if (onlineUserList != null) {
			// 销毁的session均从List中移除
			onlineUserList.remove(session);
			System.out.println("用户退出或登录超时之后用户在线人数:" + onlineUserList.size() + "人");
		}
	}

	/**
	 * TODO 根据sessionId从上下文中获取session对象
	 * 
	 * @author Palm
	 * @date 2016年7月29日
	 * @param application
	 * @param sessionId
	 * @return
	 */
	private static HttpSession getSessionWithId(ServletContext application, String sessionId) {
		// 把用户名放入在线列表,在application范围有一个List集保存所有的Session
		List<HttpSession> onlineUserList = (List<HttpSession>) application.getAttribute(KEY_SESSIONS);
		if (onlineUserList == null)
			return null;
		for (HttpSession session : onlineUserList) {
			if (!session.getId().equals(sessionId))
				continue;
			return session;
		}
		return null;
	}

	/**
	 * TODO 用于判断用户是否已经登录以及相应的处理方法
	 * 
	 * @author Palm
	 * @date 2016年7月27日
	 * @param session
	 *            用户登录时的session
	 * @param sUserName
	 *            登录的用户名称
	 * @return true-用户已登录,释放之前的session <br/>
	 *         false - 新用户登录
	 */
	public synchronized static boolean updateOnlineUserMap(HttpSession session, String sUserName) {
		// synchronized (sUserName) {
		// 如果该用户已经登录过,则使上次登陆的用户掉线
		if (OnlineUserMap.containsKey(sUserName)) {
			// 释放之前的session
			String oldSessionId = OnlineUserMap.get(sUserName);
			//同一个客户端多次登录
			if(oldSessionId.equals(session.getId())){
				System.out.println("用户重复登录:" + sUserName + ":" + session.getId());
				return true;
			}
			HttpSession oldSession = getSessionWithId(session.getServletContext(), oldSessionId);
			if (oldSession != null)
				oldSession.invalidate();

			// 更新map中当前用户对应的sessionId换成最新的
			OnlineUserMap.put(sUserName, session.getId());
			System.out.println("用户重复登录:" + sUserName + ":" + session.getId());
			return true;
		} else {// 如果用户没有登录过,直接添加到现在的SessionID和userName
			// flag = false;
			OnlineUserMap.put(sUserName, session.getId());
			// System.out.println("hUserName =" + OnlineUserMap);
			System.out.println("用户登录:" + sUserName + ":" + session.getId());
		}
		return false;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值