Application级账号锁定及账号独立会话操作
?
import java.util.Date;/** * 登录信息 * @remark 该信息保存在application中,主要用于登录锁定和同一账户同时只能登录一次 * @author lihua * @version V1.0 * @createDate 2012-9-28 */public final class LoginInApp {private String sessionId;//保存当前用户最新的sessionidprivate Date loginTime;//最后登录时间private int loginCount;//连续错误登录次数,该次数会在登录超过可连续登录时间间隔后自动回位到1public LoginInApp() {}public LoginInApp(String sessionId, Date loginTime, int loginCount) {this.sessionId = sessionId;this.loginTime = loginTime;this.loginCount = loginCount;}public String getSessionId() {return sessionId;}public void setSessionId(String sessionId) {this.sessionId = sessionId;}public Date getLoginTime() {return loginTime;}public void setLoginTime(Date loginTime) {this.loginTime = loginTime;}public int getLoginCount() {return loginCount;}public void setLoginCount(int loginCount) {this.loginCount = loginCount;}}
?
/** * 账号锁定验证 */String accountLockState = PropertiesUtil.getString(Constants.ACCOUNT_LOCK_STATE);//锁定状态开关if(ValidateUtil.matchString(accountLockState, "on")){//开启锁定HttpSession session = request.getSession();Object obj = session.getServletContext().getAttribute(Constants.KEY_SESSION_MESSAGE);if(obj!=null){//application 用户缓存不为空Map<String, LoginInApp> map = (HashMap<String, LoginInApp>)obj;LoginInApp lip = map.get(userdto.getUserName());if(lip!=null){//当前用户的登录记录不为空int max_login_number = 3;//可连续登录次数int lock_time = 10;//持续锁定时间SysParam param = sysParamServiceImpl.getByParamName(Constants.SECURITY_PARAMS[0]);if(param!=null&&ValidateUtil.validateString(param.getParamValue())){max_login_number = Integer.valueOf(param.getParamValue());}SysParam param1 = sysParamServiceImpl.getByParamName(Constants.SECURITY_PARAMS[1]);if(param1!=null&&ValidateUtil.validateString(param1.getParamValue())){lock_time = Integer.valueOf(param1.getParamValue());}if(lip.getLoginCount()>=max_login_number){//超出可连续登录次数Calendar curCal = Calendar.getInstance();Calendar lockCal = new GregorianCalendar();lockCal.setTime(lip.getLoginTime());lockCal.add(Calendar.MINUTE, lock_time);if(curCal.before(lockCal)){addActionError("账号"+userdto.getUserName()+"已被锁定,请在"+lock_time+"分钟后登录!");return "loginerror";}else{//过期解锁lip.setLoginCount(0);}}}}}
??/**
* 修改应用程序缓存账户信息 * @param user */private void modifyLoginInApp(OnlineUser user){String accountLockState = PropertiesUtil.getString(Constants.ACCOUNT_LOCK_STATE);//锁定状态开关if(ValidateUtil.matchString(accountLockState, "on")){//锁定状态开启ServletContext app = ServletActionContext.getServletContext();//上下文Map<String, LoginInApp> appInfo = (Map<String, LoginInApp>)app.getAttribute(Constants.KEY_SESSION_MESSAGE);if(ValidateUtil.matchString(user.getErrorMsg(),Constants.LOGIN_ERROR_TIP)){//登录异常if(appInfo!=null){LoginInApp lip = appInfo.get(user.getUserName());if(lip==null){lip = new LoginInApp(ServletActionContext.getRequest().getSession().getId(),new Date(),1);}else{lip.setLoginTime(new Date());lip.setLoginCount(lip.getLoginCount()+1);}appInfo.put(user.getUserName(), lip);}else{appInfo = new HashMap<String, LoginInApp>();LoginInApp lip = new LoginInApp(ServletActionContext.getRequest().getSession().getId(),new Date(),1);appInfo.put(user.getUserName(), lip);}app.setAttribute(Constants.KEY_SESSION_MESSAGE, appInfo);}}}
?private void sessionManage(OnlineUser user){
HttpSession session = request.getSession();ServletContext context = ContextLoader.getCurrentWebApplicationContext().getServletContext();Object obj = context.getAttribute(Constants.KEY_SESSION_MESSAGE);Map<String, LoginInApp> map = null;if(obj!=null){map = (HashMap<String, LoginInApp>)obj;}else{map = new HashMap<String, LoginInApp>();}map.put(user.getUserName(),new LoginInApp(session.getId(),new Date(),0));context.setAttribute(Constants.KEY_SESSION_MESSAGE,map);}
?
在拦截器中处理多客户端登录
OnlineUser ouser = (OnlineUser)session.getAttribute(Constants.KEY_SESSION_ONLINE_USER);//多个客户端登录,先登录者被踢出ServletContext context = session.getServletContext();Object obj = context.getAttribute(Constants.KEY_SESSION_MESSAGE);if(obj!=null&&ouser!=null){Map<String, LoginInApp> map = (HashMap<String, LoginInApp>)obj;String oldSessionId = map.get(ouser.getUserName())==null?null:map.get(ouser.getUserName()).getSessionId();if(ValidateUtil.validateString(oldSessionId)&&!ValidateUtil.matchString(session.getId(), oldSessionId)){session.removeAttribute(Constants.KEY_SESSION_ONLINE_USER);response.sendRedirect(request.getContextPath() + "/common/outTime.jsp");return;}}?
?
?
看起来,“同一账号只会记录该账号最后一次登录的sessionId。在拦截器中对用户的会话ID进行验证,如果不一致,则为之前登录的客户端,直接将当前会话清除,以实现账号独立会话的功能。”,前面需要添加个“登录成功后,”,语言组织不力啊。 2 楼 hy806806 2012-09-29 写的挺好,博主的字里行间处处透着谦虚,为何不自信一点,呵呵。。。个人认为数据存至应用的Applicaion中,对于大应用会耗费内存影响性能,我们在做项目组时都是通过数据库来实现这些功能的。