文章目录

  • 一、过滤器概述
  • 1、过滤器的作用
  • 2、过滤器的应用场景
  • 3、过滤器的工作流程
  • 二、过滤器生命周期与方法
  • 1、过滤器的生命周期
  • 2、过滤器方法
  • 3、过滤器的实现步骤
  • 三、多个过滤器和 dispatcher
  • 1、多个过滤器
  • 2、dispatcher



JSP 和 Servlet 中的过滤器都是 Java 类(继承avax.servlet.Filter)。

一、过滤器概述

1、过滤器的作用

过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息,可以实现以下目的:

  1. 在客户端的请求访问后端资源之前,拦截这些请求。
  2. 在服务器的响应发送回客户端之前,处理这些响应。

2、过滤器的应用场景

  1. Web资源权限访问控制
  2. 请求字符集编码处理
  3. 内容敏感字符词汇速滤
  4. 响应信息压缩

3、过滤器的工作流程

过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明,然后映射到应用程序的部署描述符中的 Servlet 名称或 URL 。当 Web 容器启动 Web 应用程序时,它会为您在部署描述符中声明的每一个过滤器创建一个实例。

JAVA 过滤器的作用 java过滤器的作用有哪些_过滤器

二、过滤器生命周期与方法

1、过滤器的生命周期

  1. web应用程序启动时, web服务器创建Filter的实例对象,以及对象的初始化。
  2. 当请求访问与过滤器关联的Web资源时,过滤器拦截请求,完成指定功能。
  3. Filter对象创建后会驻留在内存,在web应用移除或服务器停止时才销毁。
  4. 过滤器的创建和销毁由WEB服务器负责。

2、过滤器方法

方法

描述

public void init(FilterConfig filterConfig)

web 应用程序启动创建Filter 的实例对象,调用init方法,同时读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(每个filter对象只会创建一次,init方法也只会执行一次)。

public void doFilter (ServletRequest, ServletResponse, FilterChain)

该方法完成实际的过滤操作,当请求访问的url和请求方法与过滤器设置url和方式匹配时,将调用过滤器的doFilter方法。

public void destroy()

Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

3、过滤器的实现步骤

  1. 编写java类实现Filter接口,并实现其doFilter方法。
  2. 在web.xml文件中对filter类进行注册,并设置所拦截的资源。
  • web.xml配置
<!-- 字符集编码过滤器配置 -->
<filter>
    <filter-name>characterEncodingFilter</filter-name>  <!-- 过滤器的唯一标识 -->
    <filter-class>filter.CharacterEncodingFilter</filter-class>  <!-- 过滤器执行的类 -->
    <init-param>  <!-- 过滤器初始化参数,可为多个 -->
    	<param-name>charset</param-name>
    	<param-value>UTF-8</param-value>
	</init-param>
</filter>
<filter-mapping>  <!-- 过滤器映射 -->
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>  <!-- 对所有的请求进行拦截处理 -->
</filter-mapping>
  • 过滤器类
public class CharacterEncodingFilter implements Filter {
    private FilterConfig config;    // 过滤器配置对象,用于获取配置的参数
    
    public FilterConfig getConfig() {
        return config;
    }
    
    public void setConfig(FilterConfig config) {
        this.config = config;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
        System.out.println("CharacterEncodingFilter do init....");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //获取初始参数
        String charset = config.getInitParameter("charset");

        // 设置请求内容的编码方式
        servletRequest.setCharacterEncoding(config.getInitParameter("charset"));
        
        //System.out.println("CharacterEncodingFilter 请求预处理");
        // 通知过滤器链这步过滤操作已完成
        filterChain.doFilter(servletRequest, servletResponse);
        //System.out.println("CharacterEncodingFilter 响应后处理");
    }

    @Override
    public void destroy() {
        System.out.println("CharacterEncodingFilter do destroy....");
    }
}

三、多个过滤器和 dispatcher

1、多个过滤器

只要像上面完成过滤器类的编写和注册,就可以啦,web服务器会在后台建立过滤器链进行管理。

  • 过滤器链
  1. 在一个web应用中,多个过滤器组合起来称之为一个过滤链。
  2. 过滤器的调用顺序(预处理顺序)取决于web.xml 中的 filter-mapping 元素的顺序,后处理是其逆序。

2、dispatcher

dispatcher 是 filter-mapping 的子元素,用于指定拦截何种请求方式的url,其设置的值及其含义如下表:

dispatcher设置值

描述

REQUEST(默认)

当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。

INCLUDE

如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

FORWARD

如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

ERROR

如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用

dispatcher 默认值为 REQUEST ,dispatcher 也可设置为多个已拦截不同形式的访问。

<filter>
    <filter-name>testFilter</filter-name>
    <filter-class>filter.TestFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>testFilter</filter-name>
    <url-pattern>/test2.jsp</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>
  • 测试
<%
	//测试dispatcher FORWARD配置
	//request.getRequestDispatcher("/test2.jsp").forward(request, response);

    //测试dispatcher ERROR配置
	//response.sendError(404);
%>
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
	<!-- 测试dispatcher INCLUDE配置 -->
	<jsp:include page="test2.jsp"></jsp:include>
	<h1>Test</h1>
</body>
</html>