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对象<br>
     */
    protected static Map<String, Locale> localMap = new HashMap<String, Locale>();
    /**
     * 初始化语言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文件配置:

<listener>  
      <listener-class>com.zte.init.UserLoginListener</listener-class>  
</listener>


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

public class OnlineUserMap
{
    public static Map<Integer, User> onlineuser = new HashMap<Integer, User>();

    /**
    * 得到在线用户
    * @return
    */
    public static Map<Integer, User> 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;
	}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值