过滤器 与 拦截器

2024-09-02 02:44
文章标签 拦截器 过滤器

本文主要是介绍过滤器 与 拦截器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 过滤器 与 拦截器
  • 一、过滤器(Filter)
    • 1、特点
    • 2、生命周期
    • 3、实现
    • 4、过滤器链
      • 1)配置 order
      • 2)执行顺序
  • 二、拦截器 Inteceptor
    • 1、特点
    • 2、生命周期
    • 3、实现
    • 4、拦截器链
      • 1)配置 order
      • 2)执行顺序(没有异常)
      • 3)某拦截器 preHandle 返回false
      • 4)执行顺序(有异常)
      • 5)小结
  • 三、执行顺序
    • 1、自定义 Servlet
    • 2、自定义 Filter
    • 3、自定义 Inteceptor
    • 4、对比:Servlet 与 Filter
    • 5、对比:Filter 与 Inteceptor
    • 6、小结

过滤器 与 拦截器

一、过滤器(Filter)

1、特点

过滤器是基于Java Servlet规范的一部分,用于在请求 到达Servlet之前 或 响应离开Servlet之后 对请求和响应进行处理。

  • 过滤器可以对所有请求进行处理,不仅限于特定的Servlet或Spring MVC控制器。
  • 过滤器在Servlet容器层面工作,而不是Spring层面。
  • 适合用于日志记录、身份验证、权限检查等通用功能。

2、生命周期

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方法】
1. 特点:服务器启动,项目加载,创建filter对象,执行【init方法】(只执行一次)
2. 对比Servlet:先于Servlet的init方法执行# 拦截【doFilter方法】
1. 特点:用户访问被拦截的目标资源时,执行【doFilter方法】(浏览器每访问一次,就会执行一次)
2. 对比Servlet:先于Servlet的service方法执行# 销毁【destroy方法】
1. 特点:服务器关闭,项目关闭,销毁filter对象,执行【destroy方法】(只执行一次)
2. 对比Servlet:后于Servlet的destroy方法执行

3、实现

定义拦截器只要实现Filter接口,重写doFilter方法即可

public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 前置处理...System.out.println("Filter doFilter before");// 处理请求chain.doFilter(request, response);// 后置处理...System.out.println("Filter doFilter after");}
}

注册拦截器(SpringBoot示例)

@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<MyFilter> myFilter() {FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new MyFilter());// 过滤路径(/*表示所有)registrationBean.addUrlPatterns("/*");// 过滤顺序(多个Filter按Order从小到大顺序执行)registrationBean.setOrder(1);return registrationBean;}
}

4、过滤器链

1)配置 order

多个 Filter 按 Order的大小 从小到大 执行(如果没有配置Order,按 Bean声明的顺序 从上到下 执行)

@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<MyFilter> myFilter1() {FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new MyFilter1());registrationBean.addUrlPatterns("/*");registrationBean.setOrder(1);return registrationBean;}@Beanpublic FilterRegistrationBean<MyFilter> myFilter2() {FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new MyFilter2());registrationBean.addUrlPatterns("/*");registrationBean.setOrder(2);return registrationBean;}@Beanpublic FilterRegistrationBean<MyFilter> myFilter3() {FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new MyFilter3());registrationBean.addUrlPatterns("/*");registrationBean.setOrder(3);return registrationBean;}
}

2)执行顺序

Filter1 doFilter before
Filter2 doFilter before
Filter3 doFilter beforeServlet service// 如果发生异常,就不会执行 doFilter after 了
Filter3 doFilter after
Filter2 doFilter after
Filter1 doFilter after

二、拦截器 Inteceptor

1、特点

拦截器是Spring MVC提供的功能,用于在请求到达控制器之前和响应离开控制器之后进行处理。

  • 拦截器主要用于Spring MVC层面,处理的是控制器层的请求和响应。
  • 适合用于权限检查、日志记录、请求计时等与业务逻辑密切相关的操作。

2、生命周期

在这里插入图片描述

public interface HandlerInterceptor {// Controller执行之前调用default boolean preHandle(HttpServletRequest request,  HttpServletResponse response, Object handler) throws Exception {return true;}// Controller执行之后调用(发生异常 或 preHandle=false 不会调用)default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}// Controller执行之后调用(发生异常也会调用,preHandle=false不会调用)default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}

3、实现

自定义拦截器只要实现HandlerInterceptor接口,按需重写指定即可。

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Pre Handle method is Called");return true; // 继续处理请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("Post Handle method is Called");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("Request and Response is completed");}
}

注册拦截器

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 WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 添加自定义拦截器registry.addInterceptor(new MyInterceptor())// 配置拦截路径.addPathPatterns("/**")// 配置放过路径.excludePathPatterns();}
}

4、拦截器链

1)配置 order

多个 Interceptor 按 Order的大小 从小到大 执行(如果没有配置Order,按 添加的顺序 从上到下 执行)

@Configuration
public class MyAdapter implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**").order(1);registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**").order(2);registry.addInterceptor(new MyInterceptor3()).addPathPatterns("/**").order(3);}
}

2)执行顺序(没有异常)

Interceptor1 preHandle	// true
Interceptor2 preHandle	// true
Interceptor3 preHandle	// trueServlet serviceInterceptor3 postHandle
Interceptor2 postHandle
Interceptor1 postHandle  Interceptor3 afterCompletion
Interceptor2 afterCompletion
Interceptor1 afterCompletion

3)某拦截器 preHandle 返回false

这里我们假设中间的 Interceptor2 的 preHandle 返回 false

Interceptor1 preHandle	// true
Interceptor2 preHandle	// falseInterceptor1 afterCompletion
之前的拦截器(即 Interceptor1): 执行了 preHandle 和 afterCompletion
阻隔的拦截器(即 Interceptor2): 执行了 preHandle
之后的拦截器(即 Interceptor3): 全部不执行

4)执行顺序(有异常)

Interceptor1 preHandle	// true
Interceptor2 preHandle	// true
Interceptor3 preHandle	// true// 发生异常之前
Servlet service// 这个竟然是在 异常的堆栈信息 之前执行的
Interceptor3 afterCompletion
Interceptor2 afterCompletion
Interceptor1 afterCompletion异常的堆栈信息// 发生异常之后,又整体执行了一遍....
Interceptor1 preHandle
Interceptor2 preHandle
Interceptor3 preHandleInterceptor3 postHandle
Interceptor2 postHandle
Interceptor1 postHandleInterceptor3 afterCompletion
Interceptor2 afterCompletion
Interceptor1 afterCompletion

5)小结

整体顺序:所有 preHandle -> Controller -> 所有 postHandle -> 所有 afterCompletion

# preHandle
1. 调用前提无
2. 调用时机Controller方法处理之前
3. 调用链顺序顺序执行:preHandle1 ==> preHandle2 ==> preHandle3# postHandle
1. 调用前提preHandle返回true 且 Controller没有发生异常
2. 调用时机Controller方法处理完之后,afterCompletion调用之前
3. 调用链顺序倒序执行:postHandle3 ==> postHandle2 ==> postHandle1# afterCompletion
1. 调用前提preHandle返回true(Controller发生异常也会调用)
2. 调用时机Controller方法处理完之后
3. 调用链顺序倒序执行:afterCompletion3 ==> afterCompletion2 ==> afterCompletion1

三、执行顺序

1、自定义 Servlet

public class MyServlet extends HttpServlet {@Overridepublic void destroy() {System.out.println("Servlet destroy");super.destroy();}@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("Servlet init");super.init(config);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Servlet service");resp.getWriter().write("Hello from MyServlet");}
}
@Configuration
public class ServletConfig {@Beanpublic ServletRegistrationBean<MyServlet> myServlet() {return new ServletRegistrationBean<>(new MyServlet(), "/myServlet");}
}

2、自定义 Filter

public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("Filter init");Filter.super.init(filterConfig);}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 前置处理...System.out.println("Filter doFilter before");// 处理请求chain.doFilter(request, response);// 后置处理...System.out.println("Filter doFilter after");}@Overridepublic void destroy() {System.out.println("Filter destroy");Filter.super.destroy();}
}
@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<MyFilter> myFilter() {FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new MyFilter());registrationBean.addUrlPatterns("/*");registrationBean.setOrder(1);return registrationBean;}
}

3、自定义 Inteceptor

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Interceptor preHandle");return true; // 继续处理请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("Interceptor postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("Interceptor afterCompletion");}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns();}
}

4、对比:Servlet 与 Filter

// 项目启动
Filter init// 访问 http://localhost:8080/myServlet
Servlet init
Filter doFilter before
Servlet service
Filter doFilter after// 项目关闭
Servlet destroy
Filter destroy

5、对比:Filter 与 Inteceptor

@RestController
public class TestController {@GetMapping("/interceptor")public ResponseEntity<String> interceptor() {System.out.println("Servlet service");return ResponseEntity.ok("SUCCESS");}
}
// 项目启动
Filter init// 访问 http://localhost:8080/interceptor
Filter doFilter before
Interceptor preHandle
Servlet service
Interceptor postHandle
Interceptor afterCompletion
Filter doFilter after// 项目关闭
Filter destroy

6、小结

在这里插入图片描述

// 项目启动
Filter init// 访问接口
Servlet init
Filter doFilter before
Interceptor preHandle
Servlet service
Interceptor postHandle
Interceptor afterCompletion
Filter doFilter after// 项目关闭
Servlet destroy
Filter destroy

这篇关于过滤器 与 拦截器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128776

相关文章

Kafka拦截器的神奇操作方法

《Kafka拦截器的神奇操作方法》Kafka拦截器是一种强大的机制,用于在消息发送和接收过程中插入自定义逻辑,它们可以用于消息定制、日志记录、监控、业务逻辑集成、性能统计和异常处理等,本文介绍Kafk... 目录前言拦截器的基本概念Kafka 拦截器的定义和基本原理:拦截器是 Kafka 消息传递的不可或缺

Servlet中配置和使用过滤器的步骤记录

《Servlet中配置和使用过滤器的步骤记录》:本文主要介绍在Servlet中配置和使用过滤器的方法,包括创建过滤器类、配置过滤器以及在Web应用中使用过滤器等步骤,文中通过代码介绍的非常详细,需... 目录创建过滤器类配置过滤器使用过滤器总结在Servlet中配置和使用过滤器主要包括创建过滤器类、配置过滤

Mybatis拦截器如何实现数据权限过滤

《Mybatis拦截器如何实现数据权限过滤》本文介绍了MyBatis拦截器的使用,通过实现Interceptor接口对SQL进行处理,实现数据权限过滤功能,通过在本地线程变量中存储数据权限相关信息,并... 目录背景基础知识MyBATis 拦截器介绍代码实战总结背景现在的项目负责人去年年底离职,导致前期规

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

布隆过滤器的详解与应用

一、什么是Bloom Filter Bloom Filter是一种空间效率很高的随机数据结构,它的原理是,当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个位阵列(Bit array)中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检索元素一定不在;如果都是1,则被检索元素很可能在。这就是布隆过滤器的基本思

请解释Java Web应用中的前后端分离是什么?它有哪些好处?什么是Java Web中的Servlet过滤器?它有什么作用?

请解释Java Web应用中的前后端分离是什么?它有哪些好处? Java Web应用中的前后端分离 在Java Web应用中,前后端分离是一种开发模式,它将传统Web开发中紧密耦合的前端(用户界面)和后端(服务器端逻辑)代码进行分离,使得它们能够独立开发、测试、部署和维护。在这种模式下,前端通常通过HTTP请求与后端进行数据交换,后端则负责业务逻辑处理、数据库交互以及向前端提供RESTful

.NET 自定义过滤器 - ActionFilterAttribute

这个代码片段定义了一个自定义的 ASP.NET Core 过滤器(GuardModelStateAttribute),用于在控制器动作执行之前验证模型状态(ModelState)。如果模型状态无效,则构造一个 ProblemDetails 对象来描述错误,并返回一个 BadRequest 响应。 代码片段: /// <summary>/// 验证 ModelState 是否有效/// </

【SpringMVC学习09】SpringMVC中的拦截器

Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用方法。 1. springmvc拦截器的定义和配置 1.1 springmvc拦截器的定义 在springmvc中,定义拦截器要实现HandlerInterceptor接口,并实现该接口中提供的

水处理过滤器运行特性及选择原则浅谈

过滤属于流体的净化过程中不可缺的处理环节,主要用于去除流体中的颗粒物或其他悬浮物。水处理过滤器的原理是利用有孔介质,从流体中去除污染物,使流体达到所需的洁净度水平。         水处理过滤器的滤壁是有一定厚度的,也就是说过滤器材具有深度,以“弯曲通 道”的形式对去除污染物起到了辅助作用。过滤器是除去液体中少量固体颗粒的设备,当流体进入置有一定规格滤网的滤筒后,其杂质被阻挡,而

过滤器:精密过滤器特点及应用范围概述

精密过滤器(又称作保安过滤器),筒体外壳一般采用不锈钢材质制造,内部采用PP熔喷、线烧、折叠、钛滤芯、活性炭滤芯等管状滤芯作为过滤元件,根据不同的过滤介质及设计工艺选择不同的过滤元件,以达到出水水质的要求。随着过滤行业的不断发展,越来越多的行业和企业运用到了精密过滤器,越来越多的企业加入了精密过滤器行业。   一、精密过滤器的性能特点及应用   1、精密过滤器的性能特点   (1)过滤精