过滤器完成自动登录预处理并转交给servlet控制的学习

目录

一、简介过滤器

二、过滤器的运行机制

三、简介cookie

四、一个完整的过滤器完成自动登录转交给servlet的过程


一、简介过滤器

        过滤器可以说是更高级的servlet的形式,它拦截请求响应对象,把符合条件的传入到下一个过滤链,最后传到servlet核心服务。

二、过滤器的运行机制

        初步了解了过滤器的含义,那么过滤器又是怎样运作的呢?

我们初步的看一下过滤器的运行过程

客户端的数据在到达web服务器之前,会经过我们配置的过滤器链,层层筛选,最后进入到核心的servlet服务。

在具体的了解一下运行过程

我们可以看到,过滤器1将符合条件的数据传到过滤器2,过滤器2又将数据传到过滤器3,一直到过滤连末尾,在将控制权从过滤连末尾依次送回去。

大概就是上图这么一个过程。

那么我们在深入一点,过滤器本身的又是怎么运作的呢,这就要看一下过滤器的生命周期了

 

 过滤器在经过xml配置文件实例化以后,就要开始进行初始化,然后就是过滤器的核心doFilter()方法,进行过滤,最后在过滤器接受到被返回回来的控制权以后,开始执行销毁destroy()方法。

 了解了过滤器以后,我们还要在讲一下等下要涉及的cookie

三、简介cookie

        cookie大概就是客户端(浏览器)向服务器发送请求以后,服务器需要记录该用户信息,就用response向客户端发送一个存储着(key-value)格式信息的cookie,然后客户端就将其存储起来,用于对用户进行身份辨别。

        那么cookie在哪里看呢,点击F12键,edge浏览器可以在应用程序选项中看到cookie

Chrome浏览器也是点击F12进入开发者模式,在application选项中可以看到cookie

 

 

四、一个完整的过滤器完成自动登录转交给servlet的过程

        了解了过滤器和cookie,那么我们现在就来看看一个完整的过滤器完成自动登录转交给servlet的过程。

        先是过滤器部分的代码

package filter;

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.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import entity.User;

/**
 * <li>过滤器
 */
//@WebFilter("/*")
public class AutoLoginFilter implements Filter {

	public void doFilter(
			ServletRequest req, 			// 过滤请求
			ServletResponse response, 		// 过滤响应
			FilterChain chain				// 过滤器链
			) throws IOException, ServletException {
		// 做登录校验的预处理业务 
		// 需要注意的是,过滤器的Request对象是不再协议的,需要强制下转型
		HttpServletRequest request = (HttpServletRequest) req;
		//获得一个名为autologin的cookie,cookie本质上是一个键值对集合的数据结构
		Cookie[] cookies = request.getCookies();
		String autologin = null;
		// 如果cookie不空,则遍历cookie,业务上,如果拿到了自动登录信息,则初始化autologin
		for (int i = 0; cookies != null && i < cookies.length; i++) {
			if ("autologin".equals(cookies[i].getName())) { // 用名来判断 
				autologin = cookies[i].getValue();			// 取值来用
				break;
			}
		}
		
		// 检查是否有登录信息
		if (autologin != null) {
			//做自动登录,【业务上,这个值是两个部分,即用户名和密码】
			String[] parts = autologin.split("-");
			String username = parts[0];
			String password = parts[1];
			//检查用户名和密码
			if (("majie".equals(username) && "mj666666".equals(password))||("mj".equals(username) && "mj666666".equals(password))) {
				//登录成功则将用户状态存入session域
				User user = new User();
				user.setUsername(username);
				user.setPassword(password);
				request.getSession().setAttribute("user", user);
			}
		}
				
		//做完预处理工作后,下一步是放行
		chain.doFilter(request, response);
	}

}

        我们先写了一个登录校验的预处理服务,这个预处理服务呢,在第一次登录的时候并不会起效,因为此时我们的客户端中,并没有存在的cookie可以让我们调用,来进行登录校验,所以此时,过滤器不会起作用。

        当客户端存在数据以后,像这样

我们可以看到cookie里面有我们的账号,密码存在了,此时我们通过request.getCookies()得到这个cookie,然后将cookie中的数据取出来,和我们内部预置好的账号密码进行对比,如果都正确了,那么就将数据存入到session域中,此时,我们的过滤器就完成了它的任务了,那么下一步就进入到了我们的核心服务servlet

        先放servlet的登录代码 

package filter;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import entity.User;

/**
 * <li>核心登录业务控制
 */
//@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 获取参数
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 硬判断,写死了用户名和密码,思考真实的业务场境,如何取用户名和密码判断?
		if (("majie".equals(username) && "mj666666".equals(password))||("mj".equals(username) && "mj666666".equals(password))) {
			// 通过了检测,则封装数据
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);
			request.getSession().setAttribute("user", user);
			
			//发送自动登录的cookie,为以后的自动登录做准备
			String autoLogin = request.getParameter("autologin");
			if (autoLogin !=null) {
				// 封装用户名和密码,然后丢到cookie的某个键值中
				Cookie cookie = new Cookie("autologin", username+"-"+password);
				// 设置cookie的有效时间
				cookie.setMaxAge(Integer.parseInt(autoLogin));
				// 设置路径
				cookie.setPath(request.getContextPath());
				// 添加cookie
				response.addCookie(cookie);
			}
			
			//Servlet的核心业务完成:通过登录校验,控制跳转到首页
			response.sendRedirect(request.getContextPath()+"/index.jsp");
		} else {
			//Servlet的核心业务完成:未通过登录校验,控制跳转回到登录页,并给出出错信息提示
			request.setAttribute("errorMsg", "用户名或密码错误");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

        在servlet的登录服务中,我们先从session域中取账号密码,看看有没有从过滤器那里传过来的数据,然后进行账号密码判断,如果我们是第一次登录或者账号密码输出错误的话,此时我们面前的就是登录页面

        如果我们现在不是第一次登录,并且已经成功登录过一次了,那么我们要讲此时的账号密码打包,存入到session域中,封装数据,以便jsp网页操作,同时我们还要将此次的登录信息进行封装,存入到cookie中,将cookie同过response发送到客户端进行存储,以便下一次的登录,完成这两个动作以后,我们就会跳转到首页,也就是登录以后进入的页面

 

         那么现在我们就完成了预处理自动登录在转交给servlet的这么一个动作,既然有登录,那么肯定也有登出,登出的信息销毁,并不是直接在客户端删掉cookie数据,毕竟服务器不能直接修改客户端的数据,我们现在服务器上删除了session域的user用户数据,然后创建一个cookie,并且将这个cookie的有效期设置为0,也就是这个登录信息过期了,再设置路径,然后将这个值发送到客户端,客户端就会销毁这个cookie,再重定向客户端的网页到登录页面,此时,我们要登录网页,就必须要再次输入账号密码。

 

 

        代码如下

package filter;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <li>核心退出业务控制
 * <li>首先得明白,在服务器端是不能直接删除客户端的cookie。
 * <li>1 它采取的方式是在服务端设置cookie.setMaxAge(0),
 * <li>2 再通过 response.addCookie(cookie) 将这个值返回到客户端后,
 * <li>3 客户端就知道自己的cookie没用了,再删除它。 
 * <li>4 故 response.addCookie(cookie); 不能省略,它是一个告知的功能
 * <li> 做一下对比理解:
 * <li>        好比 商场不能直接扔掉客户的的会员卡(会员卡相当于cookie),
 * <li>        它只能设置客户的会员卡失效,
 * <Li>        客户知道会员卡失效后,自己才把卡扔掉(扔掉才相当于删除cookie的功能)。
 */
//@WebServlet("/LogoutServlet")
@SuppressWarnings("serial")
public class LogoutServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		
		// 移除session
		request.getSession().removeAttribute("user");
		// 创建cookie
		Cookie cookie = new Cookie("autologin", "msg");
		cookie.setPath(request.getContextPath());

		// 将cookie置为过期
		cookie.setMaxAge(0);
		response.addCookie(cookie);
		
		// 导航,重定向
		response.sendRedirect(request.getContextPath()+"/index.jsp");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		doGet(request, response);
	}

}

这次分享就到这里了,学习路上,诸君共勉,我们下次见。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值