单一登录实现

可以利用 Servlet三大域对象 request、session、application(ServletContext)中的ServletContext,它是一个全局的储存信息的空间,服务器启动后就被创建,服务器停止后才销毁。

request,一个用户可有多个;session,一个用户一个;而servletContext,所有用户共用一个。所以,为了节省空间,提高效率,ServletContext中,要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。

具体方案:将用户的登录信息保存在application里, 然后利用session监听器HttpSessionListener监听每一个登录用户的登录情况。
 

1.登录功能中添加如下代码

//单一登录操作设置    
HttpSession session = req.getSession();
				
ServletContext application = session.getServletContext();
				
Map<Integer, Object> loginMap = (Map<Integer, Object>)application.getAttribute("loginMap");	
if (loginMap == null) {
	loginMap = new HashMap<Integer, Object>();
}
for (Integer key : loginMap.keySet()) {
	if (sysUserInfo.getId().intValue() == key.intValue()) {
		returnMap.put("flag", 2);
		if (session.getId().equals(loginMap.get(key))) {
	        returnMap.put("message", "在同一地点重复登录!");
	    } else {
		    returnMap.put("message", "异地已登录,请先退出!");
	    }
		return returnMap;
    }
}
loginMap.put(sysUserInfo.getId(),session.getId());
application.setAttribute("loginMap", loginMap);
// session 销毁时间
session.setMaxInactiveInterval(40*60);		//40min失效, -1永不过期
				
// 将用户保存在session当中
session.setAttribute("sysUserInfo", sysUserInfo);
sysLogService.saveLog(req, "sys_user_info", sysUserInfo.getId()+"", " 登录");

2.编写一个实现类 SessionListener,重写HttpSessionListener

public class SessionListener implements HttpSessionListener {

	@Override
	public void sessionCreated(HttpSessionEvent httpSessionEvent) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
		HttpSession session = httpSessionEvent.getSession();
		SysUserInfo user = (SysUserInfo) session.getAttribute("sysUserInfo");
		if (user != null) {
			ServletContext application = session.getServletContext();
			@SuppressWarnings("unchecked")
			Map<String, Object> loginMap = (Map<String, Object>) application.getAttribute("loginMap");
			loginMap.remove(user.getId());
			application.setAttribute("loginMap", loginMap);
			session.removeAttribute("user");
		}
		
	}

}

sessionCreated session创建的时候使用,这里如果我们需用做统计在线人数等功能时,可以自己去实现自己的逻辑代码了

sessionDestroyed session销毁的时候用,session 销毁时调用逻辑去清除登录信息。

上述session销毁时间可以按照自己实际需求去定。session监听器的作用是为了监听那些非正常退出系统的用户,清除登录信息用的。

3、退出系统的方法和监听器中销毁session方法中的逻辑大体相同,根据自身项目的实际情况去定

public String logout(HttpServletRequest req){
		try{
			HttpSession session = req.getSession();
			
			if (session != null) {
				SysUserInfo loginUser = (SysUserInfo) session.getAttribute("sysUserInfo");
				ServletContext application = session.getServletContext();
				@SuppressWarnings("unchecked")
				Map<String, Object> loginMap = (Map<String, Object>) application.getAttribute("loginMap");
				loginMap.remove(loginUser.getId());
				application.setAttribute("loginMap", loginMap);
//				session.removeAttribute("sysUserInfo");
				sysLogService.saveLog(req, "sys_user_info", "", " 用户退出登录");
				session.invalidate();		//清除session信息
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return "forward:/web/index.do";
	}

4.web.xml中添加监听器

<listener>
    <listener-class>com.csdn.framework.SessionListener</listener-class>  
</listener>
扫描二维码关注公众号,回复: 5272385 查看本文章

猜你喜欢

转载自blog.csdn.net/zhangyongbink/article/details/86510426