目录
一、简介过滤器
二、过滤器的运行机制
三、简介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);
}
}
这次分享就到这里了,学习路上,诸君共勉,我们下次见。
|