SpringMVC之过滤器(Filter)

一、概述

1.1 含义

过滤器是Web三大组件之一,也是项目中常用的工具。过滤器由Servlet提供,基于函数回调实现链式对网络请求和响应的拦截与修改。由于基于Servlet,几乎可以拦截Web服务器管理的所有资源(JSP、图片文件、HTML文件、CSS文件等)。

定义过滤器需要实现javax.servlet.Filter接口。过滤器不是Servlet,无法直接生成对客户端的响应,只能拦截已有请求并预处理不需要或不一致的信息资源。

1.2 流程原理

在Web应用中,可以开发编写多个过滤器,这些过滤器组合称为过滤器链。用户发起请求后,请求信息会按过滤器链中过滤器的顺序依次进入每个过滤器。经过每层过滤器时,需通过过滤器的校验逻辑并放行才能进入下一层过滤器,直至服务器获取资源。服务器成功获取资源并响应过滤器后,会按反向顺序经过层层过滤器,最终响应用户。

1.3 分类

Servlet 2.5:

  • REQUEST: 用户直接访问页面时,WEB容器会调用过滤器链。
  • FORWARD: 通过RequestDispatcher的forward访问目标资源时调用此过滤器。
  • INCLUDE: 通过RequestDispatcher的include方法调用目标资源时调用。
  • ERROR: 通过声明式异常处理机制调用目标资源时调用过滤器链。

Servlet 3.0:

  • ASYNC: 支持异步处理。

二、定义过滤器

返回值类型 方法声明 描述
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 实现实际过滤操作。当客户端请求方法与过滤器设置的URL匹配时,Servlet容器会先调用过滤器的doFilter方法。FilterChain用于访问后续过滤器。
void init(FilterConfig filterConfig) Web应用启动时,Web服务器创建过滤器实例对象并调用其init方法完成对象初始化(过滤器对象仅创建一次,init方法仅执行一次)。开发者可通过init方法参数执行读取配置文件等初始化操作。
void destroy() Servlet容器销毁过滤器实例前调用此方法。用于释放过滤器占用的资源。
  • request: 代表客户端的请求对象。
  • response: 代表服务器向客户端发送的响应对象。
  • chain: 用于调用下一个Filter或目标Servlet的FilterChain对象。

三、使用过滤器

3.1 注解方式

创建步骤:

  1. 实现Filter接口,添加@WebFilter和@Order注解配置过滤器:

    java 复制代码
    @Order(1)
    @WebFilter(filterName = "myFilter", urlPatterns = {"*"})
    public class MyCustomFilter1 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {}
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                             FilterChain filterChain) {
            //TODO...
        }
    
        @Override
        public void destroy() {}
    }
  2. 在启动类添加@ServletComponentScan注解:

    java 复制代码
    @SpringBootApplication
    @ServletComponentScan
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }

3.2 注册Bean方式

  1. 创建实现Filter接口的过滤器类:

    java 复制代码
    public class MyCustomFilter2 implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException { }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                             FilterChain filterChain) {
            //TODO...
        }
    
        @Override
        public void destroy() { }
    }
  2. 创建过滤器配置类,注册过滤器:

    java 复制代码
    @Configuration
    public class FilterConfig {
        @Bean
        public FilterRegistrationBean customFilter(){
            FilterRegistrationBean<MyCustomFilter2> filterBean = new FilterRegistrationBean<>();
            filterBean.setFilter(new MyCustomFilter2());
            filterBean.setName("myFilter");
            filterBean.addUrlPatterns("/*");
            return filterBean;
        }
    }

四、注解方式

4.1 参数说明

@WebFilter可配置多个参数,部分参数说明如下:

参数名称 参数类型 参数描述
description String 设置过滤器的描述信息
displayName String 要显示的过滤器名称
initParams WebInitParam\[\] 你可以在初始化时配置一些参数
filterName String 过滤器的名称
servletNames String\[\] 设置要过滤的Servlets
value String\[\] urlPatterns属性与urlPatterns属性的作用相同,两者都指定要拦截的路径
urlPatterns String\[\] 指定要拦截的路径
dispatcherTypes DispatcherType\[\] 设置过滤器过滤的请求类型。 支持以下属性:REQUEST(默认情况下,它过滤所有类型的请求), ASYNC, ERROR, FORWARD, INCLUDE
asyncSupported boolean 设置过滤器是否支持异步模式

4.2 使用示例

(1) 创建Controller类

java 复制代码
@RestController
public class TestController {

    @GetMapping("/a/hello")
    public String hello1() {
        return "hello world! a";
    }

    @GetMapping("/b/hello")
    public String hello2() {
        return "hello world! b";
    }

    @GetMapping("/c/hello")
    public String hello3() {
        return "hello world! c";
    }
}

(2) 创建过滤器类

java 复制代码
@Order(1)
@WebFilter(filterName = "myFilter", urlPatterns = {"/a/*", "/b/*"}, description = "自定义过滤器")
public class MyCustomFilter2 implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("请求处理前...");
        chain.doFilter(request, response);  // 放行请求
        System.out.println("请求处理后...");
    }

    @Override
    public void destroy() {
        System.err.println("过滤器销毁");
    }
}

(3) 创建启动类

java 复制代码
@SpringBootApplication
@ServletComponentScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

五、注册Bean方式

5.1 方法参数说明

方法名称 方法描述
setName() 设置过滤器的名称。
setFilter() 设置要注册的过滤器。
setOrder() 设置过滤器的顺序位置。
setAsyncSupported() 设置过滤器是否支持异步模式。
addUrlPatterns() 添加拦截的路径。
setUrlPatterns() 设置拦截的路径。
addServletNames() 添加过滤器的servlet名称。
setServletNames() 设置注册过滤器的servlet名称。
setInitParameters() 设置初始化参数。
addInitParameter() 添加初始化参数。
setMatchAfter() 设置是否在Servlet上下文中声明的任何过滤器映射之后匹配过滤器映射。
setDispatcherTypes() 设置过滤器过滤的请求类型。 支持的属性如下:REQUEST(默认情况下,它过滤所有类型的请求), ASYNC, ERROR, FORWARD, INCLUDE。

5.2 使用示例

(1) 创建Controller类

java 复制代码
@RestController
public class TestController {

    @GetMapping("/a/hello")
    public String hello1(){
        return"hello world! a";
    }

    @GetMapping("/b/hello")
    public String hello2(){
        return"hello world! b";
    }

    @GetMapping("/c/hello")
    public String hello3(){
        return"hello world! c";
    }
}

(2) 创建过滤器类

java 复制代码
public class MyCustomFilter1 implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("请求处理前...");
        chain.doFilter(request, response);  // 放行请求
        System.out.println("请求处理后...");
    }

    @Override
    public void destroy() {
        System.err.println("过滤器销毁");
    }
}

(3) 创建过滤器配置类

java 复制代码
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean customFilter() {
        FilterRegistrationBean<MyCustomFilter1> filterBean = new FilterRegistrationBean<>();
        filterBean.setFilter(new MyCustomFilter1());
        filterBean.setName("FilterController");
        filterBean.addUrlPatterns("/c/*", "/b/*");
        return filterBean;
    }
}

(4) 创建启动类

java 复制代码
@SpringBootApplication
@ServletComponentScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

六、使用场景

  1. 日志记录
    过滤器可记录请求和响应的关键信息,便于排查问题和分析系统运行状态。例如记录请求URL、参数、响应状态码等。
  2. 数据统计
    用于采集各类数据指标,如统计请求次数、响应时间分布等,为系统优化提供依据。
  3. 数据格式转换
    不同系统交互时,过滤器可转换数据格式,例如将JSON转为XML。
  4. 为数据设置默认值
    检查输入数据,为缺失字段设置默认值,保证数据完整性。
  5. 权限认证、黑白名单
    实现用户权限认证和访问控制,限制特定IP或用户的访问。
  6. 数据加解密、签名验证
    对敏感数据加解密以保证安全,同时进行签名验证确保数据完整性。
相关推荐
Java爱好狂.6 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
马良神笔8 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD8 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
高频因子挖掘机9 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api
高频因子挖掘机9 小时前
历史行情返回顺序变了,为什么按行号计算指标很危险?
后端·github·api
团子哒哒10 小时前
数组、切片和Map
后端
专注仿真11 小时前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
开心猴爷11 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m5555555511 小时前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
易小尊11 小时前
我的模型在 65% 以上时准得可怕,在 50% 时像在掷硬币
后端