springboot(13):spring 过滤器和拦截器的区别

news2024/12/22 23:25:08

目录

  • 过滤器和拦截器的区别
  • 过滤器的使用
    • 1.使用spring boot提供的FilterRegistrationBean
    • 2.使用原生servlet注解定义Filter
  • 拦截器的使用

在前面我们讲过拦截器怎么使用,参考:拦截器

和拦截器有个差不多的叫过滤器。

过滤器和拦截器的区别

首先看一下下面的流程图:

在这里插入图片描述
如上图,其中prehandel、posthandel、afterCompletion是拦截器的方法,filter pre和filter after是过滤器的方法。

两者区别主要有以下几点:

  1. 触发时机:过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。拦截器是进入servlet之后才触发。
  2. 生命周期:Filter的生命周期由Servlet容器管理,而拦截器由spring提供,并可以使用IoC容器来管理,因此拦截器可以获取IOC容器中的各个bean,而过滤器就不行。
  3. 实现方式:过滤器实现基于回调函数,拦截器(代理模式)的实现基于反射。
  4. 执行方式:过滤器的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。
  5. 影响范围:过滤器可以修改request和response,而拦截器不能。但是过滤器只能在请求的前后使用,而拦截器可以详细到每个方法。

基于以上区别,过滤器和拦截器的使用场景通常不同。

拦截器本质上是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现。

拦截器主要应用场景:

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

过滤器主要应用场景:

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

过滤器的使用

有以下两种方式使用过滤器。

1.使用spring boot提供的FilterRegistrationBean

先定义Filter:只要实现接口import javax.servlet.Filter,并实现是哪个方法即可,其中最重要的是doFilter方法,在里面写我们的过滤逻辑。代码如下:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // doFilter()方法中的servletRequest参数的类型是ServletRequest,需要转换为HttpServletRequest类型方便调用某些方法
        System.out.println("filter1");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String ip = request.getRemoteAddr();
        String url = request.getRequestURL().toString();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = new Date();
        String date = sdf.format(d);

        System.out.printf("%s %s 访问了 %s%n", date, ip, url);

        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

然后注册我们的Filter:

import com.example.server.common.MyFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
        // 设置过滤的url
        filterRegistrationBean.addUrlPatterns("/*");
        // 设置优先级
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }
}

2.使用原生servlet注解定义Filter

用@WebFilter就可以进行配置。代码如下:

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;


@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "myFilter2" ,urlPatterns = "/*")
@Order(2)
public class MyFilter2 implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("my filter2");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

这里需要注意一点的是@WebFilter这个注解是Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在启动类中加另外一个注解:@ServletComponetScan,指定扫描的包。

@SpringBootApplication
@ServletComponentScan
public class FilterTestApplication {
 
	public static void main(String[] args) {	
		ConfigurableApplicationContext applicationContext = SpringApplication.run(FilterTestApplication.class, args);
	}
}

拦截器的使用

参考文章:拦截器

参考文章:
https://blog.csdn.net/qq_49313444/article/details/107504196
https://blog.csdn.net/qq_42076204/article/details/125215984

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1535. 找出数组游戏的赢家

给你一个由 不同 整数组成的整数数组 arr 和一个整数 k 。 每回合游戏都在数组的前两个元素(即 arr[0] 和 arr[1] )之间进行。比较 arr[0] 与 arr[1] 的大小,较大的整数将会取得这一回合的胜利并保留在位置 0 ,较小的整数移至数组…

[附源码]计算机毕业设计JAVA竞价拍卖系统

[附源码]计算机毕业设计JAVA竞价拍卖系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis M…

Spring 源码阅读 04:BeanFactory 初始化

本篇要阅读的是 BeanFactory 初始化的部分,也就是 refresh 方法中的这一行方法调用: // Tell the subclass to refresh the internal bean factory. // 这里会调用模版方法,通过子类的实现,初始化 BeanFactory 并解析 XML 配置 C…

企业快速构建可落地的IT服务管理体系的五大关键点

随着数字化转型的发展,IT运维管理环境日益复杂,对管理的要求也随之增高如何提升运维效率,快速落地做好运维管理,搭建一套IT服务管理必不可少,以往我们也对IT服务管理框架进行过总结,当下,面对很…

Linux ALSA 之三:简单的 ALSA Driver 实现

简单的 ALSA Driver 实现一、概述二、Linux ALSA 音频设备驱动实例1、注册 Platform Device & Platform Driver2、创建 card3、PCM 设备相关设定3.1 创建 PCM Device3.2 设置 PCM 操作3.2 PCM HW 初始化4、Control 设备相关设定4.1 定义 snd_kcontrol_new4.2 构造 control5…

C语言实现冒泡排序(图解)

目录 一、冒泡排序是什么? 二、图解冒泡排序过程 三、代码实现 3.1易错点(切记切记) 四、优化 4.1优化代码 一、冒泡排序是什么? int arr[]{9,8,7,6,5,4,3,2,1,0} ,像这样的数组,升序排序。 冒泡排序…

Dynamic Potential-Based Reward Shaping将势能塑形奖励函数拓展为F(s,t,s‘,t‘)

摘要 基于势能的奖励塑形可以显著降低学习最优策略所需的时间,并且在多agent系统中,可以显著提高最终联合策略的性能。已经证明,它不会改变一个agent单独学习的最优策略或多个agent一起学习的纳什均衡。 ------然而,现有证明的一…

正厚软件-软件测试用例设计方法之二-边界值

正厚软件-刘老师的干货分享 上一课我们学习测试用例的等价类划分法,今天我们看下边界值法。 一、方法简介 1、定义:边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充。 2、边界值与等价类…

Linux零拷贝原理学习

文章目录一、为什么要有 DMA 技术?二、传统的文件传输有多糟糕?三、如何优化文件传输的性能?四、 如何实现零拷贝?mmap writesendfile使用零拷贝技术的项目五、PageCache 有什么作用?六、大文件传输用什么方式实现?一…

c++动态创建二维数组和释放

动态创建二维数组和释放 文章目录创建参考博客😊点此到文末惊喜↩︎ 创建 指针数组的方式 使用malloc和free可以兼容c相比于使用STL可以更加灵活但是debug可能数组显示不全 // 初始化int **arr;int row 5;//用于表示行数int col 5;//用于表示列数arr new int…

网站升级HTTPS教程

现在越来越多的网站开始使用https协议,其实百度从2014年底就已经开始支持https了,并且据说在排名上,同权重的网站,开启https会优待提升排名。先不管排不排名吧,https是一种更安全更先进的技术。作为互联网的弄潮儿&…

MPU9250数据转换

MPU9250数据转换1. MPU92501.1 MPU9250介绍2. 数据转换2.1 陀螺仪数据转换2.2 加速度数据转换1. MPU9250 1.1 MPU9250介绍 1)MPU9250 内部集成有 3 轴陀螺仪、3 轴加速度计和 3 轴磁力计 2)输出: 16 位的数字量; 3) 通过集成电路…

MCE | 免疫检查点大组团

提到免疫,总会让人联想到由免疫失调引起的疾病,例如病毒感染,自身免疫病类风湿性关节炎,癌症等。实际上,机体的免疫应答受到严格的调控,并存在多种机制预防对自身蛋白的免疫反应。在过去的 20 年中&#xf…

3.2、封装成帧

3.2、封装成帧 3.2.1、封装成帧 数据链路层给上层交付的协议数据单元添加帧头和帧尾使之成为帧 在帧头和帧尾中包含有重要的控制信息 数据链路层将上层交付下来的协议数据单元封装成帧后,通过物理层将构成帧的各比特转换成电信号发送到传输媒体 那么接收方的数据…

dreamweaver作业静态HTML网页设计——摩尔庄园7页HTML+CSS+JS DW大学生网页作业制作设计 Dreamweaver简单网页

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…

15_移动端项目或者前后端分离项目接口规范

15_移动端项目或者前后端分离项目接口规范写在前面的话,主要是谈谈接口 随着前后端的分离,后端工程师不需要编写页面,甚至不需要编写JavaScript代码,只需要提供接口给前端工程师即可,可是就是仅仅一个接口&#xff0c…

mybatis-plus自带的乐观锁

文章目录1.场景1.1.模拟冲突2.添加乐观锁2.1数据库添加字段2.2配置文件中增加乐观锁拦截器2.3类的属性上添加注解2.4再次运行测试文件3.优化流程mysbatis-plus乐观锁原理:mysbatis-plus进行修改操作时,会将数据库中version字段的值拿出来和上一个查询时的…

大一学生WEB前端静态网页——旅游网页设计与实现-张家口 6页

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游景点介绍 | 旅游风景区 | 家乡介绍 | 等网站的设计与制作| HTML期末大学生网页设计作业 HTML:结构 CSS:样式 在操作方面上运…

【电力负荷预测】模拟退火算法结合狮群算法优化Elman神经网络电力负荷预测【含Matlab源码 1454期】

⛄一、模拟退火算法简介 1 引言 模拟退火算法(Simulated Annealing,SA)的思想最早由Metropolis等人于1953年提出:Kirkpatrick于1983年第一次使用模拟退火算法求解组合最优化问题[1] 。模拟退火算法是一种基于MonteCarlo迭代求解策略的随机寻优算法&…

图文详解Linux基础经典教程(09)——部署项目至CentOS

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 概述 在之前的操作里,我们在CentOS中安装了JDK、Tomcat、MySQL。接下来,我们需要将JavaWeb项目部署至CentOS。 项目开发 请在IDEA中开发JavaWeb项…