过滤器和拦截器总结

article/2025/9/12 5:18:03

        过滤器和拦截器在日常业务开发中不是经常用到,近来项目中偶尔遇到了,对过滤器和拦截器进行了一次系统学习,现总结如下。

一、过滤器Filter

        1.1 什么是过滤器

                过滤器是Servlet的高级特性之一,是实现Filter接口的Java类。其基本功能就是对servlet的调用进行干预,在servl请求和响应的过程中增加一些特定的功能。可以使用过滤器实现的功能有:统一编码,URL级别的权限访问控制,过滤敏感词汇,压缩请求信息。

        1.2  过滤器的执行

                


   

1.3 Filter接口

        通过看Filter接口代码,其有三个方法:

           

public interface Filter {default void init(FilterConfig filterConfig) throws ServletException {}void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;default void destroy() {}
}

       init(FilterConfig conf)方法:用于执行过滤器的初始化工作,web容器会在web项目启动时自动调用该方法。

        doFilter(ServletRequest request,SerlvetResponse response,FilterChain chain)方法:当请求和响应被过滤器拦截后,都会交给doFilter来处理:其中两个参数分别是被拦截request和response对象,可以使用chain的doFliter方法来放行。

        destroy()方法:用于释放关闭Filter对象打开的资源,在web项目关闭时,由web容器自动调用该方法。

1.4 如何开发一个Filter

        开发一个过滤器比较简单,第一步实现Filter接口,第二步配置过滤器

开发一个简单的filter代码如下:

package com.lsl.mylsl.filter;import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;@Component
@WebFilter(filterName = "myFilter",urlPatterns = {"/*"})
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//获取filter名字String filterName = filterConfig.getFilterName();//获取filter里配置的init-param配置指定参数的值,如果参数不存在,则返回 nullString email = filterConfig.getInitParameter("email");//获取filter里配置的init-param配置所有参数值,如果过滤器没有初始化参数,则返回一个空的 EnumerationEnumeration<String> initParameterNames = filterConfig.getInitParameterNames();//返回对调用者在其中执行操作的 ServletContext 的引用。ServletContext servletContext = filterConfig.getServletContext();}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;//统一编码处理httpRequest.setCharacterEncoding("UTF-8");httpResponse.setContentType("text/html;charset=UTF-8");//添加name属性httpRequest.setAttribute("name", "tom");//获取请求中的所有cookieCookie[] cookies = httpRequest.getCookies();if (cookies != null) {StringBuilder sb = new StringBuilder();for (Cookie cookie : cookies) {String cookieName = cookie.getName();String cookieValue = cookie.getValue();//设置cookie的相关属性ResponseCookie lastCookie = ResponseCookie.from(cookieName, cookieValue).httpOnly(true).sameSite("Lax").build();httpResponse.addHeader(HttpHeaders.SET_COOKIE, lastCookie.toString());}filterChain.doFilter(httpRequest, httpResponse);}}@Overridepublic void destroy() {}
}

第二步配置filter:

        filter配置有三种方式,上面的代码中是其中一种配置(注解配置)。

                第一种:在web.xml配置

                

<filter><filter-name>myFilter</filter-name><filter-class>com.lsl.mylsl.filter.MyFilter</filter-class><init-param><param-name>email</param-name><param-value>15***011@qq.com</param-value></init-param>
</filter>
<filter-mapping><filter-name>myFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

<filter>配置

fliter-name:指为过滤器的名字

filter-class:过滤器的完整类名

init-param:用于为过滤器指定初始化参数,它的子元素指定参数的名字

<filter-mapping>配置

 filter-name:你在<fliter>中声明的filter-name

url-patten:设置 filter 所拦截的请求路径(过滤器关联的URL样式)

第二种:注解配置,这边比较简单,定义filter上的注解

        

@WebFilter(filterName = "myFilter",urlPatterns = {"/*"})

第三种:利用配置类,相关代码如下

        

package com.lsl.mylsl.filter;import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyFilterConfig {@Beanpublic FilterRegistrationBean myFilter(){FilterRegistrationBean fb = new FilterRegistrationBean();//设置filter启动顺序fb.setOrder(1);fb.setFilter(new MyFilter());fb.addInitParameter("email","15***11@qq.com");//设置拦截请求规则,这里拦截所有请求fb.addUrlPatterns("/*");return fb;}
}

这里简单说下这三种filter配置的优缺点

        第一种xml的配置需要在xml中写配置,但是现在大部分是springboot项目开发,都是重注解轻配置,现在不怎么使用了。如果xml中配置了多个filter,那么按上下先后顺序依次起作用。

        第二种注解配置,写法比较简单,但是有一个缺点,多个filter没法控制先后顺序。如果想用这个注解,但是还想控制filter的先后顺序,网上有个说法,就是按filter的名字首字母顺序来确定先后顺序,比如有多个filter的名字是AdminFilter和UserFilter,那么就是前者先生效后者后生效。

        第三种配置类配置,我个人比较倾向于这个(当然如果就是一个简单filter,用注解最简单方便),有xml配置的所有功能。可以定义启动顺序,初始化参数等。

二、拦截器Interceptor

        2.1 什么是拦截器

        Spring MVC 中的拦截器( Interceptor )类似于ServLet中的过滤器( Filter ),它主要用于拦截用户请求并作出相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。

        2.2 拦截器工作原理  

        一个拦截器,只有 preHandle 方法返回 true , postHandle 、 afterCompletion 才有可能被执行;如果 preHandle 方法返回 false ,则该拦截器的 postHandle 、 afterCompletion 必然不会被执行。拦截器不是Filter,却实现了Filter的功能,其原理在于:

        所有的拦截器 (Interceptor) 和处理器 (Handler) 都注册在 HandlerMapping 中。
Spring MVC 中所有的请求都是由 DispatcherServlet 分发的。
        当请求进入 DispatcherServlet.doDispatch() 时候,首先会得到处理该请求的 Handler (即 Controller 中对应的方法)以及所有拦截该请求的拦截器。拦截器就是在这里被调用开始工作的。

        2.3 拦截器使用场景                

        拦截器本质上是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:

        -登录验证,判断用户是否登录。
        -权限验证,判断用户是否有权限访问资源,如校验token
        - 日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
        -处理cookie、本地化、国际化、主题等。
        -性能监控,监控请求处理时长等。

        2.4、拦截器接口HandlerInterceptor

        

package org.springframework.web.servlet;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}

        从代码可以看出,拦截器接口有三个方法,分别的作用是:

                preHandle方法叫做预处理方法,本方法在控制器方法(MyController的方法)之前执        行,用户的请求最先到达此方法,在这个方法中可以获取请求的信息,验证请求是否符合要求。以验证用户是否登录,验证用户是否有权限访问某个链接地址(url)。如果返回true则放行,返回false则拦截。

                postHandle方法:叫做后处理方法。在controller中的方法之后执行的。能够获取到处理器方法的返回值 mv,可以修改mv中的数据和视图。可以影响到最后的执行结果。主要是对原来的执行结果做二次修正

                afterCompletion方法:最后执行的方法,在页面渲染之后执行。在请求处理完成后执行的,框架中规定是当你的视图处理完成后,对视图进行了forword。就任务请求处理完成。一般做资源回收工作的,程序请求过程中创建了一些对象。在这里可以删除,吧占用的内存回收

        2.5  开发一个拦截器

                开发一个拦截器也需要2步,第一步是实现HandlerInterceptor接口来定义一个拦截器,第二步就是配置拦截器了

        第一步定义一个拦截器

        

package com.lsl.mylsl.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {//在拦截的请求了添加属性,在对应请求的controller中的request中就可以获取该参数了//比如String userName = (String)request.getAttribute("userName");request.setAttribute("userName","lsl");//获取cookieCookie[] cookies = request.getCookies();//设置header属性response.addHeader("SameSite","Lax");//添加cookieCookie cookie = new Cookie("name","lsl");response.addCookie(cookie);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

        

        第二步:配置拦截器

        

package com.lsl.mylsl.interceptor;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 拦截器配置类*/
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {/*** 配置拦截器* @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(myInterceptor()).addPathPatterns("/api/lsl/**")//需要拦截的请求.addPathPatterns("/api/mjx/**")//需要拦截的请求.excludePathPatterns("/api/debug/**")//不拦截的请求.excludePathPatterns("api/lsl/getName");//不拦截的请求}/*** 注入拦截器到spring容器* @return*/@Beanpublic MyInterceptor myInterceptor(){return new MyInterceptor();}
}

三、过滤器和拦截器的区别

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调(职责链)

2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

6、拦截器可以获取IOC容器中的各个bean,而过滤器不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

7、过滤器属于Servlet,而拦截器属于springmvc

8、过滤器可以拦截所有请求,包括访问静态资源的请求,拦截器只能拦截action请求,即访问controller的请求。

通俗理解:
(1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)
(2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预它,通过验证的少点,顺便干点别的东西

过滤器和拦截器图解

在这里插入图片描述


http://chatgpt.dhexx.cn/article/B23B1tpx.shtml

相关文章

Java 过滤器与拦截器的区别

什么是过滤器&#xff08;Filter&#xff09; 过滤器&#xff0c;是在java web中将你传入的request、response提前过滤掉一些信息&#xff0c;或者提前设置一些参数。然后再传入Servlet或Struts2的 action进行业务逻辑处理。比如过滤掉非法url&#xff08;不是login.do的地址请…

Java拦截器和过滤器的区别

过滤器和拦截器的区别&#xff1a; ①拦截器是基于java的反射机制的&#xff0c;而过滤器是基于函数回调。   ②拦截器不依赖与servlet容器&#xff0c;过滤器依赖与servlet容器。   ③拦截器只能对action请求起作用&#xff0c;而过滤器则可以对几乎所有的请求起作用。  …

Java过滤器与拦截器的区别

Java过滤器与拦截器的区别 1. 过滤器与拦截器概述1.1 过滤器 Filter1.2 拦截器 interceptor 2. 过滤器与拦截器区别3. 过滤器与拦截器实现3.1 过滤器&#xff08;Filter&#xff09;3.2 拦截器 (Interceptor)3.3 拦截器WebMvc配置3.4 切片&#xff08;Aspect&#xff09; 4. 过…

C语言pow函数的调用

1.pow函数的含义&#xff1a;在math.h的头文件中是指a的b次方。 2.对于pow函数的直接应用&#xff1a; #include<stdio.h> #include<math.h> //***math头文件 int main() {double a2,b3;double result;resultpow(2,3); …

mysql pow函数怎么用_pow函数怎么用

PHP pow函数表示指数表达式。 pow函数怎么用&#xff1f; php pow()函数 语法 作用&#xff1a;pow()函数的作用是将一个数进行n次方计算后返回 语法&#xff1a;pow(X,Y); 参数&#xff1a; X表示要做处理的数字 Y表示指定n次方中的n数值 说明&#xff1a;返回X的Y次方幂&…

c语言的pow函数运用

在c语言当中我们要计算一个数的n次方时候&#xff0c;可以使用多种方法&#xff0c;但是也有一种比较简单的方法&#xff0c;便是调用一个函数pow函数。 pow函数在使用时候需要引用头文件#include<math.h>&#xff0c;接下来可以引用一个例子&#xff1a; 如果现在假设我…

C语言中的pow函数

在我们学习C语言时&#xff0c;在一些算法的问题上常常会遇到让我们求一个数的n次方&#xff0c;这时候为了方便我们可以使用C语言函数库给我们的pow函数&#xff0c;*因为这是从C语言函数库调用出来的所以我们在使用前需要引入头文件#include<math.h>。 比如当我们输入…

pow函数python_python pow函数怎么用

python中的pow函数的功能是计算x的y次幂。本篇文章将带大家一起了解一下&#xff0c;pow()函数在Python中的用法。感兴趣的朋友了解一下。 以下是 math 模块 pow() 方法的语法:import math math.pow( x, y ) 内置的 pow() 方法pow(x, y[, z]) 函数是计算x的y次方&#xff0c;如…

计算机里pow函数是什么,pow函数是什么?

pow函数&#xff1a; C/C中的数学函数&#xff1b; pow() 函数用来求 x 的 y 次幂(次方)&#xff0c;x、y及函数值都是double型 pow()用来计算以x 为底的 y 次方值&#xff0c;然后将结果返回。设返回值为 ret&#xff0c;则 ret xy。 可能导致错误的情况&#xff1a; 如果底数…

WebClient 连接池配置

背景 项目中调用第三方接口&#xff0c;第三方接口响应时间不稳定&#xff0c;并且并发越大响应时间越长&#xff0c;如果使用BIO模式可能会导致服务器连接占用过高&#xff0c;所以采用WebClient reactor模式来调用第三方接口。 网络IO模型 连接池相关配置 maxConnections…

WebClient用法小结

进来的项目中要实现能够在windows service中调用指定项目的链接页面。由于访问页面时候使用的是ie浏览器或其他浏览器&#xff0c;所以想起用webclient类。 如果只想从特定的URI请求文件&#xff0c;则使用WebClient&#xff0c;它是最简单的.NET类&#xff0c;它只用一两条命…

WebClient类的使用方法(C#---网络编程)

WebClient类的使用方法&#xff08;C#---网络编程&#xff09; 1、WebClient类 WebClient类提供向URI标识的任何本地、Intranet或Internet资源发送数据以及从这些资源接收数据的公共方法。 默认情况下&#xff0c;WebClient实例不能发送可选的HTTP报头。如果要发送可选报头&a…

WebClient 用法总结

一、WebClient概述 WebClient提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法&#xff0c; WebClient 类提供向 URI 标识的任何本地、Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法。 WebClient 类使用 WebRequest 类提供对资源…

C#-WebClient

using ( var wc new System.Net.WebClient() ) {var imagebytes wc.DownloadData( hag.ImagePath );using ( MemoryStream ms new MemoryStream( imagebytes ) ) {picImage.Image Image.FromStream( ms );} } C#中HttpWebRequest、WebClient、HttpClient的使用 HttpWebRe…

webclient学习1.webclient是什么?

1.webclient是什么&#xff1f; WebClient 软件包是 RT-Thread 自主研发的&#xff0c;基于 HTTP 协议的客户端的实现&#xff0c;它提供设备与 HTTP Server 的通讯的基本功能。 2.软件包功能特点 WebClient 软件包功能特点&#xff1a; 支持 IPV4/IPV6 地址 WebClient 软…

SpringBoot - 网络请求客户端WebClient使用详解

在 Spring 5 之前&#xff0c;如果我们想要调用其他系统提供的 HTTP 服务&#xff0c;通常可以使用 Spring 提供的 RestTemplate 来访问&#xff0c;不过由于 RestTemplate 是 Spring 3 中引入的同步阻塞式 HTTP 客户端&#xff0c;因此存在一定性能瓶颈。根据 Spring 官方文档…

【QString 函数学习篇】

【QString 函数学习篇】 【1】UI设计布局【2】QChar | setAlignment |【3】sprintf | asprintf | setNum | number |【4】toInt | toUpper [十进制->十六进制 | 十进制->二进制]【5】clear | append【6】二进制->十六进制 | 二进制->十进制【7】prepend【8】strimm…

Qt扫盲-QString使用总结

QString使用总结 一、概述二、初始化字符串1、极速版2、原理版 三、操作字符串1、极速版1. 增加2. 删除3. 修改4. 插入5. 转换 2、原理版 四、查询字符串五、字符串格式转换六、Null 字符串和 Empty 字符串的区别七、字符串参数格式化八、更高效的字符串构造九、最大大小和出现…

Qt之QString字符串类的详细介绍及功能函数示例用法

前序&#xff1a;为了加深对Qt各个类的认识和了解&#xff0c;决定以后再闲暇的时间对Qt类进行详细的阅读&#xff08;基于Qt cteater 的帮助文档&#xff09;&#xff0c;这样既可以提高自己的英文阅读能力&#xff0c;也可以对各个类有一个更加深入的认识和了解。 注&#xf…

QString类详解

文章目录 一、简要介绍1.1 隐式共享 二、常用方法2.1 常用构造函数2.2 字符串与数值之间的转换2.3 添加字符串2.4 大小写转换2.5 长度2.6 其他常用函数 一、简要介绍 在Qt中表示字符串的类是QString类&#xff0c;它存储字符串是采用的Unicode码&#xff0c;编码方式是使用UTF…