十五、Filter过滤器
1、什么是过滤器
1、内容
1、Filter过滤器是javaweb的三大组件之一。三大组件分别为:servlet程序、Listener监听器、Filter过滤器
2、Filter过滤器是JavaEE的规范。是一个接口
3、FIlter的作用:拦截请求,过滤响应。
2、应用场景
1、权限检查
2、日记操作
3、事务管理
2、Filter体验
2.1、需求
1、在web工程下,有个admin目录。这个admin目录下的所有资源(html、jsp、jpg、等等)都是需要在用户登录之后才允许访问的。
2.2、Filter工作流程图

1、思考:根据之前我们学过内容。我们知道,用户登录之后都会把用户登录的信息保存到 Session 域中。所以要检查用户是否 登录,可以判断 Session 中否包含有用户登录的信息即可!!!
2.3、Filter过滤器的使用步骤
1、编写一个类去实现Filter接口
2、实现接口中的的doFilter()
3、到web.xml中去配置FIlter的拦截路径
2.4、代码实现
1、Filter的代码
1、AdminFilter类
package com.qt.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class AdminFilter implements Filter {
public AdminFilter() {
System.out.println("111 构造器方法");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("222 init");
// 1、获取filter的名称:filter-name
System.out.println("filter-name:"+filterConfig.getFilterName());
// 2、获取web.xml中的init-param配置文件
System.out.println("init-param:"+filterConfig.getInitParameter("username"));
System.out.println("init-param:"+filterConfig.getInitParameter("url"));
// 3、获取ServletContext对象
System.out.println("filter-对象为:"+filterConfig.getServletContext());
//
}
/**
* 用于拦截请求的方法
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("333 doFilter");
HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
if(user==null){
servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
return;
}else {
//让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
System.out.println("444 destroy");
}
}
2、web.xml中的配置文件
1、Filter过滤器中的web.xml 配置
<!-- 配置filter过滤器的拦截路径-->
<filter-mapping>
<!-- 表示当前的拦截路径给哪个filter使用-->
<filter-name>AdminFilter</filter-name>
<!-- 配置拦截路径
/表示请求地址为:http://ip:port/工程路径/ 映射到idea的文本路径
/admin/* 表示:请求地址:http://ip:port/工程路径/admin/*
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
2、Servlet程序的web.xml配置
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.qt.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
3、完整的用户登录页面
1、login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是登录页面 login.jsp页面
<form action="http://localhost:8080/15_Filter/loginServlet" method="get">
用户名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
2、a.jsp 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
我是a.jsp文件
<%
System.out.println("a.jsp页面执行了");
Object user = session.getAttribute("user");
if(user==null){
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}
%>
</body>
</html>
3、FIlter的生命周期
3.1、生命周期包含的方法
1、实现FIlter接口的实现类就会有这些方法
1、构造器方法
1、第一个执行
2、代码
public xxxxx() { //xxxxx是构造器名称
}
3、构造器需要自己添加
2、init初始化方法
1、第二个执行
2、代码
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
3、doFilter过滤方法
1、第三个执行
2、每次拦截到请求,就会执行
3、代码
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
4、destroy销毁
1、最后一个执行
2、停止web工程时,才会执行。
4、FilterConfig类
4.1、内容
1、FIlterConfig是FIlter过滤器的配置文件类
2、tomcat每次创建FIlter时候,就会同时创建一个FIlterConfig类。这里包含了FIlter配置文件的配置信息。
4.2、FilterConfig类的作用
1、内容
1、获取filter过滤器的配置内容
2、获取Filter的名称:filter-name的内容
3、获取Filter中配置的init-param初始化参数
4、获取ServletContext对象
2、例子
1、java代码

2、web.xml配置文件

5、FilterChain过滤器链
5.1、内容
1、FilterChain:是过滤器链,是让多个过滤器如何同时工作的
5.2、图解

1、FilterChain.doFilter()方法的作用
1、执行下一个FIlter过滤器(如果有的话)
2、执行目标资源(没有Filter)
2、在多个FIlter过滤器执行的时候,它们的执行顺序是由他们的web.xml中从上到下配置的顺序决定的!!!
3、多个Filter过滤器执行的特点
1、所有FIlter和目标资源默认都执行在同一个线程中
2、多个Filter共同执行的时候,它们都使用同一个Request对象
6、Filter的拦截路径
6.1、精确匹配
1、内容

6.2、目录匹配
1、内容

6.3、后缀名匹配
1、内容

6.4、Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!
7、ThreadLocal的使用
7.1、内容
1、ThreadLocal的作用,是解决多线程的数据安全问题
2、ThreadLocal:可以给当前线程关联的一个数据(可以是普通变量、可以是对象、可以是数组、集合)
7.2、ThreadLocal的特点
1、ThreadLocal可以为当前线程关联一个数据。(它可以像Map一样存取数据、key为当前线程)
2、每一个ThreadLocal对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个ThreadLocal对象实例。
3、每个ThreadLocal对象实例定义的时候,一般都是static类型
4、ThreadLocal中保存数据,在线程销毁后。会由JVM虚拟自动释放