java技术--基于javaWeb的单态登录

在网上有许多单态登录的实例,但是大部分都是基于JSP,现在大型项目开发很少在Jsp中集成逻辑编码,因此本人基于纯后台总结一下单态登录的实现。

注:单态登陆和单点登录是两个不同的概念
(1)单态登录:目的是防止多台机器同时使用一个账号
(2)单点登录:用户只需要登录一次就可以访问所有相互信任的应用系统

1.单态登录实现步骤

 (1)定义一个Javabean对象,已实现数据库连接
     User.java
    public class User implements java.io.Serializable{
	private static final long serialVersionUID = 7873162303386188683L;
	@Id
	private Long id;
	private String name;
	private String password;
	// 登录ip地址
    @Transient
	private static String ip;
	//登录时间
	@Transient
	private static Date loginDate;
}
(2)DAO,Servlet实现数据库操作省略
(3)定义一个Controller,实现交互
 UserController.java
   @RequestMapping(value = "/check_login", method = RequestMethod.POST)
	public ResponseResult checkLogin(@RequestBody User user,HttpServletRequest request, HttpSession session) {
		User u = userService.login(user);
			if (null != u) {
				if (null != user) {
					if (session != null) {
						user.setId(u.getId());
						user.setIp(request.getRemoteAddr());
						user.setLoginDate(new java.util.Date());
						user.setId(u.getId());
						//将登录对象user放入session监听登录信息,触发监听器
						request.getSession().setAttribute("user", user);
					}
				}
			}
		return ResponseResult.create(GlobalConstant.SUCCESS_CODE, null, new JSONObject());
	}

2.单态登录监听器实现

(1)设置一个集合用来存放登录用户信息
	public static final Map<String, HttpSession> loginUser = new HashMap<>();	
(2)实现监听用户登录状态
public class LoginListener implements HttpSessionAttributeListener { 	
    Log log= LogFactory.getLog(this.getClass());
	@Override
	/**
	 * HttpSessionBindingEvent:
	 * 1.当UserController中:request.getSession().setAttribute("user", user);
	 * 2.该事件在 监 听 到 HttpSession 发 生 绑 定 和 取 消 绑 定 的 情 况 时 连 通HttpSessionBindingListener
	 */
    public void attributeAdded(HttpSessionBindingEvent event){   
    	String name = event.getName();
    	//如果用户已经登录,将已登录用户踢下线
        if (name.equals("user")) {
            User user = (User) event.getValue();
            if (GlobalData.loginUser.get(user.getName()) != null) {
            	// map中有记录,表明该帐号在其他机器上登录过,将以前的登录失效
                HttpSession session = GlobalData.loginUser.get(user.getName());
                User oldUser = (User) session.getAttribute("user");
                log.info("账号"+oldUser.getName()+"在"+oldUser.getIp()+"已经登录,该登录将被迫下线!");  
                session.removeAttribute("user");
                session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线。");
            }
            //如果用户第一次登录,将session以用户名为索引,放入map中
            GlobalData.loginUser.put(user.getName(), event.getSession());
            log.info("账号" + user.getName()+"在" + user.getIp()+"登录"); 
        }  
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
		 String name = event.getName();
		 //注销
	        if (name.equals("user")) {
	        	// 将该session从map中移除
	            User user = (User) event.getValue();
	            GlobalData.loginUser.remove(user.getName());
	            log.info("账号"+user.getName()+"注销"); 
	        }
	}
	@Override
	public void attributeReplaced(HttpSessionBindingEvent event) {		
		 String name = event.getName();
		 // 没有注销的情况下,用另一个帐号登录
		 if(name.equals("user")) {
			// 移除旧的的登录信息
			 User oldUser = (User) event.getValue();
			 GlobalData.loginUser.remove(oldUser.getName());
			// 新的登录信息
			 User user = (User) event.getSession().getAttribute("user");
			// 也要检查新登录的帐号是否在别的机器上登录过
			 if(GlobalData.loginUser.get(user.getName()) != null) {
				// map 中有记录,表明该帐号在其他机器上登录过,将以前的登录失效
				 HttpSession session = GlobalData.loginUser.get(user.getName());
				 session.removeAttribute("user");
				 session.setAttribute("msg", "您的帐号已经在其他机器上登录,您被迫下线");
			 }
			 GlobalData.loginUser.put("user", event.getSession());
	         log.info("账号" + user.getName()+"在" + user.getIp()+"登录"); 
		 }
	}      

3.监听器web.xml配置

    (1)在web.xml中配置编写好的LoginListener 
    (2)配置如下:******表示LoginListener 所在包
   <listener>
    <listener-class>******.LoginListener</listener-class>
  </listener> 

总结:至此一个完整的单态登录已经实现

(1)需要注意监听器LoginListener和控制层UserController的联通
(2)UserController中:request.getSession().setAttribute("user", user)发 生 绑 定 和 取 消 绑 定 的 情 况 时 
(3)LoginListener:监听器将被触发
  <1>HttpSessionBindingEvent event
  <2> String name = event.getName();
(4)event.getName()获取到的便是request.getSession().setAttribute("user", user)中的对象  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值