什么是Filter过滤器

  • 1 filter 过滤器是javaweb的三大组件之一,分别为 servlet程序 listenser 监听器, filter过滤器
  • 2 filter 过滤器是 java ee 的规范,也就是接口
  • 3 filter 过滤器它的作用是 拦截请求,过滤响应

    过滤器常见的使用场景

  • 1 权限检查

  • 2 日期操作
  • 3 事务管理
  • 4 etc。。。

    入门实践

  • 需求: 在web工程下有一个admin目录,对admin目录下所有资源进行过滤,要求作为用户登录之后才可访问

  • 步骤
    • 创建类, 实现Filter接口。注意不要引错包
    • 实现过滤方法 doFilter()
    • 在web.xml 中进行注册,让服务器发现过滤器 ```java package com.addicated.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 {

  1. @Override
  2. public void init(FilterConfig filterConfig) throws ServletException {
  3. // 1 获取filter 的名称 filter-name 的内容
  4. System.out.println(filterConfig.getFilterName());

// 2 获取在filter 中陪孩子的init-param 初始化参数 System.out.println(filterConfig.getInitParameter(“username”)); // 3 获取 servletContext对象 System.out.println(filterConfig.getServletContext());

}

/*
 * @Author shihu
 * @Description //TODO 专门用于拦截请求, 执行过滤方法
 * @Date 5:28 下午 2021/9/12
 * @Param [servletRequest, servletResponse, filterChain]
 * @return void
 **/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

    HttpSession session = null;
    session = httpServletRequest.getSession();
    Object user = session.getAttribute("user");
    if (user == null) {
        // 说明没有登录 ,请求分发到登录去
        httpServletRequest.getRequestDispatcher("/login.jsp").forward(httpServletRequest, servletResponse);
    } else {
        // 让程序继续往下访问用户的目标资源
        filterChain.doFilter(servletRequest, servletResponse);
    }

}

@Override
public void destroy() {

}

}


- web.xml 中进行注册,使filter生效
```java
  --    filter标签用于配置一个filter过滤器-->
        <filter>
            <filter-name>AdminFilter</filter-name>
            <filter-class>com.addicated.filter.AdminFilter</filter-class>
        </filter>

    <!--    指定哪些访问路径需要经过filter进行过滤-->
        <filter-mapping>
            <filter-name>AdminFilter</filter-name>
    <!--
        url-pattern 配置拦截路径
        / 表示请求地址为  http://ip:port/工程路径/  映射到 idea 下的web目录


     -->
            <url-pattern>/admin/* </url-pattern>
        </filter-mapping>

注意点

  • 当有多个filter的时候,需要注意在doFilter()方法中,对于后续的调用要写 filterChain.doFilter(),否则程序将不再向下运行,此时访问任意资源都会变为空白。

      if (user ==null){
                  // 说明没有登录 ,请求分发到登录去
                  httpServletRequest.getRequestDispatcher("/login.jsp").forward(httpServletRequest,servletResponse);
              }else {
                  // 让程序继续往下访问用户的目标资源  如果不写,则会导致后面访问资源都为空白
                  filterChain.doFilter(servletRequest,servletResponse);
    
              }
    
  • 关于filter的执行顺序,,同时存在多个filter的情况下,执行顺序按照web.xml中的注册顺序从上向下执行。

    Filter的生命周期

  • filter的生命周期包含几个方法

    • 1 构造器方法
    • 2 init 初始化方法
      • 第1,2步在web工程启动的时候执行 filter已经创建
    • 3 doFilter 过滤方法
      • 3 每次拦截到就会执行
    • 4 destory 销毁方法
      • 4 web工程停止的时候就会执行

        FilterConfig类

  • 这个类的定位其实与servletConfig类有些相似

  • 顾名思义,其为filter过滤器的配置类,tomcat每次创建filter对象的时候也会创建一个filterConfig对象,这里面包含了filter配置文件的配置信息

    作用

  • 用来获取filter的配置内容

  • 1 获取filter的名称 filter-name的内容
  • 2 获取在filter 中陪孩子的init-param 初始化参数
  • 3 获取 servletContext对象

          1 获取filter的名称 filter-name的内容
          2 获取在filter 中陪孩子的init-param 初始化参数
          3 获取 servletContext对象
                 // 1  获取filter 的名称 filter-name 的内容
                  System.out.println(filterConfig.getFilterName());
          //        2 获取在filter 中陪孩子的init-param 初始化参数
                  System.out.println(filterConfig.getInitParameter("username"));
          //        3 获取 servletContext对象
                  System.out.println(filterConfig.getServletContext());
    

    FilterChain 过滤器链

  • 顾名思义,就是多个过滤器一起工作

  • 上面提到的filterChain.doFilter(request,respons)方法的作用
    • 如果存在下一个 filter过滤器 则执行
    • 如果下面不存在filter过滤器,则执行访问目标资源
  • 存在多个filter的情况,按照web.xml中注册的顺序自上而下依次执行

    特点

  • 所有filter和目标资源默认执行在同一个线程中

  • 多个filter共同执行的时候,共用一个request对象,这就意味着多个filter之间是可以共享域中变量属性

    关于Filter的拦截路径

    精确匹配

     <url-pattern>/target.jsp</url-pattern>
     以上路径表示请求地址必须 为 ip:port/工程路径/target.jsp
    

    目录匹配

     <url-pattern>/admin/*</url-pattern>
     以上配置路径表示,表示请求地址为 http://ip:port/工程目录/admin/*
    

    后缀名匹配

    <url-pattern>*.html</url-pattern>
     以上配置路径表示,请求地址必须以.html 极为才会拦截到
     后缀名匹配方式前不用写斜杠/
    

    web.xml配置

    ```java <?xml version=”1.0” encoding=”UTF-8”?>
<filter>
    <filter-name>AdminFilter</filter-name>
    <filter-class>com.addicated.filter.AdminFilter</filter-class>

    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>

</filter>
<filter-mapping>
    <filter-name>AdminFilter</filter-name>
    <url-pattern>/admin/* </url-pattern>
</filter-mapping>

```