同一用户名限制本机或多台机器同时登陆的设想及实现

先贴代码:

1、用户常用操作工具类,包括在session、上下文中设置、清除数据

package com.qytx.util;

import java.util.HashMap;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;

import com.qytx.modle.User;

/**
 * 操作当前用户
 * 
 * @author 开拓者
 * 
 */
public class CurrentUserUtils {
	/**
	 * SESSION中用户的session标示
	 */
	public static final String CURRENT_SESSION_USER = "user";
	/**
	 * 用用中存储的用户数据标示
	 */
	public static final String CURRENT_CONTEXT_USER = "CURRENT_CONTEXT_USER";

	/**
	 * 存储session中的用户数据
	 * 
	 * @param session
	 * @param user
	 *            用户对象
	 */
	public static HttpSession setCurrentSessionUser(HttpSession session,
			User user) {
		session.setAttribute(CURRENT_SESSION_USER, user);
		return session;
	}

	/**
	 * 获取当前session中的用户对象
	 * 
	 * @param session
	 * @return User
	 */
	public static User getCurrentSessionUser(HttpSession session) {
		return (User) session.getAttribute(CURRENT_SESSION_USER);
	}

	/**
	 * 清除session中的当前登录用户数据
	 * 
	 * @param session
	 */
	public static void clearCurrentSessionUser(HttpSession session) {
		// session.removeAttribute(CURRENT_SESSION_USER);
		session.invalidate();
	}

	/**
	 * 清除session中的已经登录用户数据
	 * 
	 * @param session
	 */
	public static void clearAlreadyLoginUser(ServletContext context,
			String userName) {

		// 清除应用中已登录的数据
		HashMap<String, HttpSession> map = CurrentUserUtils
				.getCurrentServletContextUser(context);
		if (null != map) {
			HttpSession session = map.get(userName);
			session.removeAttribute(CURRENT_SESSION_USER);
			session.invalidate();

			map.remove(userName);

		}

	}

	/**
	 * 在应用级别存储用户数据
	 * 
	 * @param context
	 * @param userName
	 * @param session
	 */
	public static void setCurrentServletContextUser(ServletContext context,
			User user, HttpSession session) {
		HashMap<String, HttpSession> userMap = new HashMap<String, HttpSession>();
		userMap.put(user.getUserName(), session);

		context.setAttribute(CURRENT_CONTEXT_USER, userMap);
	}

	/**
	 * 取得上下文中的用户数据
	 * 
	 * @param context
	 * @return HashMap<String, User>
	 */
	@SuppressWarnings("unchecked")
	public static HashMap<String, HttpSession> getCurrentServletContextUser(
			ServletContext context) {
		return (HashMap<String, HttpSession>) context
				.getAttribute(CURRENT_CONTEXT_USER);
	}

	/**
	 * 清除应用中已存在的数据
	 * 
	 * @param context
	 */
	public static void clearCurrentServletUser(ServletContext context) {
		context.removeAttribute(CURRENT_CONTEXT_USER);
	}

}

 2.登陆过滤器,内含需要排除的页面

package com.qytx.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.qytx.modle.User;
import com.qytx.util.CurrentUserUtils;

public class LoginFilter implements Filter {

	private final static String[] eixt_url = { "index.jsp", "logout.jsp",
			"logout.html", "login_admin.action", "login_user.action",
			"regist.jsp", "regist.action", "get_code.action", "rule.jsp",
			"findpasswd.jsp", "find.action", "logout.action",
			"login_admin.jsp", "login_user.jsp","email.action", "/js", "/css", "/images" }; // 不用做权限判断的URL

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws ServletException, IOException {

		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		boolean haveFind = true;
		// System.out.println("req.getRequestURI()==="+req.getRequestURI());

		if (req.getRequestURI().indexOf(".jsp") >= 0
				|| req.getRequestURI().indexOf(".action") >= 0)
			haveFind = false;

		for (int i = 0; i < eixt_url.length; i++) {
			if (req.getRequestURI().indexOf(eixt_url[i]) >= 0) {
				haveFind = true;
				break;
			}
		}

		// System.out.println("haveFind==="+haveFind);

		User user = CurrentUserUtils.getCurrentSessionUser(req.getSession());
		System.out.println("Current login user:" + user + ","
				+ req.getSession().getId());
		if (!haveFind && null == user) {
			res.sendRedirect("/logout.jsp");
			System.out.println("----redirect----");
			return;
		}
		chain.doFilter(req, res);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}

	public void destroy() {
	}

}

3.监听session失效时的工具类,即调用invilate()方发时

package com.qytx.util;

import java.io.Serializable;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import com.qytx.modle.User;

/**
 * session销毁时移除应用中的用户,用于非正常退出时监测session的销毁
 * 
 * @author 开拓者
 * 
 */
@SuppressWarnings("serial")
public class OnlineUserListener implements HttpSessionListener, Serializable {

	public void sessionCreated(HttpSessionEvent event) {
	}

	public void sessionDestroyed(HttpSessionEvent event) {
		HttpSession session = event.getSession();
		User user = CurrentUserUtils.getCurrentSessionUser(session);

		if (null != user) {
			CurrentUserUtils.clearAlreadyLoginUser(session.getServletContext(),
					user.getUserName());
		}

		System.out.println("超时退出。");
	}

}
4.

4.登陆实现代码片段

ServletContext context = ServletActionContext
						.getServletContext();
				// 取得应用中的用户数据
				HashMap<String, HttpSession> userMap = CurrentUserUtils
						.getCurrentServletContextUser(context);
				// 判断当前登录的用户数据在应用中是否已经存在
				if (null != userMap) {
					Iterator<Entry<String, HttpSession>> iterator = userMap
							.entrySet().iterator();
					Collection<String> userNames = new ArrayList<String>();
					while (iterator.hasNext()) {
						Entry<String, HttpSession> entry = iterator.next();
						String key = entry.getKey();
						if (null != key) {
							userNames.add(key);
						}
						if (userNames.contains(userInfo.getUserName())) {
							CurrentUserUtils.clearAlreadyLoginUser(context,
									userInfo.getUserName());
						}
						break;
					}

				}

				// 登录后将用户数据放入session
				HttpSession session = CurrentUserUtils.setCurrentSessionUser(
						ServletActionContext.getRequest().getSession(),
						userInfo);

				// 登录后将用户数据放入context
				CurrentUserUtils.setCurrentServletContextUser(context,
						userInfo, session);

你可能感兴趣的:(同一用户名限制本机或多台机器同时登陆的设想及实现)