web项目通过Session监听器控制在线人数以及同一用户异地登陆限制

对于项目中要求控制同时在线人数的需求,可以通过Session监听器来实现。

Session监听器类:

public class UserLoginListener implements HttpSessionAttributeListener
{
    @Override
    public void attributeAdded(HttpSessionBindingEvent se)
    {
        String username = se.getName();
        String sessionId = se.getSession().getId();
        if (username == BaseAction.SESSION_USER)
        {
            new OnlineUserMap().removeUser(sessionId);
            User userInfo = (User) se.getSession().getAttribute(username);
            userInfo.setSessionId(sessionId);
            new OnlineUserMap().addOnlineUser(userInfo.getUserId(), userInfo);
        }

    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se)
    {
        String username = se.getName();
        String sessionId = se.getSession().getId();
        if (username == BaseAction.SESSION_USER)
        {
            new OnlineUserMap().removeUser(sessionId);
        }
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent se)
    {
        String username = se.getName();
        String sessionId = se.getSession().getId();
        if (username == BaseAction.SESSION_USER)
        {
            new OnlineUserMap().removeUser(sessionId);
            User userInfo = (User) se.getSession().getAttribute(username);
            userInfo.setSessionId(sessionId);
            new OnlineUserMap().addOnlineUser(userInfo.getUserId(), userInfo);
        }
    }

}
Session监听器实现HttpSessionAttributeListener接口,需要实现该接口的三个方法:attributeAdded、attributeRemoved和attributeReplaced,其中:

attributeAdded        //在session中添加对象时触发此操作 笼统的说就是调用setAttribute这个方法时候会触发的

attributeRemoved   //修改、删除session中添加对象时触发此操作  笼统的说就是调用 removeAttribute这个方法时候会触发的

attributeReplaced   //在Session属性被重新设置时


Action基类的BaseAction类:

public class BaseAction extends ActionSupport
{
    private static final long serialVersionUID = -5102862846807662318L;
    public static final String INFO = "info";
    public static final String ERROR = "error";
    public static final String SUCCESS = "success";
    public static final String HOMEPAGE = "homepage";

    private static final ResultEntity SUCCESS_ENTITY = new ResultEntity();

    public static final String SESSION_USER = "USER_INFOMATION";

    public static final String SESSION_USERNAME = "CS_SESSION_USERNAME";

    private static JsonConfig jsonConfig = new JsonConfig();

    /**
     * 语言Map对象
*/ protected static Map localMap = new HashMap(); /** * 初始化语言Map的key→value数据 */ static { jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor()); localMap.put("en", Locale.ENGLISH); localMap.put("zh", Locale.SIMPLIFIED_CHINESE); } /* 向页面传递error信息 */ public String errormessage; /* 向页面传递info信息 */ public String infomessage; /* 向页面传递error信息,返回URL */ public String backURL; /* 显示模式: 0为列表,1为缩略图,共享session中保存 */ private int mode = 0; /* 排列顺序: 0为倒序,1为顺序 */ private int sort = 0; /* 排列字段: 默认为时间 */ private int sorttype = 0; private String requestFrom; /** * 当启用共享session的时候,根据sessionID获得共享的session,否则获取tomcat默认的session * * @param sessionid * @return * @throws Exception */ public HttpSession findSession() { return ServletActionContext.getRequest().getSession(); } /** * 获得request对象 * * @return */ public HttpServletRequest getRequest() { return ServletActionContext.getRequest(); } /** * 获得response对象 * * @return */ public HttpServletResponse getResponse() { return ServletActionContext.getResponse(); } /** * 获得servlet上下文 * * @return */ public ServletContext getServletContext() { return ServletActionContext.getServletContext(); } protected void rsaResponse(ResultEntity resultEntity) { toJson(resultEntity); } /** * 将对象以json方式返回 * @param obj 需要转换为json字符串的对象 */ protected void toJson(Object obj) { try { // 如果obj为CsResponse类或其子类,则判断retMessage是否为空,为空则根据retCode设置retMessage if (obj instanceof ResultEntity) { ResultEntity resultEntity = (ResultEntity) obj; if (StringUtils.isEmpty(resultEntity.getMesg())) { resultEntity.setMesg(getText(resultEntity.getResult())); } } IOUtils.write(JSONObject.fromObject(obj, jsonConfig).toString(), getJsonResponse().getWriter()); } catch (IOException e) { LoggerUtil.logger.error(obj + " convert to json failed.", e); } } protected void successResponse() { toJson(SUCCESS_ENTITY); } /** * 获取json返回方式的Response * @return response */ protected HttpServletResponse getJsonResponse() { HttpServletResponse response = getResponse(); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); return response; } protected String getRequestIp() { return RequestUtil.getIpAddr(getRequest()); } protected SessionUser getSessionUser() { return (SessionUser) findSession().getAttribute(SESSION_USER); } protected void cacheSessionUser(SessionUser user) { HttpSession session = findSession(); session.setAttribute(SESSION_USER, user); session.setAttribute(SESSION_USERNAME, user.getUsername()); } public int getMode() { return mode; } public void setMode(int mode) { this.mode = mode; } public int getSort() { return sort; } public void setSort(int sort) { this.sort = sort; } public int getSorttype() { return sorttype; } public void setSorttype(int sorttype) { this.sorttype = sorttype; } public String getErrormessage() { return errormessage; } public void setErrormessage(String errormessage) { this.errormessage = errormessage; } public String getInfomessage() { return infomessage; } public void setInfomessage(String infomessage) { this.infomessage = infomessage; } public String getBackURL() { return backURL; } public void setBackURL(String backURL) { this.backURL = backURL; } public void setRequestFrom(String requestFrom) { this.requestFrom = requestFrom; } public String getRequestFrom(String defaultFrom) { if (StringUtils.isBlank(requestFrom)) { return defaultFrom; } return requestFrom; } public String getPostBody() { String body = null; try { body = IOUtils.toString(getRequest().getInputStream()); } catch (IOException e) { e.printStackTrace(); } if (StringUtils.isBlank(body)) { throw new CsException(ReturnCode.PARAM_ERROR); } return body; } protected void resetLanguage() { String language = ServletActionContext.getRequest().getParameter("language"); if (StringUtils.isBlank(language)) { return; } if (localMap.containsKey(language)) { ServletActionContext.getContext().setLocale(localMap.get(language)); } else { ServletActionContext.getContext().setLocale(new Locale(language)); } } }

Session监听器web.xml文件配置:

  
      com.zte.init.UserLoginListener  


缓存在线用户数据,在线用户集合类:

public class OnlineUserMap
{
    public static Map onlineuser = new HashMap();

    /**
    * 得到在线用户
    * @return
    */
    public static Map getOnlineuser()
    {
        return onlineuser;
    }

    /**
    * 添加在线用户
    * @param sessionId
    * @param userName
    * @return
    */
    public void addOnlineUser(Integer userId, User user)
    {
        onlineuser.put(userId, user);
    }

    /**
    * 移除用户
    * @param userName
    */
    public void removeUser(String sessionId)
    {
        for (Integer userId : onlineuser.keySet())
        {
            if (onlineuser.get(userId).getSessionId().equals(sessionId))
            {
                onlineuser.remove(userId);
                break;
            }
        }
    }

}


在用户登录的流程中做如下操作限制登录人数:

int limitUser = 30;
new OnlineUserMap();
int userNumber = OnlineUserMap.onlineuser.keySet().size();
if (userNumber >= limitUser){
    LoggerUtil.logger.error("Current online population is " + OnlineUserMap.onlineuser.keySet().size()
                    + ", limit population " + limitUser);
    throw new CsException(ReturnCode.ONLINE_USER_LIMIT);
}

限制同一个用户多地登录:

HttpServletRequest session = ServletActionContext.getRequest();
        String sessionId = session.getSession().getId();
        new OnlineUserMap();
        //当前登陆的Session/User
        User loginuserinfo = OnlineUserMap.onlineuser.get(user.getUserId());
        if (loginuserinfo != null)
        {
            if (loginuserinfo.getSessionId() != null)
            {
                if (!loginuserinfo.getSessionId().equals(sessionId))
                {
                    throw new CsException(ReturnCode.USER_LOGGED);
                }
            }
        }

从HttpservletRequest中获取ip地址:

/**
	 * 从HttpservletRequest中获取ip地址
	 * @param request 请求对象
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request)
	{
		String ipAddress = request.getHeader("x-forwarded-for");
		if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress))
		{
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress))
		{
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		
		if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress))
		{
			ipAddress = request.getHeader("x-request-ip");
		}		
		if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress))
		{
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1"))
			{
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try
				{
					inet = InetAddress.getLocalHost();
					ipAddress = inet.getHostAddress();
				}
				catch (UnknownHostException e)
				{
					e.printStackTrace();
				}
			}
		}

		// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15)
		{
			if (ipAddress.indexOf(",") > 0)
			{
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}






你可能感兴趣的:(web项目通过Session监听器控制在线人数以及同一用户异地登陆限制)