今天尝试实现用户登录之后点击退出按钮然后重定向到登录界面的操作,结果点击按钮后用户一直无法退出
登陆时添加的Cookie
String isStudent = req.getParameter("is-student");//判断是学生还是管理员,如果为null就是管理员
String username = req.getParameter("username");//用户名
String password = req.getParameter("password");//密码
String remember = req.getParameter("remember");//是否记住密码
if(isStudent!=null){//如果登录的是学生
Student student=new Student(username,password);
httpSession.setAttribute("student", student);//传入Student对象用以验证是否已经登录,下同
}else{//如果登录的是管理员
User user =new User(username,password);
httpSession.setAttribute("user", user);
}
if (remember != null) {
//传入Cookie
Cookie cookie_username = new Cookie("username", username);
Cookie cookie_password = new Cookie("password", password);
Cookie cookie_isStudent = new Cookie("is-student", isStudent);
cookie_username.setMaxAge(60 * 60 * 24 * 30);
cookie_password.setMaxAge(60 * 60 * 24 * 30);
cookie_isStudent.setMaxAge(60 * 60 * 24 * 30);
resp.addCookie(cookie_username);
resp.addCookie(cookie_password);
resp.addCookie(cookie_isStudent);
}
实现按钮
<a href="logout-student">
<i class="fas fa-sign-out-alt"></i> 退出登录
</a>
注册退出的LogoutStudentServlet(通过addCookie覆盖原来的Cookie实现Cookie的删除)
@WebServlet("/logout-student")
public class LogoutStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie_isStudent = new Cookie("is-student", null);
Cookie cookie_username = new Cookie("username", null);
Cookie cookie_password = new Cookie("password", null);
//将Cookie设置失效
cookie_username.setMaxAge(0);
cookie_password.setMaxAge(0);
cookie_isStudent.setMaxAge(0);
//覆盖Cookie的代码段
resp.addCookie(cookie_username);
resp.addCookie(cookie_password);
resp.addCookie(cookie_isStudent);
resp.sendRedirect("login");//重定向到登录界面
}
}
我的想法是:用户点击退出按钮就可以重定向到登录界面,结果点击之后,用户不仅没有退出,甚至Cookie都没有被覆盖
遇到问题第一时间干什么?百度!面向CSDN编程!
然后走向了一条岔路,绝大多数人遇到无法删除Cookie的情况都是因为Cookie路径没有设置,域名没有设置之类的,于是我给Cookie添加了路径
cookie_username.setPath("/");
cookie_password.setPath("/");
cookie_isStudent.setPath("/");
以防意外,在添加Cookie和覆盖Cookie的代码处我都加上了这段,理想是丰满的,结果却不是
点击退出按钮后,程序会跳转到注册的LogoutStudentServlet,但是,它没有调用doGet方法,Cookie也没有被覆盖,而是直接重定向到登录界面,这就意味着这个Servlet中无论我写不写东西,程序都能正常运行,它只是需要一个注册名为“logout-student”的Servlet
如图:
它首先跳转到logout-student,也就是定义的退出servlet程序,之后重定向到登录界面login,但是之后又通过Cookie自动登录到用户界面,也就是说,用户点击退出后,程序跳了2个界面又回到了用户界面,好像干了什么又好像什么也没干
但一切都是有根源的,我锁定了重定向到login这个操作,在将LogoutStudentServlet中所有重定向到login的代码注释后,发现这个bug依然存在,说明问题不在servlet中,我的项目中与servlet相关联的只有全局过滤器,于是成功在全局过滤器中发现了问题
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
res.setContentType("text/html;charset=utf-8");
String url = req.getRequestURL().toString();
if (!url.endsWith("/login") && !url.contains("/static/")) {
//这里本意是防止不登陆直接进入用户界面,但结果却是把项目给卡了
HttpSession session = req.getSession();
User user = (User) session.getAttribute("user");
//从session中获取user对象,用以验证管理员是否登录,下同
// 应添加Student student = (Student) session.getAttribute("student");
if (user == null ) {//条件应添加&& student == null
//判断条件本来是实现没有登录的用户会全部重定向到登录界面,但我新增了学生用户后没有添加学生的判断条件,导致退出之后不覆盖Cookie直接重定向到登录界面
res.sendRedirect("login");
return;
}
}
chain.doFilter(req, res);
}
问题根源在于添加了新的登录用户student类型后,我没有在全局过滤器中加入它,而原来的过滤器只认user类型的用户,这就导致student无法退出