过滤器、监听器、拦截器的区别

过滤器、监听器、拦截器的区别

  • 过滤器(filter)、监听器(Listener)是JavaWeb的三大组件。
  • 而拦截器(Interceptor)是Spring框架中的。

我们主要是要分清除过滤器和拦截器的区别:

  1. 实现原理:过滤器是基于函数回调实现的,而拦截器是基于java的反射机制
  2. 使用范围:过滤器Filter的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。而拦截器是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。
  3. 触发时机:![[Pasted image 20240602162705.png]]
    ![[Pasted image 20240602162846.png]]
    从图中我看可以看出,过滤器Filter是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。而拦截器Interceptor是在请求进入servlet后,在进入Controller之前进行预处理的,Controller中渲染了对应的视图之后请求结束。

执行顺序

配置Filter:

package com.qcby.demo.config;

import org.springframework.stereotype.Component;

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

@Component
public class MyFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("Filter 前置过滤");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("Filter 处理中");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

        System.out.println("Filter 后置过滤");
    }
}

自定义拦截器

package com.qcby.demo.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor 前置拦截");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor 后置拦截");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor 最终拦截");
    }
}

配置拦截器

package com.qcby.demo.config;

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 MyConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**") // 设置要拦截的
                .excludePathPatterns("/test1");// 设置不拦截的
    }
}

控制器

package com.qcby.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("test")
public class TestController {

    @GetMapping("/test1")
    public String test() {
        return "123456";
    }
}

项目启动之后,我们会发现过滤器的init()方法,随着容器的启动进行了初始化:
![[Pasted image 20240602182638.png]]

然后浏览器访问对应的端口号:http://localhost:8080/test/test1,会有以下输出:
![[Pasted image 20240602185048.png]]

这样就验证了我们前边的过滤器和拦截器的触发顺序。
对于拦截器的触发时机,在只有一个拦截器时:
![[Pasted image 20240602185232.png]]

有多个拦截器时
![[Pasted image 20240602185303.png]]

过滤器的应用场景

  1. 过滤敏感词汇(防止sql注入)
  2. 设置字符编码
  3. URL级别的权限访问控制
  4. 压缩响应信息

拦截器的应用场景

  1. 登录验证,判断用户是否登录。
  2. 权限验证,判断用户是否有权限访问资源,如校验token
  3. 日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
  4. 处理cookie、本地化、国际化、主题等。
  5. 性能监控,监控请求处理时长等。
  6. 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)

参考文献

  • Springboot——拦截器
  • 过滤器 和 拦截器的 6个区别,别再傻傻分不清了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/673812.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

晶体(二):差分晶振

一、定义 差分晶振是一种有源晶体振荡器,输出差分信号(由两个相位相反、幅度相等的信号组成),从而消除了共模噪声,具有抗干扰能力强、对参考电平完整性要求较弱、抑制串扰、EMI 能力强、功耗小、速率高、不受温度和电压…

【Ubuntu常用命令】终端个人常用命令总结

【Ubuntu常用命令】终端常用命令总结 查看硬盘挂载情况查看内存占用情况移动或重命名文件和目录复制文件或目录conda安装本地文件 查看硬盘挂载情况 mount 命令会列出当前系统上所有已挂载的文件系统。它会显示挂载点、文件系统类型、挂载选项等信息 mount df 命令用于显示文…

MySQL学习——影响选项文件处理的命令行选项和程序选项修改器

大多数支持选项文件的MySQL程序都处理以下选项。因为这些选项会影响选项文件的处理,所以必须在命令行上给出,而不是在选项文件中给出。为了正常工作,这些选项中的每一个都必须先于其他选项给出,但以下情况除外: -prin…

AK F.*ing leetcode 流浪计划之费马小定理与组合数取模

欢迎关注更多精彩 关注我,学习常用算法与数据结构,一题多解,降维打击。 费马小定理与证明 参考 https://zhuanlan.zhihu.com/p/594859227 费马小定理:如果p是一个质数,而正整数a不是p的倍数,那么a(p-1)≡…

继承的基本语法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在编写类时,并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间存在一定的继承关系时,就可以通过继承来达到代…

AI早班车6.3

1.蚂蚁技术日:支付宝三大「AI 管家」亮相。 2.百度赵世奇:百度搜索+文心智能体平台,助力智能体人人可用。 3.腾讯:发布大模型App腾讯元宝。 4.AFAC2024金融智能创新大赛启动,让高质量金融服务人人可用 …

Docker笔记-解决非交互式运行python时print不输出的问题

换句话来说就是在docker中如何不会python的print 只需要在启动时&#xff0c;不让python缓冲其输出。 关键命令如下&#xff1a;PYTHONUNBUFFERED1 如下&#xff1a; docker run -e PYTHONUNBUFFERED1 <your_image> 下面解释下-e "-e"选项的全称是"…

lux和ffmpeg进行下载各大主流自媒体平台视频

1、lux下载&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1WjGbouL3KFTU6LeqZmACpA?pwdagpp 提取码&#xff1a;agpp 2、ffmpeg下载&#xff0c;跟lux放在同一个目录&#xff1b; 3、为lux、ffmpeg设置环境变量&#xff1b; 4、WINR&#xff0c;打开运行&#xff0…

Love-Yi情侣网站3.0存在SQL注入漏洞

目录 1. 前言 2. 网站简介 3. 寻找特征点 3.1 第一次尝试 3.2 第二次尝试 4.资产搜索 5.漏洞复现 5.1 寻找漏洞点 5.2 进行进一步测试 5.2.1 手动测试 1.寻找字段 2.寻找回显位 3.查询当前用户 5.2.2 sqlmap去跑 6.总结 1. 前言 朋友说自己建了一个情侣网站,看到…

chat4-Server端保存聊天消息到mysql

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程&#xff0c;此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…

基于django | 创建app,并启动django

1、删除系统默认的目录路径&#xff1a;BASE_DIR / templetes 2、在终端输入命令&#xff1a; python manage.py startapp app01 # 这里的app01是我创建app的名称 3、如果没有创建成功&#xff0c;手动点击 Creat App , 4、在 setting.py 中找到 INSTALLED_APPS ,添加 ap…

✅count(1)、count(*) 与 count(列名) 的区别

简单来说&#xff1a; COUNT(1) 和 COUNT(*) 表示的是直接查询符合条件的数据库表的行数。而 COUNT(列名) 表示的是查询符合条件的列的值不为 NULL 的行数。 除了查询得到结果集有区别之外&#xff0c;在性能方面 COUNT() 约等于 COUNT(1)&#xff0c;但是 **COUNT() 是 SQL9…

Qt——升级系列(Level Two):Hello Qt 程序实现、项目文件解析、

Hello Qt 程序实现 使用“按钮”实现 纯代码方式实现&#xff1a; // Widget构造函数的实现 Widget::Widget(QWidget *parent): QWidget(parent) // 使用父类构造函数初始化QWidget&#xff0c;传入父窗口指针, ui(new Ui::Widget) // 创建Ui::Widget类的实例&#xff0c;并…

基于GTX 8B10B编码的自定义PHY接收模块(高速收发器十三)

点击进入高速收发器系列文章导航界面 前文完成了发送模块的设计&#xff0c;本文接着完成接收模块的设计&#xff0c;接收模块相对发送模块会更加麻烦。 1、设计思路 前文在讲解官方示例工程时&#xff0c;提到GTX IP的接收部分没有做字对齐&#xff0c;需要用户自己编写字对齐…

微服务:Rabbitmq的基本的消息队列的入门简单使用(消息队列中间件)

先介绍最简单的使用方式&#xff0c;后面还会更新其他使用方法。 简单案例 目录结构 引入依赖&#xff1a; <!--AMQP依赖&#xff0c;包含RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…

JAVA:Spring Boot整合Kaptcha验证码实现登录验证

请关注微信公众号&#xff1a;拾荒的小海螺 博客地址&#xff1a;http://lsk-ww.cn/ 1、简述 在Web应用程序中&#xff0c;验证码是一种常见的安全措施&#xff0c;用于验证用户的身份以防止恶意活动&#xff0c;如自动化攻击或机器人。Spring Boot提供了许多库和工具&#x…

UnityAPI学习之Transform组件基本使用

目录 Transform组件 访问与获取 Transform的位置和旋转信息 Transform局部坐标和旋转信息的获取 Transform的缩放与正方向 缩放&#xff08;Scale&#xff09; 正方向 Transform相关的查找方法 销毁游戏物体 Transform组件 访问与获取 现在创建一个容器放置GrisGO物…

VueX核心内容

聚沙成塔每天进步一点点 本文内容 ⭐ 专栏简介Vuex 核心内容核心概念1. State&#xff08;状态&#xff09;示例&#xff1a; 2. Getter&#xff08;获取器&#xff09;示例&#xff1a; 3. Mutation&#xff08;突变&#xff09;示例&#xff1a; 4. Action&#xff08;动作&a…

MbedTLS源码跨平台编译(window/macos/linux)

1.window平台编译: 克隆: git clone --recursive https://github.com/Mbed-TLS/mbedtls.git 克隆成功 添加OpenSSL环境变量 验证环境 使用cmake编译 cmake ../生成配置时出错 出现上面原因是克隆下来的library与programs及tests目录少文件了,直接下载zip包替换library目录

dibbler-DHCPv6 的开源框架(C++ 实现)1

一、下载 IPv6 DHCPv6 协议的开源框架&#xff1a;dibbler 下载地址&#xff1a;https://github.com/tomaszmrugalski/dibbler.git 二、代码编写语言和文件结构 编写语言 文件 三、编译 编译 server 端&#xff1a; chmod x configure ./configure# 编译服务端(4核) mak…