文章目录

  • Filter过滤器
  • Filter初体验
  • Filter的生命周期
  • FilterConfig类
  • FilterChain过滤器链
  • Filter过滤器的拦截路径
  • 精确匹配
  • 目录匹配
  • 后缀名匹配


Filter过滤器

什么是Filter过滤器?

答:Filter过滤器是JavaWeb三大组件之一,三大组件分别是Servlet程序、Listener监听器以及Filter过滤器。Filter过滤器是JavaEE的规范,也就是接口。器最主要的作用是连接请求,响应过滤。

兰姐请求的应用场景——权限检查、日志管理

Filter初体验

需求:在web工程下,又一个admin目录,这个admin目录下的所有资源(html页面、jpg图片、jsp文件、等等)都必须是用户登录之后才允许访问

分析:根据先前所学分析,用户的登陆信息都会存在在session域中,因此只需要判断当前session域中是否有用户信息即可判断当前用户是否登陆

Object user = session.getAttribute("user");
if(user == null){
  request.getRequestDispatcher("/login.jsp").forward(request,response);
  return
}

上述过程是未使用Filter的方法,但如果是html页面则无法实现上述逻辑,因此上述方法具有很大的局限性。而Filter能很好地解决上述问题,其运行流程如下图所示

Java中带过滤属性的方法 java过滤器filter_System

Filter过滤器的使用步骤:

  1. 编写一个类去实现Filter接口,并实现doFilter方()
public class AdminFilter implements Filter {
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		// 这里有雨doFilter中的参数没有获取session的方法,这里需要对其进行类型强转
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    HttpSession session = httpServletRequest.getSession();
    Object user = session.getAttribute("user");
    // 如果等于 null,说明还没有登录
    if (user == null) {
      servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest, servletResponse);
      return;
    }else {
      // 让程序继续往下访问用户的目标资源
      filterChain.doFilter(servletRequest, servletResponse);		//这句话很重要
    }
  }
}
  1. 到web.xml中去配置filter拦截路径
<filter>
  <!--给 filter 起一个别名-->
  <filter-name>AdminFilter</filter-name>
  <!--配置 filter 的全类名-->
  <filter-class>filter.AdminFilter</filter-class>
</filter>


<!--filter-mapping 配置 Filter 过滤器的拦截路径-->
<filter-mapping>
  <!--filter-name 表示当前的拦截路径给哪个 filter 使用-->
  <filter-name>AdminFilter</filter-name>
  <!--url-pattern 配置拦截路径
  /表示请求地址为:http://ip:port/工程路径/ 映射到IDEA的web目录
  /admin/* 表示请求地址为:http://ip:port/工程路径/admin/* -->
  <url-pattern>/admin/*</url-pattern>
</filter-mapping>
  • 也就是每当有用户希望访问/admin/*目录下的文件时,web项目都会让其去先访问filter.AdminFilter过滤器,然后韩兆过滤器中编写的逻辑执行。
  • 在step1中的过滤器便携逻辑中,如果当前session中用户信息为空,则说明用户未登陆,让其访问login.jsp,直到用户成功登陆,才能让其通过过滤器,访问用户的目标资源。

Filter的生命周期

Filter的生命周期包括以下几个部分

  1. 构造器方法
  2. init初始化方法
  • 说明:在web工程启动的时候,第一步第二步就已经执行,成功将Filter过滤器创建并初始化好了
  1. doFilter过滤方法
  • 每次拦截到请求就会执行
  1. destroy方法
  • 终止Web工程时执行(停止web工程,也会销毁Filter过滤器)
public class AdminFilter implements Filter {
  public AdminFilter() {
    System.out.println("1、Filter的AdminFilter()构造器方法 ");
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("2、Filter的init(FilterConfig filterConfig)初始化方法 ");
  }
  
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("3、Filter的doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)方法 ");
  }

  @Override
  public void destroy() {
    System.out.println("4、Filter的destroy() 销毁方法 ");
  }
}

FilterConfig类

FilterConfig类见名知义,其是Filter过滤器的配置文件类,Tomcat每次创建Filter的时候,也会同时创建一个FilterConfig类,这里包含了Filter配置文件的配置信息。

FilterConfig类的作用是获取filter过滤器的配置内容

  1. 获取Filter的filter-name的内容
  2. 获取在Filter中配置的init-param初始化参数
  3. 获取ServletContext对象。

在初始化时就有filterConfig对象,可以直接调用

@Override
public void init(FilterConfig filterConfig) throws ServletException {
  System.out.println("2、Filter的init(FilterConfig filterConfig)初始化方法 ");

  //         1、获取 Filter 的名称 filter-name 的内容
  System.out.println("filter-name -> " + filterConfig.getFilterName());
  //         2、获取在 Filter 中配置的 init-param 初始化参数
  System.out.println("初始化参数username的值是 -> " + filterConfig.getInitParameter("username"));
  System.out.println("初始化参数 url 的值是 -> " + filterConfig.getInitParameter("url"));
  //         3、获取 ServletContext 对象
  System.out.println(filterConfig.getServletContext());
}

对应的xml配置信息如下

<filter>
        <filter-name>AdminFilter</filter-name>
        <filter-class>filter.AdminFilter</filter-class>
        
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>

        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/test</param-value>
        </init-param>
    </filter>

效果图:


FilterChain过滤器链

FilterChain,就是多个过滤器如何一起工作,具体工作流程如下图所示(责任链模式)

Java中带过滤属性的方法 java过滤器filter_Java中带过滤属性的方法_02

由上图可知,客户端发起的请求在多个过滤器以及目标资源中传递。自始至终都只有一个request和一个response,因此彼此之间可以通过request域实现数据共享以及传递处理,并且服务器中处理这些请求和响应的程序是中都是由一个进程来完成。

Filter过滤器的拦截路径

精确匹配

<url-pattern>/target.jsp</url-pattern>

以上配置的路径表示请求地址必须为:http://ip:port/工程路径/target.jsp

目录匹配

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

以上配置的路径表示请求地址必须为:http://ip:port/工程路径/admin/*

后缀名匹配

<url-pattern>*.html</url-pattern>

以上的配置路径,表示请求地址必须是以html结尾,才会拦截到

注意:

  • 这里.字符串不一定是类型,也可以是*.abc等字符串类型,且不需要以/开头
  • Filter只关心请求地址是否匹配,不关心请求资源是否存在。