过滤器和拦截器

上篇文章我们学习了 Session 认证和 Token 认证,这篇我们来学习一下过滤器和拦截器,过滤器和拦截器在日常项目中经常会用到。

一、过滤器

1.1、理论概念

过滤器 Filter 是 JavaWeb 三大组件(Servlet、Filter、Listener)之一,过滤器主要是拦截资源的请求,进而实现一些特殊的处理。

作用:设置字符集、控制权限、登陆检查、敏感字符处理等。

Filter 过滤器随着 Web 应用启动而启动,只初始化一次

  • init(FilterConfig):初始化接口,在用户自定义的 Filter 初始化的时候被调用。
  • doFilter(ServletRequest,ServletResponse,FilterChain):每个用户的请求进来时都会调用此方法,通过调用 FilterChain.doFilter 可以将请求继续传递下去。
  • destroy:Filter 对象被销毁时,调用此方法。

实现过滤器 Filter 步骤:

  1. 定义类,实现 Filter 接口,重写其方法。
  2. 配置过滤器
1.2、SpringBoot集成过滤器

①、使用 @Component 配置过滤器

新建一个 SpringBoot 项目,在 Filter 包新建 TestFilter 实现类,并在实现类中实现 doFilter方法,并且实现类使用 @Component 修饰。

package com.duan.filter;
import javax.servlet.*;
import java.io.IOException;/*** @author db* @version 1.0* @description TestFilter* @since 2023/12/20*/
@Component
public class TestFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("通过@Component方式配置过滤器");chain.doFilter(request,response);}
}

启动项目,通过 postman 访问 login 接口,查看结果。

②、使用 @Configuration 配置过滤器

首先在 Filter 包新建 TestFilter2 实现类,并在实现类中实现 doFilter 方法,然后需要一个 @Configuration 配置类,在配置类使用 @Bean 手动注入 FilterRegistrationBean 类。

用 FilterRegistrationBean 类设置自定义的 Filter 实现类和一些设置项;

package com.duan.filter;import javax.servlet.*;
import java.io.IOException;/*** @author db* @version 1.0* @description TestFilter2* @since 2023/12/20*/
public class TestFilter2 implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("使用@Configration配置过滤器");chain.doFilter(request,response);}
}

过滤器配置类代码如下

package com.duan.config;import com.duan.filter.TestFilter2;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.servlet.Filter;
import java.util.ArrayList;
import java.util.List;/*** @author db* @version 1.0* @description FilterConfig* @since 2023/12/20*/
@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<TestFilter2> testFilter2(){FilterRegistrationBean<TestFilter2> filterFilterRegistrationBean = new FilterRegistrationBean<>();filterFilterRegistrationBean.setEnabled(true);    // 是否启动注入过滤器filterFilterRegistrationBean.setFilter(new TestFilter2());  // 设置过滤器filterFilterRegistrationBean.setOrder(1);         // 设置过滤器顺序  数字越小越靠前filterFilterRegistrationBean.setName("TestFilter2");    // 设置过滤器名字List<String> urlPatterns = new ArrayList<>();urlPatterns.add("/*");filterFilterRegistrationBean.setUrlPatterns(urlPatterns);  // 设置要过滤的路径return filterFilterRegistrationBean;}
}

启动项目,通过 postman 调用 login 接口,查看结果。

③、使用@WebFilter@ServletComponentScan 配置过滤器

在 Filter 包新建 LoginFilter,在实现类上使用 @WebFilter 注解,在启动类上使用 @ServletComponentScan 注解设置扫描路径。

代码实现如下:
package com.duan.Filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;/*** @author db* @version 1.0* @description LoginFilter*/@WebFilter(urlPatterns = "/*")
public class LoginFilter implements Filter {// 拦截方法,只要资源请求被拦截到,就一定会调用此方法@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("拦截方法执行了");//        chain.doFilter(request,response);}}

启动类上添加 @ServletComponentScan 注解


package com.duan;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;/*** @author db* @version 1.0* @description FilterApplication*/
@ServletComponentScan
@SpringBootApplication
public class FilterApplication {public static void main(String[] args) {SpringApplication.run(FilterApplication.class);}
}

通过 postman 调用 login 接口,发现 filter 会拦截 login 请求。

修改 loginFilter 代码

package com.duan.filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;/*** @author db* @version 1.0* @description LoginFilter* @since 2023/12/19*/@WebFilter(urlPatterns = "/*")
public class LoginFilter implements Filter {// 拦截方法,只要资源请求被拦截到,就一定会调用此方法@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("拦截方法执行,拦截了请求");System.out.println("放行前逻辑+++++++");chain.doFilter(request,response);System.out.println("放行后逻辑——————");}
}

在通过 postman 调用 login 方法,

查看控制台输出

二、拦截器

2.1、理论概念

概念:是一种动态拦截方法调用的机制,类似于过滤器。在Spring中动态拦截控制器中方法的执行。

作用:在调用目标方法前后执行相关操作,进行增强。如:日志记录、权限检查、性能监控等。

实现拦截器步骤:

  1. 首先定义一个拦截器,在该拦截器类上使用 @Component 注解,实现 HandlerInterceptor 接口,并重写所有方法。
  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):目标方法执行前调用 true 放行。
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):目标方法执行后调用。
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):请求处理后调用。
  1. 将创建的拦截器加入到 SpringBoot 的配置文件中。
2.2、SpringBoot 集成拦截器

①、新建一个 SpringBoot 项目,在 handler 包新建 LoginInterceptor 实现类,并在实现类中实现 preHandle、postHandle、afterCompletion 方法,并且在该类上使用 @Component 注解。

package com.duan.handler;import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @author db* @version 1.0* @description LoginInterceptor* @since 2023/12/20*/
@Component
public class LoginInterceptor implements HandlerInterceptor {// 目标方法执行前调用  true:放行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("preHandle");return true;}// 目标方法执行后调用@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}// 请求处理后调用@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("Completion...");}
}

②、在 config 包下新建 LoginInterceptorConfig 配置类,在类中配置拦截器。

package com.duan.config;import com.duan.handler.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author db* @version 1.0* @description LoginInterceptorConfig  注册拦截器* @since 2023/12/20*/
@Configuration
public class LoginInterceptorConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(loginInterceptor).addPathPatterns("/**");}
}

③、通过 postman 调用 login 接口,发现过滤器会过滤 login 请求。

三、总结

过滤器和拦截器区别:

过滤器(Filter)

拦截器(Interceptor)

调用方

Filter 被Server(Tomcat)调用

被Spring调用

实现方式

基于函数回调

基于Java反射

定义位置

是在java.servlet包下

接口HandlerInterceptor定义在org.springframework.web.servlet包下

作用位置

Filter只在Servlet前后起作用

拦截器可以在方法前后、异常抛出前后等

拦截器和过滤器同时存在时执行流程如下图所示:

代码仓库链接:https://gitee.com/duan138/practice-code/tree/dev/

下一篇文章我们使用过滤器和拦截器实现基于 Token 认证的登录功能。


改变你能改变的,接受你不能改变的,关注公众号:程序员康康,一起成长,共同进步。

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

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

相关文章

Mac 环境多JDK安装与切换

一、下载jdk 去Oracle官网上下载想要安装的jdk版本&#xff0c;M芯片选择arm架构的.bmg格式的文件。 https://www.oracle.com/java/technologies/downloads/。 二、安装jdk 2.1 双击下载的文件&#xff0c;安装步骤一步步点继续就好。 2.2 安装完成后会在/Library/Java/JavaV…

【Linux Shell】9. 流程控制

文章目录 【 1. if else 判断 】1.1 if1.2 if else1.3 if elif else1.4 实例 【 2. case 匹配 】【 3. 循环 】3.1 for 循环3.2 while 循环3.3 until 循环3.4 无限循环3.5 跳出循环3.5.1 break 跳出所有循环3.5.2 continue 仅跳出当前循环 【 1. if else 判断 】 1.1 if fi 是…

国际新产品开发专业认证-NPDP

&#x1f451;NPDP认证是美国产品开发管理协会(PDMA)所发起的新产品开发专业认证&#xff0c;是国际公认的wei一的新产品开发专业认证。 ✍&#x1f3fb;NPDP考试每年考2次&#xff0c;分别在每年的5月和11月。考试一共200道单选题&#xff0c;做对150道及格通过考试。 &#x…

应用层

title: 应用层 date: 2023-12-20 21:03:48 tags: 知识总结 categories: 计算机网络 应用层&#xff1a;负责最直观的应用请求的封装、发起 一、域名系统DNS 连接在互联网上的主机不仅有IP地址&#xff0c;还有便于用户记忆的主机名字。域名系统DNS能够把互联网上的主机的名字…

亲测有效:腾讯云免费服务器30天申请流程

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云百科txybk.com分享2024年最新腾讯云免费服务器…

【Unity】如何在Unity中使用C#的NuGet 包资源

【背景】 Unity的脚本语言是C#&#xff0c;而C#有很多功能和能力可以通过nuget包提供。有没有办法把这些能力结合到Unity中一起使用呢&#xff1f;如果可以&#xff0c;那将大大扩展Unity中各类功能实现的便捷性。 【方法】 答案是&#xff1a;你可以&#xff01; 获取Nuge…

uniapp使用tcp和udp的区别和例子

在Node.js中&#xff0c;主要有三种socket&#xff1a;TCP&#xff0c;UDP和Unix域套接字。以下分别介绍这TCP/UDP的使用方法和示例&#xff1a; TCP socket TCP socket提供了可靠的、面向连接的通信流&#xff0c;适用于需要可靠传输的应用&#xff0c;例如Web浏览器的HTTP请…

[实践总结] java XML解析防止外部实体注入

防止部实体注入 /*** 增加防止部实体注入逻辑*/ public static void setReaderFeature(SAXReader reader) throws SAXException {// 禁用DTDreader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);// 禁用外部DTDreader.setFeature(&qu…

cpu缓存一致性

文章目录 cpu缓存一致性缓存的出现&#xff1a;多核之后带来的缓存一致性问题&#xff0c;如何解决LOCK 指令&#xff08;刚好可以实现上述的目标&#xff09;LOCK 指令特性内存屏障特性编译器屏障的作用MESI协议为什么有了 MESI协议 还需要 内存屏障问题&#xff1a;总结&…

创建第一个SpringMVC项目,入手必看!

文章目录 创建第一个SpringMVC项目&#xff0c;入手必看&#xff01;1、新建一个maven空项目&#xff0c;在pom.xml中设置打包为war之前&#xff0c;右击项目添加web框架2、如果点击右键没有添加框架或者右击进去后没有web框架&#xff0c;点击左上角file然后进入项目结构在模块…

gem5学习(9):构建gem5——Building gem5

目录 一、Requirements for gem5 二、Getting the code 三、Your first gem5 build 1、gem5 binary types 四、Common errors 1、gcc版本过低 2、使用非默认版本的python 3、未安装M4宏处理器 4、Protobuf版本过低 前面的gem5学习&#xff08;3&#xff09;—&#xf…

基于Java SSM框架实现游戏论坛平台系统项目【项目源码+论文说明】

基于java的SSM框架实现游戏论坛平台系统演示 摘要 本论文主要论述了如何使用java语言开发一个游戏论坛平台的设计&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构、ssm 框架和 java 开发的 Web 框架&#xff0c;基于Werkzeug WSGI工具箱和…

react antd EditableProTable - 可编辑表格

与编辑表格外的内容联动 value 同 dataSource&#xff0c;传入一个数组,是 table 渲染的元数据 T[] undefined onChange dataSource 修改时触发&#xff0c;删除和修改都会触发,如果设置了 value&#xff0c;Table 会成为一个受控组件。 (value:T[])>void undefined recordC…

梨花妖传说

在这个现代都市的喧嚣中&#xff0c;有一座被人们称之为“梨花城”的城市。这里是一个充满了高楼大厦、繁华街道和现代科技的城市&#xff0c;然而&#xff0c;在这个城市的某个角落&#xff0c;隐藏着一个神秘而美丽的存在——梨花妖。 梨花妖的名字叫做梨儿&#xff0c;她拥…

Hello 2024(A~D,F1)

新年坐大牢 A - Wallet Exchange 题意&#xff1a;共有俩钱包&#xff0c;每回合从其中一个钱包中拿走一块钱&#xff0c;谁拿走最后一块钱谁赢。 思路&#xff1a;奇偶讨论即可。 // Problem: A. Wallet Exchange // Contest: Codeforces - Hello 2024 // URL: https://cod…

BERT 模型是什么

科学突破很少发生在真空中。相反&#xff0c;它们往往是建立在积累的人类知识之上的阶梯的倒数第二步。要了解 ChatGPT 和 Google Bart 等大型语言模型 &#xff08;LLM&#xff09; 的成功&#xff0c;我们需要回到过去并谈论 BERT。 BERT 由 Google 研究人员于 2018 年开发&…

docker的安装使用以及优势

前段时间和朋友开发电商分布式项目作为学习&#xff0c;由于远程开发的需要&#xff0c;需要将redis,mysql,mq等一些基础的服务放在阿里云服务器上&#xff0c;并使用docker来安装这些服务&#xff0c;使容器服务化。 1.使用docker的优势 将 Redis 和 MySQL 等数据库直接安装在…

C++合并K个有序链表

本篇博客介绍如何使用C合并k个有序链表&#xff0c;在代码中会用到std::priority_queue&#xff0c;首先需要介绍一下std::priority_queue的用法&#xff0c;介绍完std::priority_queue后将介绍如何使用std::priority_queue来辅助合并k个有序链表。 一、C priority_queue用法介…

RTMO:迈向高性能的单阶段实时多人姿态估计

摘要 https://arxiv.org/pdf/2312.07526.pdf 实时多人姿态估计在平衡速度和精度方面提出了重大挑战。虽然两阶段自上而下的方法随着图像中人数增加而变慢&#xff0c;但现有的单阶段方法往往无法同时提供高精度和实时性能。本文介绍了RTMO&#xff0c;这是一种单阶段姿态估计框…

用通俗易懂的方式讲解:如何提升大模型 Agent 的能力?

大型语言模型&#xff08;LLM&#xff09;的出现带火了Agent。利用LLM理解人类意图、生成复杂计划并且能够自主行动的能力。Agent具有无与伦比的能力&#xff0c;能够做出类似于人类复杂性的决策和完成一些复杂的工作。 目前市面上已经出现非常多得Agent框架&#xff1a;XAgen…