过滤器Filter介绍和使用

一、Filter介绍

过滤器概念

  • 客户端与服务器资源文件之间的一道过滤网;
  • 管理Web服务器的所有资源,例如对JSP、Servlet、静态图片文件或静态HTML文件等进行拦截;
  • 可以过滤几乎所有的请求,完成一些特殊的功能;
  • Filter依赖于Servlet容器,属于Servlet规范的一部分;
  • Filter的执行由Servlet容器回调完成;
  • Filter的生命周期由Servlet容器管理。

过滤器使用场景

完成通用的操作:登陆验证、URL级别的权限访问控制、压缩响应信息、统一编码处理、过滤敏感字符等等。

过滤器实现步骤

  • 定义一个类,实现javax.servlet.Filter接口;
  • 复写方法,尤其是doFilter方法,必须实现;
  • 配置过滤器信息。
    • web.xml
    • @WebFilter注解
    • @Configuration配置类

过滤器生命周期

Filter的生命周期由Servlet容器管理:

  • init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源。
  • doFilter:每一次请求被拦截资源时,会执行。执行多次。
  • destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源。

过滤器拦截路径配置

  • 具体的资源路径: /hello.jsp 只访问hello.jsp资源时,过滤器才会被执行
  • 拦截目录: /hello/* 访问/hello下的所有资源时,过滤器才会被执行
  • 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器才会被执行
  • 拦截所有资源: /* 访问所有资源时,过滤器才会被执行

过滤器拦截请求调度方式配置

  • 请求调度方式
    • REQUEST:默认值。浏览器直接请求资源
    • FORWARD:转发访问资源
    • NCLUDE:包含访问资源
    • ERROR:错误跳转资源
    • ASYNC:异步访问资源
  • web.xml配置:<filter-mapping>中的<dispatcher>标签
  • @WebFilter注解配置:dispatcherTypes属性
  • @Configuration配置类:FilterRegistrationBean对象的dispatcherTypes属性

过滤器链(多个过滤器)调用的先后顺序

  • web.xml: <filter-mapping>定义在上边的,先执行
  • @WebFilter注解:按照类名字符串比较规则比较,值小的先执行(注意不是配置的filter的名字)
    • 如: AFilter 和 BFilter,AFilter就先执行了。
    • 如: AFilter17 和 AFilter6,AFilter17就先执行了。
  • @Order注解:值小的先执行
  • Configuration配置类:FilterRegistrationBean对象的order属性:值小的先执行
  • @WebFilter指定的过滤器优先级都高于FilterRegistrationBean配置的过滤器

过滤器链(多个过滤器)执行的先后顺序

  • FilterChain的执行顺序遵循先进后出原则
  • 以doFilter方法中调用filterChain.doFilter(servletRequest,servletResponse)的位置为准,这里放行到下一个过滤器;
  • filterChain.doFilter位置之前的代码先执行,然后再放行;
  • filterChain.doFilter位置之后的代码是响应回来后再执行;
  • Request请求被所有的Filter处理之后,返回的顺序是从最后一个开始返回,直到返回给客户端

二、Filter使用

Java Web使用Filter

基于实现Filter + web.xml配置

创建一个类,实现javax.servlet.Filter接口,尤其是doFilter方法;

package com.liutit.filter;

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

public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客户端发送请求经过过滤器,
        // 这里一般处理请求对象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服务器响应请求后,经过此处,然后再到客户端,
        // 这里一般处理响应对象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

在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_3_1.xsd"
         version="3.1">
   <filter>
      <filter-name>demo</filter-name>
      <filter-class>com.liutit.filter.DemoFilter</filter-class>
   </filter>
   <!-- filter-mapping标签定义的位置决定多个过滤器调用的顺序,由上而下依次调用, 与filter标签的定义位置无关-->
   <filter-mapping>
      <filter-name>demo</filter-name>
      <!-- 拦截路径 -->
      <url-pattern>/*</url-pattern>
      <!-- 拦截方式 -->
      <dispatcher>REQUEST</dispatcher>
   </filter-mapping>
</web-app>

基于实现Filter + @WebFilter注解

创建一个类,实现javax.servlet.Filter接口,尤其是doFilter方法,并在类上添加@WebFilter注解;

package com.liutit.filter;

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

@WebFilter("/*")
public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客户端发送请求经过过滤器,
        // 这里一般处理请求对象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服务器响应请求后,经过此处,然后再到客户端,
        // 这里一般处理响应对象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

Spring Boot使用Filter

pom.xml导入pring-boot-starter-web包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

基于实现Filter + 配置Configuration类

package com.liutit.filter;

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

public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客户端发送请求经过过滤器,
        // 这里一般处理请求对象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服务器响应请求后,经过此处,然后再到客户端,
        // 这里一般处理响应对象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

Configuration类

package com.liutit.config;

import com.liutit.filter.DemoFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.DispatcherType;

@Configuration
public class FilterConfiguration {

    @Bean
    public FilterRegistrationBean registrationFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        // 设置过滤器
        filterRegistration.setFilter(new DemoFilter());
        // 指定url策略
        filterRegistration.addUrlPatterns("/*");
        // 指定过滤请求调度方式,默认REQUEST
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        // 设置过滤器名称
        filterRegistration.setName("demoFilter");
        // 过滤器顺序:数字越小,越先执行
        filterRegistration.setOrder(1);
        return filterRegistration;
    }
}


基于实现Filter + @WebFilter注解 + @ServletComponentScan注解

package com.liutit.filter;

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

@Order(1)
@WebFilter("/*")
public class DemoFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 客户端发送请求经过过滤器,
        // 这里一般处理请求对象Request
        System.out.println("filter in....");
        
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        
        // 服务器响应请求后,经过此处,然后再到客户端,
        // 这里一般处理响应对象Response
        System.out.println("filter out....");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

启动类上添加@ServletCoponentScan注解

在启动类上使用@ServletComponentScan注解后,
Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册。

package com.liutit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

友情链接更多精彩内容