Springboot教程(二)——过滤器、拦截器

过滤器

过滤器可以在调用控制器方法之前进行一些操作,过滤器类一般放在filter包下。

配置类注册

使用过滤器时,要实现Filter接口,并重写doFilter方法:

class TestFilter : Filter {override fun doFilter(request: ServletRequest?, response: ServletResponse?, chain: FilterChain?) {// 逻辑chain?.doFilter(request, response)}
}

这里要注意,过滤器最后应调用chain.doFilter(request, response)方法,将请求交给后一个过滤器。当然,有些时候不想交给后一个过滤器,也可以不写

要启用过滤器,需要写一个配置类,用@Configuration标注。在配置类中,定义一个方法,用@Bean标注,这个方法需要先获取一个FilterRegistrationBean<T>对象,用于注册过滤器,再对这个对象进行一些操作,最后返回这个对象。这里面有一个泛型,表示要注册的过滤器的类型:

@Configuration
class TestConfig {@Beanfun getFilter(): FilterRegistrationBean<TestFilter>{val bean = FilterRegistrationBean<TestFilter>()// 逻辑return bean}}

 它的基本操作如下:

    @Beanfun getFilter(): FilterRegistrationBean<TestFilter>{val bean = FilterRegistrationBean<TestFilter>()bean.filter = TestFilter()    // 设置注册过滤器的对象bean.order = 1                // 设置过滤器优先级,值越小优先级越高,1是最顶级bean.addUrlPatterns("/index") // 设置过滤的路径bean.setName("testFilter")    // 设置过滤器的名字return bean}

我们来实践一下:

在项目下创建filter包,在filter包下创建TestFilter类:

package com.example.c0101.filterimport jakarta.servlet.Filter
import jakarta.servlet.FilterChain
import jakarta.servlet.ServletRequest
import jakarta.servlet.ServletResponseclass TestFilter : Filter {override fun doFilter(request: ServletRequest?, response: ServletResponse?, chain: FilterChain?) {println("doFilter")chain?.doFilter(request, response)}
}

这个类实现了Filter接口,重写了doFilter方法,表示过滤器的操作。在这里面只是打印了"doFilter"的信息。

在项目下创建config包,在config包下创建TestConfig类:

package com.example.c0101.configimport com.example.c0101.filter.TestFilter
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration@Configuration
class TestConfig {@Beanfun getFilter(): FilterRegistrationBean<TestFilter>{val bean = FilterRegistrationBean<TestFilter>()bean.filter = TestFilter()    // 设置注册过滤器的对象bean.addUrlPatterns("/index") // 设置过滤的路径return bean}}

这个类用于注册一个TestFilter的过滤器。

在项目下创建controller包,在controller包下创建TestController类:

package com.example.c0101.controllerimport org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController@RestController
class TestController {@RequestMapping("/index")fun index(): String{println("进入index方法")return "这是主页"}
}

这个控制器注册了/index的路径,返回一个"这是主页"的字符串。

我们用浏览器访问http://127.0.0.1:8080/index,然后回到idea里,发现控制台输出:

doFilter
进入index方法

因为过滤器会在进入方法之前执行


@WebFilter注解注册

将@WebFilter标注在过滤器类上,可以快速注册一个过滤器。但是,@WebFilter需要和@Component同时使用,这样才能被Spring Boot扫描到:

@WebFilter("/index")
@Component
class TestFilter : Filter {override fun doFilter(request: ServletRequest?, response: ServletResponse?, chain: FilterChain?) {println("doFilter")chain?.doFilter(request, response)}
}

Spring Boot的扫描

提到了“被Spring Boot扫描到”,那就讲一下扫描。Spring Boot的主类是创建项目时就自带的XXXApplication.kt内定义的XXXApplication:

@SpringBootApplication
class C0101Applicationfun main(args: Array<String>) {runApplication<C0101Application>(*args)
}

这个类被@SpringBootApplication注解标注,这个注解源码的最核心注解有如三个:

  • @SpringBootConfiguration 让项目采用Java注解的配置方式,而不是xml配置方式
  • @EnableAutoConfiguration 开启自动配置,启动时可以自动加载配置文件和配置类
  • @ComponentScan 启动组件扫描器。组件扫描器可以扫描被@Component注解标注的类

所以说,一个类想要被扫描到,就必须被@Component注解标注。我们之前学的@Controller、@Configuration等注解,其实上内部都有@Component注解,因此可以被扫描到

@WebFilter实践

删除原来项目的配置类和config包,在TestFilter类上标注:

@WebFilter("/index")
@Component

运行代码,在浏览器访问http://127.0.0.1:8080/index,控制台输出:

doFilter
进入index方法

和我们之前的结果一样

拦截器

定义一个拦截器类,需要继承HandlerInterceptor接口,通过重写preHandle、postHandle、afterCompletion方法,设置一个请求的不同时期的拦截方法:

事件
收到请求
过滤器doFilter方法
拦截器preHandle方法
控制器对应的方法
拦截器postHandle方法
解析视图
请求结束
拦截器afterCompletion方法

定义拦截器的代码如下:

class TestInterceptor : HandlerInterceptor {override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {println("preHandle")return true}override fun postHandle(request: HttpServletRequest,response: HttpServletResponse,handler: Any,modelAndView: ModelAndView?) {println("postHandle")}override fun afterCompletion(request: HttpServletRequest,response: HttpServletResponse,handler: Any,ex: Exception?) {println("afterCompletion")}
}

这里面preHandle方法的返回值如果为true表示正常执行,如果为false表示阻止请求正常执行

注册一个拦截器,需要创建配置类,继承WebMvcConfigurer接口并重写addInterceptors方法,这个方法会传入一个registry参数,我们需要调用它的addInterceptor方法,并接收它的返回值,再用这个返回值调用addPathPatterns方法设置要拦截的路径:

@Configuration
class TestConfig : WebMvcConfigurer{override fun addInterceptors(registry: InterceptorRegistry) {val regist = registry.addInterceptor(TestInterceptor())regist.addPathPatterns("/index")}
}

我们来实践一下

网站的某些路径需要用户先登录才能访问,那么如何确保用户已经登录呢?

最常用的做法是,在用户登录后给用户一个访问令牌,用户访问其他路径时,需要将访问令牌传给服务器,服务器再对访问令牌进行判断。我们可以通过拦截器简单的模拟拦截访问令牌:

创建一个interceptor包,创建TestInterceptor类:

package com.example.c0101.interceptorimport jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.web.servlet.HandlerInterceptorclass TestInterceptor : HandlerInterceptor {override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {val token = request.getParameter("token")return if (token == "token") true else{response.status = 401val outputStream = response.outputStreamoutputStream.write("令牌错误".toByteArray())false}}}

代码首先通过request.getParameter方法获取token参数(访问令牌),然后判断这个访问令牌是否正确(为了方便起见,我们通过判断访问令牌是否为"token"来判断访问令牌是否正确),如果正确则请求正常执行,否则通过response.setStatus方法设置请求状态码(401:当前请求需要用户验证),然后通过response.getOutputStream获取响应的输出流,再向这个输出流写入"令牌错误"的信息,然后阻止请求执行

关于request、response这里不多讲,它们是Servlet里的类的对象

接下来创建config包,再config包下创建TestConfig类:

package com.example.c0101.configimport com.example.c0101.interceptor.TestInterceptor
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer@Configuration
class TestConfig : WebMvcConfigurer{override fun addInterceptors(registry: InterceptorRegistry) {val regist = registry.addInterceptor(TestInterceptor())regist.addPathPatterns("/index")}
}

将/index路径注册了TestInterceptor拦截器

接下来用postman访问http://127.0.0.1:8080/index,进行传入token和不传入token的测试:

 可以发现,拦截器成功拦截了令牌错误的访问

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

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

相关文章

对数据结构的初步认识

前言: 牛牛开始更新数据结构的知识了.本专栏后续会分享用c语言实现顺序表,链表,二叉树,栈和队列,排序算法等相关知识,欢迎友友们互相学习,可以私信互相讨论哦! &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&a…

【简写Mybatis】02-注册机的实现以及SqlSession处理

前言 注意&#xff1a; 学习源码一定一定不要太关注代码的编写&#xff0c;而是注意代码实现思想&#xff1a; 通过设问方式来体现代码中的思想&#xff1b;方法&#xff1a;5W1H 源代码&#xff1a;https://gitee.com/xbhog/mybatis-xbhog&#xff1b;https://github.com/xbh…

%00截断 [GKCTF 2020]cve版签到

打开题目 F12之后在Headers中发现hint 两者结合利用零字符截断使get_headers()请求到本地127.0.0. 结合链接 构造 ?urlhttp://127.0.0.1%00www.ctfhub.com 必须以123结尾 ?urlhttp://127.0.0.123%00www.ctfhub.com 得到flag 知识点&#xff1a; PHP中get_headers函数 g…

解析ChatGPT Plus相比chatgpt3.5有哪些优势

「ChatGPT Plus」提供更出色的对话体验和更广泛的应用能力&#xff0c;学生可以用来写作、职场人也可以用来写计划书、策划书等等&#xff0c;并且问它一些问题比搜索引擎好用多了简直。但普通人使用起来有一点门槛&#xff0c;并且升级4.0也难住了许多爱好者。 ChatGPT主要功能…

【Excel PDF 系列】EasyExcel + iText 库

你知道的越多&#xff0c;你不知道的越多 点赞再看&#xff0c;养成习惯 如果您有疑问或者见解&#xff0c;欢迎指教&#xff1a; 企鹅&#xff1a;869192208 文章目录 前言转换前后效果引入 pom 配置代码实现定义 ExcelDataVo 对象主方法EasyExcel 监听器 前言 最近遇到生成 …

微信小程序蓝牙通信HC08

总结这两天研究的蓝牙串口。人话版资料不多&#xff0c;主要靠翻别人的仓库和文档。 单片机部分&#xff0c;与蓝牙串口通信是通过串口。比我想的要简单&#xff0c;小程序部分&#xff0c;有非常多的服务和特征&#xff0c;而且人话版资料不多。 如果本文有什么问题&#xf…

AI绘画工具合集,让想象触手可及!

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

【目标检测新SOTA!v7 v4作者新作!】YOLO v9 思路设计 + 全流程优化 + 手把手训练自己数据

YOLO v9 思路复现 全流程优化 手把手训练自己数据 提出背景&#xff1a;深层网络的 信息丢失、梯度流偏差YOLO v9 设计逻辑可编程梯度信息&#xff08;PGI&#xff09;&#xff1a;使用PGI改善训练过程广义高效层聚合网络&#xff08;GELAN&#xff09;&#xff1a;使用GELAN…

华为数通方向HCIP-DataCom H12-821题库(单选题:481-500)

第481题 以下关于基于SD-WAN思想的EVPN互联方案的描述,错误的是哪一项? A、通过部署独立的控制面,将网络转发和控制进行了分离,从而实现了网络控制的集中化 B、通过对WAN网络抽象和建模,将上层网络业务和底层网络具体实现架构进行解耦,从而实现网络自动化 C、通过集中的…

四、分类算法 - 决策树

目录 1、认识决策树 2、决策树分类原理详解 3、信息论基础 3.1 信息 3.2 信息的衡量 - 信息量 - 信息熵 3.3 决策树划分的依据 - 信息增益 3.4 案例 4、决策树API 5、案例&#xff1a;用决策树对鸢尾花进行分类 6、决策树可视化 7、总结 8、案例&#xff1a;泰坦尼…

深度学习手写字符识别:推理过程

说明 本篇博客主要是跟着B站中国计量大学杨老师的视频实战深度学习手写字符识别。 第一个深度学习实例手写字符识别 深度学习环境配置 可以参考下篇博客&#xff0c;网上也有很多教程&#xff0c;很容易搭建好深度学习的环境。 Windows11搭建GPU版本PyTorch环境详细过程 数…

stable diffusion学习笔记 手部修复

图片手部修复原理 某张图片在生成后&#xff0c;仅有手部表现不符合预期&#xff08;多指&#xff0c;畸形等&#xff09;。这种情况下我们通常使用【局部重绘】的方式对该图片的手部进行【图生图】操作&#xff0c;重新绘制手部区域。 但是仅采用重绘的方式也很难保证生成的…

python爬虫实战:获取电子邮件和联系人信息

引言 在数字时代&#xff0c;电子邮件和联系人信息成为了许多企业和个人重要的资源&#xff0c;在本文中&#xff0c;我们将探讨如何使用Python爬虫从网页中提取电子邮件和联系人信息&#xff0c;并附上示例代码。 目录 引言 二、准备工作 你可以使用以下命令来安装这些库&a…

将文件从windows传入到ubuntu

实现效果图 2.方法&#xff1a; 2.1打开 Ubuntu 的终端窗口&#xff0c;然后执行如下命令来安装 FTP 服务 输入&#xff1a;sudo apt-get install vsftpd 等待软件自动安装&#xff0c;安装完成以后使用如下 VI 命令打开/etc/vsftpd.conf&#xff0c;命令如下&#xff1a;su…

Git Windows安装教程

Git简介 Git是目前世界上最先进的分布式版本控制系统。它的工作原理 / 流程如下&#xff1a; [ Workspace:工作区 Index / Stage:暂存区 Repository:仓库区&#xff08;或本地仓库&#xff09; Remote:远程仓库 ] Git的下载 去 Git 官网下载对应系统的软件了&#xff0c;下…

用39块钱的全志V851se视觉开发板做了个小相机,还可以物品识别、自动追焦!

用39块钱的V851se视觉开发板做了个小相机。 可以进行物品识别、自动追焦&#xff01; 这个超低成本的小相机是在V851se上移植使用全志在线开源版本的Tina Linux与OpenCV框架开启摄像头拍照捕获视频&#xff0c;并结合NPU实现Mobilenet v2目标分类识别以及运动追踪等功能…并最终…

dolphinscheduler集群部署教程

文章目录 前言一、架构规划二、配置集群免密登录1. 配置root用户集群免密登录1.1 hadoop101节点操作1.2 hadoop102节点操作1.3 hadoop103节点操作 2. 创建用户2.1 hadoop101节点操作2.2 hadoop102节点操作2.3 hadoop103节点操作 三、安装准备1. 安装条件2. 安装jdk3. 安装MySQL…

“智能语音指令解析“ 基于NLP与语音识别的工单关键信息提取

“智能语音指令解析“ 基于NLP与语音识别的工单关键信息提取 1. 背景介绍1.1 场景痛点1.2 方案选型 2. 准备开发环境3. PaddleSpeech 语音识别快速使用4. PaddleNLP 信息抽取快速使用5. 语音工单信息抽取核心功能实现6. 语音工单信息抽取网页应用6.1 网页前端6.2 网页后端6.3 a…

C# Onnx yolov8-obb 旋转目标检测

目录 效果 模型信息 项目 代码 下载 C# Onnx Yolov8-OBB 旋转目标检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-02-26T08:38:44.171849 description&#xff1a;Ultralytics YOLOv8s-obb model trained on runs/DOTAv1.0-ms.ya…

解决:“出现问题,Outlook 无法设置你的账户”

原文&#xff1a;https://blog.iyatt.com/?p14213 1 问题描述 Office 专业版 2024 预览版 在 Outlook 输入邮箱后无法进一步配置登录信息&#xff08;腾讯企业邮箱 Exchange 登录&#xff09; 2 解决方法 通过控制面板里的邮箱设置可以正常添加登录&#xff0c;而且能…