Java监听器实现防止重复登录案例

监听器的功能  防止重复登录:当一个用户登录系统之后,另外一个用户使用相同账户登陆时,对前一个用户进行踢除操作,保证在同一时间只有一个账户在登录系统。

案例说明:

  • 通过过滤器实现登录控制,未登录用户不能访问系统首页
  • 用户登录,将登录名存储到session里
  • 登录监听器session属性中登录值属性变化
  • 若登录用户用户名已登录系统,清除前次登录信息

步骤:

  • 实现登录功能
  • 登录权限过滤验证
  • 用户信息存储实现
  • 监听功能实现 

创建index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
  <%
  	String flag=request.getParameter("flag");
  %>  
 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login</title>
</head>

<script type="text/javascript">
	var flag='<%=flag %>';
	if("1"==flag){
		alert("你尚未登陆,或者账号在异地登陆,请重新登陆!");
	}
	
</script>
<body>
	
	<form action="login.jsp" method="post" class="smart-green">
	<h1>系统登录</h1>

	<label>
	<span>用户名:</span>
	<input id="username" type="text" name="username"/>
	</label>

	<label>
	<span>密码:</span>
	<input id="password" type="password" name="password"/>
	</label>

	<span>&nbsp;</span>

	<label>
	<input type="submit" class="button" value="登录"/>
	</label>
	
  </form>
</body>
</html>

 

 一、实现登录功能

  1.  获取用户名和密码
  2. 将登录用户名存储至session对象
  3. 页面跳转到(登录后)main.jsp

 login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    //获取登录用户名和密码
	String username = request.getParameter("username");
	String password = request.getParameter("password");
	
	//将登录用户名存储至session对象
	session.setAttribute("LoginUser", username);
	
	//页面跳转到main.jsp
	response.sendRedirect(request.getContextPath()+"/main.jsp");
	
%>

对于main.jsp即登录后的页面,大家可以根据自己的喜好设置,需在前面加上

<%
    String user=(String)session.getAttribute("LoginUser");
%> 

二、登录权限过滤验证

  1.  Filter接口
  2. 从session对象中获取登录用户名
  3. 判断是否登录,即用户名是否已经存在:不存在则重定向至登录页面,已登录则转入相应请求

   SessionFilter.java



/**
 * 用户登录权限过滤器
 */
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SessionFilter implements Filter {

	@Override
	public void destroy() {
	

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		//将request和response转为专门的http请求对象
		HttpServletRequest hrequest=(HttpServletRequest)request;
		HttpServletResponse hresponse=(HttpServletResponse)response;
		
		//从session对象中获取登录用户名
		String LoginUser = (String)hrequest.getSession().getAttribute("LoginUser");
		
		//判断是否登录,即用户名是否存在
		if(LoginUser==null) {
			//不存在则重定向至登录页面
			hresponse.sendRedirect(hrequest.getContextPath()+"/index.jsp?flag=1");
			
			return;
		}else {
			chain.doFilter(request, response);//已登录,转到相应的请求
			return;
		}
		
		
		

	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		

	}

}

三、用户信息存储实现

  1. 通过登录名获取对应登录用户的sessionId
  2. 通过sessionId获取对应的session对象
  3. 存储登录名与相应的登录sessionId至缓存对象
  4. 存储 sessionId与对应的session对象至缓存对象

LoginCache.java

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;

/**
 * 用户信息存储实现
 * @author 16286
 *
 */


public class LoginCache {
	
	private static LoginCache instance = new LoginCache();
	
	//单例模型
	private LoginCache() {
		
	}
	
	public static LoginCache getInstance() {
		return instance;
	}
	
	private Map<String,String>LoginUserSession=new HashMap<String,String>();
	//key值:登录用户登录名,value值:登录用户sessionId
	private Map<String,HttpSession>LoginSession=new HashMap<String,HttpSession>();
	//key值:登录用户sessionId,value值:登录用户session对象
	
	/**
	 *  通过登录名获取对应登录用户的sessionId
	 */
	public String getSessionIdByUsername(String username) {
		return LoginUserSession.get(username);
	}
	
	/**
	 * 通过sessionId获取对应的session对象
	 */
	public HttpSession getSessionBySessionId(String sessionId) {
		return LoginSession.get(sessionId);
	}
	
	/**
	 * 存储登录名与相应的登录sessionId至缓存对象
	 */
	public void setSessionIdByUsername(String username,String sessionId) {
		LoginUserSession.put(username, sessionId);
	}
	
	/**
	 * 存储sessionId与对应的session对象至缓存对象
	 */
	public void setSessionBySessionId(String sessionId,HttpSession session) {
		LoginSession.put(sessionId, session);
	}
}

四、监听功能实现

 LoginSessionListener.java


import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

import com.lzy.session.LoginCache;

public class LoginSessionListener implements HttpSessionAttributeListener {

	private static final String LOGIN_USER = "LoginUser";

	@Override
	public void attributeAdded(HttpSessionBindingEvent hsbe) {
		// 监听到session属性值发生添加操作,获取对应操作的属性名
		String attname = hsbe.getName();

		if (LOGIN_USER.equals(attname)) {
			// 获取添加的属性值,即用户登录名
			String attrVal = (String) hsbe.getValue();
			// 获取该次操作的session对象
			HttpSession session = hsbe.getSession();
			// 该次操作的session对象ID
			String sessionId = session.getId();
			// 从缓存对象里面,获得该用户登录名对应的sessionID值
			String sessionId2 = LoginCache.getInstance().getSessionIdByUsername(attrVal);

			if (null == sessionId2) {// 未获得结果,不需要清理前次登录用户会话信息

			} else {
				HttpSession session2 = LoginCache.getInstance().getSessionBySessionId(sessionId2);// 获取前次该用户登录对应的session对象
				session2.invalidate();// 清理前次登录用户会话存储信息,使得前次登录失效
			}

			// 完成该次登录用户登录名、sessionID,session对象的缓存对象存储
			LoginCache.getInstance().setSessionIdByUsername(attrVal, sessionId);
			LoginCache.getInstance().setSessionBySessionId(sessionId, session);
		}

	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		// TODO Auto-generated method stub

	}

}

配置xml

<!--注册监听器-->
<listener>
 	<listener-class>com.lzy.session.LoginSessionListener</listener-class>
 </listener>

<!--注册过滤器-->
<filter>
     <filter-name>SessionFilter</filter-name>
	 <filter-class>com.lzy.session.SessionFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>SessionFilter</filter-name>
	<url-pattern>/main.jsp</url-pattern>
</filter-mapping>

 

最后运行结果(用两个浏览器进行测试)

 运行程序

在360浏览器里打开本地服务器

跳转到登录后的界面main.jsp

接着在火狐浏览器打开

输入相同的账号密码,登录成功后,回到360浏览器,点击刷新,就会出现

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

l去留无心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值