需求:
一个账户同时只能一次登录在线,当使用同一个账户二次登录的时候那么第一的登录将被失效(类似QQ挤下线)
处理基本思想:
将唯一用户ID与Session建立关联关系放在Application作用域中进行管理。
----------------------------------------------------------------------------------------------------------
关键处理类:
package com.defshare.sy.web.util;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import com.defshare.foundation.global.PropertiesUtil;
import com.defshare.sy.config.AuthConfig;
public final class AuthenUtil {
static Logger LOG = Logger.getLogger(AuthenUtil.class);
/**
* 多重登录检测处理
* @param loginId
*/
public synchronized static final void multipleLoginDetect(String loginId){
ServletContext servletContext = ServletActionContext.getServletContext();
Map<String,HttpSession> sessionMap = new HashMap<String,HttpSession>();
Object sessionMapObj = servletContext.getAttribute("LOGINED_USER_SESSION_MAP");
if (sessionMapObj!=null){
sessionMap = (Map<String,HttpSession>)sessionMapObj;
}
if (sessionMap.containsKey(loginId.toUpperCase())){//如果登过录就销毁以前登录的Session
HttpSession session = sessionMap.get(loginId.toUpperCase());
if (session!=null && !ServletActionContext.getRequest().getSession().getId().equals(session.getId())){
try {
session.invalidate();
} catch (Exception e) {
LOG.info("session被重复销毁:["+e.getMessage()+"]");
}
}
}
sessionMap.put(loginId.toUpperCase(), ServletActionContext.getRequest().getSession());//将当前session重新放入Map
servletContext.setAttribute("LOGINED_USER_SESSION_MAP", sessionMap);
}
/**
* 登出
* @param loginId
*/
public synchronized static final void logout(String loginId){
if(loginId==null || "".equals(loginId))
return;
ServletContext servletContext = ServletActionContext.getServletContext();
Object sessionMapObj = servletContext.getAttribute("LOGINED_USER_SESSION_MAP");
if (sessionMapObj==null){
return;
}
Map<String,HttpSession> sessionMap = (Map<String,HttpSession>)sessionMapObj;
if (sessionMap.containsKey(loginId.toUpperCase())){//如果登过录就销毁以前登录的Session
HttpSession session = sessionMap.get(loginId.toUpperCase());
if (session!=null){
try {
session.invalidate();
LOG.info("根据登录ID:"+loginId+"找到Session,执行销毁");
} catch (Exception e) {
LOG.info("session被重复销毁:["+e.getMessage()+"]");
}
}
sessionMap.remove(loginId.toUpperCase());
}
}
public synchronized static final String getAdminName(){
return AuthConfig.adminName;
}
/**
* 获得管理员信息
* <p>
* admin,0000
* </p>
* @return
*/
public synchronized static final String getAdminInfo(){
return AuthConfig.adminName+","+AuthConfig.adminPwd;
}
}
登录调用示范:
/**
* 诊所登录
*
* @return
*/
public String doLogin() {
SystemLog log = new SystemLog();
String zsid = super.getParam("zsid").toString();
String zsmm = super.getParam("zsmm").toString();
log.setLoginId(zsid);
log.setKind("1");
log.setIp(request.getRemoteHost());
if (StringUtils.isBlank(zsid) || StringUtils.isBlank(zsmm)) {
super.addValidateMsg(VALIDATE_MSG, "诊所编号密码不能为空");
log.setContent("诊所登录失败:[诊所编号密码不能为空]");
systemLogService.addLog(log);
return "toLogin";
}
if (zsid.equals(AuthConfig.adminName)) {
super.addValidateMsg(VALIDATE_MSG, "非法的诊所ID");
log.setContent("诊所登录失败:[非法的诊所ID]");
systemLogService.addLog(log);
return "toLogin";
}
try {
if (cliniqueService.authentication(zsid, zsmm)) {
super.addAttr(IAction.LOGINED_USER, zsid, VScope.SESSION);
UserUtil.setLoginedUser(zsid);// 保存线程局部变量
AuthenUtil.multipleLoginDetect(zsid);
log.setContent("诊所" + zsid + ">登录>成功!");
systemLogService.addLog(log);
return "login_success";
}
} catch (Exception e) {
super.addValidateMsg(VALIDATE_MSG, e.getMessage());
log.setContent("诊所登录异常:[" + e.getMessage() + "]");
systemLogService.addLog(log);
return "toLogin";
}
super.addAttr(IAction.LOGIN_MSG, "用户名密码不正确", VScope.REQ);
log.setContent("诊所登录失败:[用户名密码不正确]");
systemLogService.addLog(log);
return "toLogin";
}
登出调用示范:
public String logout() {
if(!StringUtils.isBlank(getCurrentUser())){
SystemLog log = new SystemLog();
log.setLoginId(getCurrentUser());
log.setKind("1");
log.setIp(request.getRemoteHost());
log.setContent("诊所" + getCurrentUser() + ">注销>成功!");
AuthenUtil.logout(getCurrentUser());
systemLogService.addLog(log);
return "logout_success";
}else{
return "logout_success";
}
}