当前位置: 首页 > news >正文

过滤器 与 拦截器

文章目录

  • 过滤器 与 拦截器
  • 一、过滤器(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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • window下kafka3启动多个
  • C++高精度算法--加法
  • STM32外部中断(总结了易出现的BUG)
  • Windows10上Nginx如何通过自签名证书方式发布Https服务(下)
  • pycharm 2024.1下载、安装
  • 【c++】cout打印char * 或者char[]的细节详解
  • Java中的事件驱动架构(EDA)
  • 面相对象的成员介绍
  • C# 什么是属性
  • 使用twilio向手机发短信做监控报警
  • 协议转换桥+高速协议传输终端
  • 【解决】CentOS7 生命周期结束后 使用 yum命令报错问题
  • 系统运维方案书(Word原件)
  • DNS部署与安全
  • esp8266根据httpserver状态,调用网络唤醒,实现一键开机
  • angular组件开发
  • Apache Zeppelin在Apache Trafodion上的可视化
  • CAP理论的例子讲解
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • Mithril.js 入门介绍
  • Odoo domain写法及运用
  • PHP那些事儿
  • PV统计优化设计
  • vue脚手架vue-cli
  • Webpack 4 学习01(基础配置)
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 爱情 北京女病人
  • 测试开发系类之接口自动化测试
  • 成为一名优秀的Developer的书单
  • 坑!为什么View.startAnimation不起作用?
  • 两列自适应布局方案整理
  • 前端性能优化——回流与重绘
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 如何在 Tornado 中实现 Middleware
  • 入门到放弃node系列之Hello Word篇
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 通信类
  • 想写好前端,先练好内功
  • 小程序开发之路(一)
  • 用 Swift 编写面向协议的视图
  • 与 ConTeXt MkIV 官方文档的接驳
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • zabbix3.2监控linux磁盘IO
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #Lua:Lua调用C++生成的DLL库
  • #window11设置系统变量#
  • $forceUpdate()函数
  • (SpringBoot)第七章:SpringBoot日志文件
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (算法)硬币问题
  • (一)插入排序
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • ***详解账号泄露:全球约1亿用户已泄露