一、过滤器的执行流程:

HelloFilter.java:

package com.filter.demo;

import javax.servlet.*;
import java.io.IOException;

/**
 * Filter 也称之为 过滤器,他是 Servlet 技术中最激动人心的技术,web 开发人员通过 filter 技术,对 web 服务器管理的
 * 所有 web 资源,例如 jsp、servlet、静态图片文件、或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现
 * URL 级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
 *
 * Servlet API 中提供了一个 Filter 接口,开发 web 应用时,如果编写的 java 类实现了这个接口,则把这个 java 类称之为
 * 过滤器(Filter)。通过 filter 技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:
 * |————————|           |————————————|          |——————————|            |——————————|
 * |        |   ——————> |            |  ——————> |          |  ————————> | servlet  |
 * | 浏览器 |            | web服务器  |          |  过滤器  |            |  jsp     |
 * |        |   <—————— |            |  <—————— |          |  ————————> |  html    |
 * |————————|           |————————————|          |——————————|            |——————————|
 *
 * 过滤器执行流程:
 *  1、服务器启动的时候先创建 过滤器对象,然后初始化过滤器;(步骤 1、2)
 *  2、浏览器客户端访问服务器时,先进入过滤器,执行 doFilter 方法,处理过滤业务,过滤器执行完成后放行;(步骤 3)
 *  3、过滤器放行后进入 servlet,处理用户请求;(步骤 4)
 *  4、servlet 处理完成之后,又回到 过滤器;(步骤 5)
 *  5、服务器关闭的时候,销毁 过滤器对象;(步骤 6)
 */
public class HelloFilter implements Filter {
    // 构造方法
    public HelloFilter() {
        System.out.println("1、创建过滤器实例。");
    }

    // 初始化方法
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2、执行过滤器初始化方法。");
    }

    // 过滤器业务处理方法,在请求到达 servlet 之前先进入此方法处理公用的业务逻辑操作
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        System.out.println("3、执行过滤器业务处理方法。");

        // 放行:进入目标资源。如果有下一个过滤器,则进入下一个过滤器。
        filterChain.doFilter(servletRequest, servletResponse);

        System.out.println("5、servlet 处理完成,又回到过滤器。");
    }

    @Override
    public void destroy() {
        System.out.println("6、销毁过滤器实例。");
    }
}

HelloServlet.java:

package com.filter.demo;

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

@WebServlet(name = "HelloServlet", value = "/helloServlet")
public class HelloServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("4、处理用户请求开始。");
    }

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

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置过滤器 -->
    <filter>
        <!-- filter 名称 -->
        <filter-name>filter</filter-name>
        <!-- 过滤器类的全名 -->
        <filter-class>com.filter.demo.HelloFilter</filter-class>
    </filter>
    <filter-mapping>
        <!-- filter 名称 -->
        <filter-name>filter</filter-name>
        <!-- 拦截所有资源 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

执行结果:

Java 过滤器如何起作用 java的过滤器_java

 

二、获取过滤器的初始化参数:

在 init 方法中通过 filterConfig 对象获取 初始化参数:

@Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2、执行过滤器初始化方法。");

        // 获取初始化参数:根据指定的参数名获取参数值
        String encoding = filterConfig.getInitParameter("encoding");
        System.out.println("encoding: " + encoding);

        // 获取所有初始化参数
        Enumeration<String> enums = filterConfig.getInitParameterNames();
        while(enums.hasMoreElements()){
            String name = enums.nextElement(); // 获取初始化参数名
            String value = filterConfig.getInitParameter(name); // 根据参数名获取参数值
            System.out.println(name + "=" + value);
        }
    }

在 web.xml 中配置 初始化参数: 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置过滤器 -->
    <filter>
        <!-- filter 名称 -->
        <filter-name>filter</filter-name>
        <!-- 过滤器类的全名 -->
        <filter-class>com.filter.demo.HelloFilter</filter-class>

        <!-- 配置初始化参数 -->
        <init-param>
            <param-name>encoding</param-name>   <!-- 参数名 -->
            <param-value>UTF-8</param-value>    <!-- 参数值 -->
        </init-param>
        <init-param>
            <param-name>username</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>123</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <!-- filter 名称 -->
        <filter-name>filter</filter-name>
        <!-- 拦截所有资源 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

执行结果:

Java 过滤器如何起作用 java的过滤器_xml_02

三、拦截指定的请求: 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置过滤器 -->
    <filter>
        <!-- filter 名称 -->
        <filter-name>filter</filter-name>
        <!-- 过滤器类的全名 -->
        <filter-class>com.filter.demo.HelloFilter</filter-class>
    </filter>
    <filter-mapping>
        <!-- filter 名称 -->
        <filter-name>filter</filter-name>

        <!-- 1、拦截所有资源:访问任何目标资源都会进入过滤器;
        <url-pattern>/*</url-pattern>-->

        <!-- 2、拦截指定 jsp:如果要拦截多个指定的 jsp,可以写多个 <url-pattern> 标记,如下所示;
            只有在地址栏输入:http://localhost:8080/06_Filter_war_exploded/index.jsp
            或者:http://localhost:8080/06_Filter_war_exploded/list.jsp 时才会进入 过滤器;
        <url-pattern>index.jsp</url-pattern>
        <url-pattern>list.jsp</url-pattern>  -->

        <!-- 3、拦截所有 jsp:访问任意 jsp 资源都会进入 过滤器;
        <url-pattern>*.jsp</url-pattern> -->

        <!-- 4、拦截指定的 servlet:
            只有在地址栏输入:http://localhost:8080/06_Filter_war_exploded/helloServlet 才会进入过滤器;
        <url-pattern>/helloServlet</url-pattern> -->

        <!-- 5、根据指定的 servlet 名称拦截:只有在访问 servlet 名称为 HelloServlet 的资源时才会进入 过滤器;
        <servlet-name>HelloServlet</servlet-name> -->

        <!-- 6、拦截指定的类型: -->
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>    <!-- 默认:拦截请求(直接访问或者重定向) -->
        <dispatcher>FORWARD</dispatcher>    <!-- 拦截转发 -->
        <dispatcher>INCLUDE</dispatcher>    <!-- 拦截包含的页面 -->
        <dispatcher>ERROR</dispatcher>      <!-- 拦截声明式异常页面 -->
    </filter-mapping>

</web-app>