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

掌握Spring MVC拦截器整合技巧,实现灵活的请求处理与权限控制!

拦截器

    • 1.1 拦截器概念
    • 1.2 拦截器入门案例
      • 1.2.1 环境准备
      • 1.2.2 拦截器开发
        • 步骤1:创建拦截器类
        • 步骤2:配置拦截器类
        • 步骤3:SpringMVC添加SpringMvcSupport包扫描
        • 步骤4:运行程序测试
        • 步骤5:修改拦截器拦截规则
        • 步骤6:简化SpringMvcSupport的编写
    • 1.3 拦截器参数
      • 1.3.1 前置处理方法
      • 1.3.2 后置处理方法
      • 1.3.3 完成处理方法
    • 1.4 拦截器链配置
      • 1.4.1 配置多个拦截器
        • 步骤1:创建拦截器类
        • 步骤2:配置拦截器类

1.1 拦截器概念

在这里插入图片描述

(1)浏览器发送一个请求会先到Tomcat的web服务器。

(2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源。

(3)如果是静态资源,会直接到Tomcat的项目部署目录下去直接访问。

(4)如果是动态资源,就需要交给项目的后台代码进行处理。

(5)在找到具体的方法之前,我们可以去配置过滤器(可以配置多个),按照顺序进行执行。

(6)然后进入到到中央处理器,SpringMVC会根据配置的规则进行拦截。

(7)如果满足规则,则进行处理,找到其对应的controller类中的方法进行执行,完成后返回结果。

(8)如果不满足规则,则不进行处理。

(9)这个时候,如果我们需要在每个Controller方法执行的前后添加业务,具体该如何来实现?

这个就是拦截器要做的事。

  • 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
  • 作用:
    • 在指定的方法调用前后执行预先设定的代码。
    • 阻止原始方法的执行。
    • 总结:拦截器就是用来做增强。

看完以后,大家会发现

  • 拦截器和过滤器在作用和执行顺序上也很相似。

所以这个时候,就有一个问题需要思考:拦截器和过滤器之间的区别是什么?

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术。
  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强。
    在这里插入图片描述

1.2 拦截器入门案例

1.2.1 环境准备

  • 创建一个Web的Maven项目

  • pom.xml添加SSM整合所需jar包

  • 创建对应的配置类

  • 创建模型类Book

  • 编写Controller

    @RestController
    @RequestMapping("/books")
    public class BookController {@PostMappingpublic String save(@RequestBody Book book){System.out.println("book save..." + book);return "{'module':'book save'}";}@DeleteMapping("/{id}")public String delete(@PathVariable Integer id){System.out.println("book delete..." + id);return "{'module':'book delete'}";}@PutMappingpublic String update(@RequestBody Book book){System.out.println("book update..."+book);return "{'module':'book update'}";}@GetMapping("/{id}")public String getById(@PathVariable Integer id){System.out.println("book getById..."+id);return "{'module':'book getById'}";}@GetMappingpublic String getAll(){System.out.println("book getAll...");return "{'module':'book getAll'}";}
    }
    

1.2.2 拦截器开发

步骤1:创建拦截器类

让类实现HandlerInterceptor接口,重写接口中的三个方法。

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {@Override//原始方法调用前执行的内容public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...");return true;}@Override//原始方法调用后执行的内容public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}@Override//原始方法调用完成后执行的内容public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...");}
}

注意:拦截器类要被SpringMVC容器扫描到。

步骤2:配置拦截器类
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books" );}
}
步骤3:SpringMVC添加SpringMvcSupport包扫描
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig{}
步骤4:运行程序测试

使用PostMan发送http://localhost/books
在这里插入图片描述

如果发送http://localhost/books/100会发现拦截器没有被执行,原因是拦截器的addPathPatterns方法配置的拦截路径是/books,我们现在发送的是/books/100,所以没有匹配上,因此没有拦截,拦截器就不会执行。

步骤5:修改拦截器拦截规则
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*" );}
}

这个时候,如果再次访问http://localhost/books/100,拦截器就会被执行。

拦截器中的preHandler方法,如果返回true,则代表放行,会执行原始Controller类中要请求的方法,如果返回false,则代表拦截,后面的就不会再执行了。

步骤6:简化SpringMvcSupport的编写
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}
}

此后咱们就不用再写SpringMvcSupport类了。

最后我们来看下拦截器的执行流程:
在这里插入图片描述

当有拦截器后,请求会先进入preHandle方法,

​ 如果方法返回true,则放行继续执行后面的handle[controller的方法]和后面的方法。

​ 如果返回false,则直接跳过后面方法的执行。

1.3 拦截器参数

1.3.1 前置处理方法

原始方法之前运行preHandle

public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("preHandle");return true;
}
  • request:请求对象
  • response:响应对象
  • handler:被调用的处理器对象,本质上是一个方法对象,对反射中的Method对象进行了再包装

使用request对象可以获取请求数据中的内容,如获取请求头的Content-Type

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contentType = request.getHeader("Content-Type");System.out.println("preHandle..."+contentType);return true;
}

使用handler参数,可以获取方法的相关信息

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HandlerMethod hm = (HandlerMethod)handler;String methodName = hm.getMethod().getName();//可以获取方法的名称System.out.println("preHandle..."+methodName);return true;
}

1.3.2 后置处理方法

原始方法运行后运行,如果原始方法被拦截,则不执行

public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("postHandle");
}

前三个参数和上面的是一致的。

modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整

因为咱们现在都是返回json数据,所以该参数的使用率不高。

1.3.3 完成处理方法

拦截器最后执行的方法,无论原始方法是否执行

public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("afterCompletion");
}

前三个参数与上面的是一致的。

ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理。

因为我们现在已经有全局异常处理器类,所以该参数的使用率也不高。

这三个方法中,最常用的是preHandle,在这个方法中可以通过返回值来决定是否要进行放行,我们可以把业务逻辑放在该方法中,如果满足业务则返回true放行,不满足则返回false拦截。

1.4 拦截器链配置

目前,我们在项目中只添加了一个拦截器,如果有多个,该如何配置?配置多个后,执行顺序是什么?

1.4.1 配置多个拦截器

步骤1:创建拦截器类

实现接口,并重写接口中的方法

@Component
public class ProjectInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...222");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...222");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...222");}
}
步骤2:配置拦截器类
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Autowiredprivate ProjectInterceptor2 projectInterceptor2;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");}
}

步骤3:运行程序,观察顺序
在这里插入图片描述

拦截器执行的顺序是和配置顺序有关,先进后出。

  • 当配置多个拦截器时,形成拦截器链。
  • 拦截器链的运行顺序参照拦截器添加顺序为准。
  • 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行。
  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作。
    在这里插入图片描述

preHandle:与配置顺序相同,必定运行

postHandle:与配置顺序相反,可能不运行

afterCompletion:与配置顺序相反,可能不运行。

这个顺序不太好记,最终只需要把握住一个原则即可:以最终的运行结果为准

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹

相关文章:

掌握Spring MVC拦截器整合技巧,实现灵活的请求处理与权限控制!

拦截器 1.1 拦截器概念1.2 拦截器入门案例1.2.1 环境准备1.2.2 拦截器开发步骤1:创建拦截器类步骤2:配置拦截器类步骤3:SpringMVC添加SpringMvcSupport包扫描步骤4:运行程序测试步骤5:修改拦截器拦截规则步骤6:简化SpringMvcSupport的编写 1.3 拦截器参数1.3.1 前置处理方法1.3…...

使用xbindkeys设置鼠标侧键

1.安装如下包 sudo apt install xbindkeys xautomation 2.生成配置文件 xbindkeys --defaults > $HOME/.xbindkeysrc 3.确定侧键键号 在终端执行下面的代码: xev | grep button 此时会出现如下窗口,将鼠标指针移动到这个窗口上: 单…...

跨站点请求伪造攻击 - Cross Site Request Forgery (CSRF)

什么是CSRF 最好理解CSRF攻击的方式是看一个具体的例子。 假设你的银行网站提供一个表单,允许当前登录用户将钱转账到另一个银行账户。例如,转账表单可能如下所示: <form method="post"action="/transfer"> <...

PLAN B KRYPTO ASSETS GMBH CO. KG 普兰资产管理公司

引领加密技术不断演进 PLAN B KRYPTO ASSETS普兰资产管理以其独创的「Trident Strategy三叉戟模型」技术为基础&#xff0c;持续推动加密技术的发展&#xff0c;打造 Schutz&#xff08;舒茨盾&#xff09; AI 金融隐私匿名公链。致力于提供高效的技术服务&#xff0c;基于机构…...

java接口和多态

1.接口 1.1黑马信息管理系统集合改进 (应用) 使用数组容器的弊端 容器长度是固定的&#xff0c;不能根据添加功能自动增长 没有提供用于赠删改查的方法 优化步骤 创建新的StudentDao类&#xff0c;OtherStudentDao 创建ArrayList集合容器对象 OtherStudentDao中的方法声明…...

C# 图解教程 第5版 —— 第22章 命名空间和程序集

文章目录 22.1 引用其他程序集22.2 命名空间22.2.1 命名空间名称22.2.2 命名空间的补充22.2.3 命名空间跨文件伸展22.2.4 嵌套命名空间 22.3 using 指令22.3.1 using 命名空间指令22.3.2 using 别名指令22.3.3 using static 指令 22.4 程序集的结构22.5 程序集标识符22.6 强命名…...

【Maven】008-Maven 私服搭建与使用

【Maven】008-Maven 私服搭建与使用 文章目录 【Maven】008-Maven 私服搭建与使用一、概述1、简介2、建立私服后依赖查找和下载逻辑第一步&#xff1a;请求本地仓库第二步&#xff1a;请求 Maven 私服第三步&#xff1a;请求外部远程仓库&#xff08;远程中央仓库等&#xff09…...

TMDB电影数据分析(下)

TMDB电影数据分析&#xff08;下&#xff09; 本文对源自Kaggle TMDB电影数据集进行分析影响电影票房的因素&#xff0c;数据分析流程包含数据集概分析、数据清洗、数据统计以及分析影响电影票房的因素。影响票房因素可能是电影预算、电影类型、电影时长、受欢迎程度、电影评分…...

django后台手机号加密存储

需求&#xff1a; 1 &#xff1a;员工在填写用户的手机号时&#xff0c;直接填写&#xff0c;在django后台中输入 2&#xff1a;当员工在后台确认要存储到数据库时&#xff0c;后台将会把手机号进行加密存储&#xff0c;当数据库被黑之后&#xff0c;手机号字段为加密字符 3&am…...

三、Qt Creator 使用

关于Qt的安装及环境配置&#xff0c;在我的上一篇《二、QT下载、安装及问题解决(windows系统)》已经讲过了。 本章节有一个重点&#xff0c;在新建 工程文件时&#xff0c;所在路径不要有中文&#xff0c;否则编译及运行程序不能正常运行。 在使用Qt Creator&#xff08;以下…...

css 边框渐变

需求&#xff1a; 普通的div 边框不好看&#xff0c;做一个渐变色 进程&#xff1a; 最简单的当然是做一个内部是白色的边框是渐变色的图&#xff0c;然后使用 background: url("back.jpg")&#xff0c;这样看起来就像是做了一个渐变的边框如果做不了图&#xff0…...

SofaMQ一些常用的API

SofaMQ的十五种常用的API 引言 SofaMQ作为阿里巴巴开源的消息中间件&#xff0c;提供了丰富的API以支持各种消息传递场景。在本文中&#xff0c;我们将介绍SofaMQ的十五种常用API&#xff0c;并通过实例演示其用法。 1. Producer相关API 1.1 SofaMQProducer SofaMQProduce…...

IIS 缓存, 更新后前端资源不能更新问题

解决办法: 通常只需要index.html 不缓存即可, 其他文件都是根据index.html 中的引用去加载; 正确的做法是在 站点下增加 web.config 文件, 内容如下: 我这个是因为目录下有个config.js 配置文件, 也不能缓存, 所以加了两个 <?xml version"1.0" encoding&quo…...

中科院罗小舟团队提出 UniKP 框架,大模型 + 机器学习高精度预测酶动力学参数

作者&#xff1a;李宝珠 编辑&#xff1a;三羊 中国科学院深圳先进技术研究院罗小舟团队提出了&#xff0c;基于酶动力学参数预测框架 (UniKP)&#xff0c;实现多种不同的酶动力学参数的预测。 众所周知&#xff0c;生物体内的新陈代谢是通过各种各样的化学反应来实现的。这…...

组件中写选项的顺序(vue的问题)

为什么选项要有统一的书写顺序呢&#xff1f;很简单&#xff0c;就是要将选择和认知成本最小化。 副作用 (触发组件外的影响) el全局感知 (要求组件以外的知识) nameparent组件类型 (更改组件的类型) functional模板修改器 (改变模板的编译方式) delimiterscomments模板依赖 (…...

LUA 对象转excel

1. 首先把LUA 转成JSON 对象 因为是excel, 所以第一层要是数组&#xff0c;否则没有什么意义&#xff0c;即lua对象要是一个数组比较合理。这里使用开源的json.lua&#xff0c; 但是开源的&#xff0c;对于数字作下标的&#xff0c;或者是一个数组里&#xff0c;不同类型的key…...

深入理解 Flink(八)Flink Task 部署初始化和启动详解

JobMaster 部署 Task 核心入口&#xff1a; JobMaster.onStart();部署 Task 链条&#xff1a;JobMaster --> DefaultScheduler --> SchedulingStrategy --> ExecutionVertex --> Execution --> RPC请求 --> TaskExecutor TaskExecutor 处理 JobMaster 的 …...

openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c

文章目录 openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c概述笔记END openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c 概述 开源工程包含的头文件类型是.inc, 要重命名为.h, 否则没有c头文件语法提示 从数组中载入大数p,q,g 建立ossl…...

【k8s】Kubernetes技术和相关命令简介

一、 Kubernetes简介 Kubernetes是Google开源的一个容器编排引擎&#xff0c;它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时&#xff0c;通常要部署该应用的多个实例以便对应用请求进行负载均衡。kubernetes&#xff0c;简称K8s&#xff0…...

清晰光谱空间:全自动可调波长系统的高光谱成像优势

高光谱成像技术 高光谱成像技术是一种捕获和分析宽波长信息的技术&#xff0c;能够对材料和特征进行详细的光谱分析和识别。高光谱成像技术的实现通过高光谱相机&#xff0c;其工作原理是使用多个光学传感器或光学滤波器分离不同波长的光&#xff0c;并捕获每个波段的图像&…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...