web项目通过Session监听器控制在线人数以及同一用户异地登陆限制
2017-06-19 11:24
591 查看
对于项目中要求控制同时在线人数的需求,可以通过Session监听器来实现。
Session监听器类:
attributeAdded //在session中添加对象时触发此操作 笼统的说就是调用setAttribute这个方法时候会触发的
attributeRemoved //修改、删除session中添加对象时触发此操作 笼统的说就是调用 removeAttribute这个方法时候会触发的
attributeReplaced //在Session属性被重新设置时
Action基类的BaseAction类:
Session监听器web.xml文件配置:
缓存在线用户数据,在线用户集合类:
在用户登录的流程中做如下操作限制登录人数:
限制同一个用户多地登录:
从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;
}
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;
}
相关文章推荐
- 利用session监听器来控制用户的上下线和在线人数问题
- java web 项目中通过session 统计在线访问人数
- java 监听器(监听用户监听器也叫Listener,是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可 以自动激发一些操作,比如监听在线的用户的数量。当增加一在线人数)
- VS 安装项目 :通过文本框得到用户输入 以及 安装后运行某程序(如打开C:\\a.html)
- web小项目---图片显示实时在线人数小程序
- 如何限制同一客户端登录的用户数量以及禁止同一用户同时在不同客户端登录? (转)
- 一个嵌入式web服务器项目,实现通过手机Android App实现对嵌入式设备的控制
- 配置H3C交换机实例(设置安全策略版,通过源IP地址对WEB登录用户进行控制)[连载之电子商务系统架构]
- 如何限制同一客户端登录的用户数量以及禁止同一用户同时在不同客户端登录
- 求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
- Nginx禁止直接通过IP地址访问网站以及限制IP登陆某目录(关闭默认站点或空主机头)
- java的web项目中使用cookie保存用户登陆信息
- 怎样限制web服务器在线人数
- 求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
- web day24 小项目练习图书商城, 用户,模块(注册,激活,登陆,退出),分类/图书模块
- java项目同一浏览器下限制用户重复登录
- 限制用户通过ssh密钥进行认证登陆
- java session HttpSessionListener、HttpSessionBindingListener使用区别,实现在线人数统计以及踢出用户
- java的web项目中使用cookie保存用户登陆信息
- 如何限制IP和指定用户,通过SSH登陆linux服务器