使用过滤器和监听器防止用户重复登录
老师您好这是我参照问答社区创建的项目,但是无法运行,劳烦老师能够帮忙修改完善一下,指出哪里错了,然后我再去理解。
相关代码:
package com.imooc.user;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
public class LoginMessage {
/*LoginMessage类:
该类是单例,有存储用户登录sessionID和用户登录session的Map集合,
有通过用户名查询和设置sessionID的方法,
以及通过sessionID查找和设置session的方法。*/
private static LoginMessage instance = new LoginMessage();
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对象
private LoginMessage(){
}
public static LoginMessage getInstance(){
return instance;
}
public String getSessionIdByUsername(String username){
return loginUserSession.get(username);
}
public HttpSession getSessionBySessionId(String sessionId){
return loginSession.get(sessionId);
}
public void setSessionIdByUserName(String username,String sessionId){
loginUserSession.put(username, sessionId);
}
public void setSessionBySessionId(String sessionId,HttpSession session){
loginSession.put(sessionId, session);
}
}
相关代码:
package com.imooc.user;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/servlet/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*LoginServlet类:该类中只需要获取登录用户信息,将其存入session,转发到主界面的代码*/
// 发送请求,将该请求下发到登录成功页面
String username = request.getParameter("userName");
String password = request.getParameter("password");
HttpSession session = request.getSession();
session.setAttribute("loginUser", username);//登录完成,将登录用户名存储至session对象
response.sendRedirect("/success.jsp");
}
}
相关代码:
package com.imooc.user;
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 IsFilter implements Filter{
@Override
public void destroy() {
System.out.println("过滤器销毁");
}
/*IsFilter类(类命名不规范,首字母应该大写)
该类中只用来判断是否登录,如果登录,则跳转到主界面,没有登录则跳转到登录页面:*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hrequest = (HttpServletRequest)request;
HttpServletResponse hresponse = (HttpServletResponse)response;
String loginUser = (String)hrequest.getSession().getAttribute("loginUser");
// 判断用户是否登录
if(loginUser==null){
hresponse.sendRedirect(hrequest.getContextPath()+"/login.jsp");
return;
}else{
chain.doFilter(request, response);
return;
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
相关代码:
package com.imooc.user;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class SessionAttributeListener implements HttpSessionAttributeListener{
private static final String LOGIN_USER="loginUser";
public SessionAttributeListener() {
super();
}
/*该类的attributeAdded方法中获取监听到的属性名,
* 如果是登录操作,则获取登录的名称,判断登录名称是否之前登录过,
* 如果登录过,则清理前次会话信息,将本次登录信息存入LoginMessage*/
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
String attrName = event.getName();
if(LOGIN_USER.equals(attrName)){//若属性名为登录属性名,判定为用户登录操作
String attrVal = (String)event.getValue();//获取添加的属性值,即用户登录名
HttpSession session = event.getSession();//该次操作的session对象
String sessionId = session.getId();//该次操作的session对象ID
String sessionId2 = LoginMessage.getInstance().getSessionIdByUsername(attrVal);//从缓存对象里面,获得该用户登录名对应的sessionID值
if(null == sessionId2){//未获得结果,不需要清理前次登录用户会话信息
}else{
HttpSession session2 = LoginMessage.getInstance().getSessionBySessionId(sessionId2);//获取前次该用户登录对应的session对象
session2.invalidate();//清理前次登录用户会话存储信息,使得前次登录失效
}
//完成该次登录用户登录名、sessionID,session对象的缓存对象存储
LoginMessage.getInstance().setSessionIdByUserName(attrVal, sessionId);
LoginMessage.getInstance().setSessionBySessionId(sessionId, session);
}
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
}
}
相关代码:
<%@ page language="java" contentType="text/html; UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="login_h">
<div id="login_h_title">
<h1>系统登录</h1>
</div>
<div id="login_body">
<form id="body_form" action="http://localhost:8080/UserLogin/servlet/login" method="get" >
<p>用户名:
</p>
<input type="text" id="userName" name="userName" placeholder="请输入中文/字母/数字的用户名【4-7位】"
/>
<p>密码:
</p>
<input type="password" id="pwd" name="password" placeholder="字母开头,数字字母6-10位组成"/ ><br>
<input type="submit" id="sub" name="sub" value="登录">
</form>
</div>
</div>
<script type="text/javascript">
/*$.ajax({
"url":"http://localhost:8080/UserLogin/servlet/login" ,
"type":"get",
"dataType":"json",
"success":function(json){
}
})*/
/* 给表单添加提交事件 */
/* 给相应的输入框添加正则表达式,限制输入内容 */
document.getElementById("body_form").onsubmit=function(){
var regexUserName=/^[\u4e00-\u9fa5A-Za-z1-9]{1}[\u4e00-\u9fa5A-Za-z0-9]{3,6}$/;
var regexPwd=/^[A-Za-z]{1}[0-9A-Za-z]{5,9}$/;
var userName=document.getElementById("userName").value;
var pwd=document.getElementById("pwd").value;
if(regexUserName.test(userName)==false){
alert("用户名不符合当前格式!");
return false;
}else if(regexPwd.test(pwd)==false){
alert("密码不不符合格式");
return false;
}else{
alert("校验成功!");
}
}
</script>
</body>
</html>
相关代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
<h1 style="color:red;">您好,您已登录!</h1>
</body>
</html>
相关代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>UserLogin</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>IsFilter</filter-name>
<filter-class>com.imooc.user.IsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>IsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.imooc.user.SessionAttributeListener</listener-class>
</listener>
</web-app>
45
收起
正在回答 回答被采纳积分+1
1回答
好帮手慕阿满
2021-03-15 12:02:36
同学你好,在同学的web.xml代码中,对所有的路径进行了拦截,如:
这里所有的路径包括登录页面login.jsp,以及登录时要访问LoginServlet的/servlet/login。访问登录页面login.jsp时还没有登录就被拦截,在过滤器中判断没有登录,重定向到login.jsp页面,又被拦截,在过滤器中判断没有登录,重定向到login.jsp页面,如此循环往复,造成重定向次数过多,拒绝访问。
这里建议在过滤器中增加一个判断,如果路径中包含login,则表示是要登录路径,放行不拦截。这样可以正常访问登录页面login.jsp以及登录的/servlet/login,代码参考:
祝学习愉快~
java工程师2020版
- 参与学习 人
- 提交作业 9393 份
- 解答问题 16556 个
综合就业常年第一,编程排行常年霸榜,无需脱产即可学习,北上广深月薪过万 无论你是未就业的学生还是想转行的在职人员,不需要基础,只要你有梦想,想高薪
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星