掌握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:与配置顺序相反,可能不运行。

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

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

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

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

相关文章

操作系统课程设计-内存管理

目录 前言 1 实验题目 2 实验目的 3 实验内容 3.1 步骤 3.2 关键代码 3.2.1 显示虚拟内存的基本信息 3.2.2 遍历当前进程的虚拟内存 4 实验结果与分析 5 代码 前言 本实验为课设内容,博客内容为部分报告内容,仅为大家提供参考,请勿直…

【计算机网络】【新加坡南洋理工大学】【Computer Control Network】【广域网和局域网简介】【中英对照(自译)】

一、说明 仅供学习使用。 二、广域网(WAN)和局域网(LAN)简介

思瑞浦与IAR携手共筑嵌入式开发新生态--AMEYA360

2024年1月18日思瑞浦与IAR联合宣布,IAR旗舰产品IAR Embedded Workbench for Arm已全面支持思瑞浦TPS32混合信号微控制器主流系列产品,为开发者提供更完整、高效的开发解决方案。 思瑞浦总部位于中国,提供模拟及嵌入式处理器产品和解决方案&am…

腊八与健康,探寻羊奶与腊八渊源的奥秘

腊八与健康,探寻羊奶与腊八渊源的奥秘 腊八这个传统节日在我国有着悠久的历史,它是在农历腊月初八举行的一个重要的节日。腊月初八,民间有吃腊八粥的习俗,这是一种由多种杂粮、豆、米、枸杞等制作而成的美味佳肴。而在腊八粥中&a…

django后台手机号加密存储

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

AVL树 -- C++实现

AVL树 – C实现 1. AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1…

【软件测试】学习笔记-精准测试

软件测试行业从最开始的手工测试到自动化测试,从黑盒测试到白盒测试,测试理念和技术都发生了日新月异的变化。现如今,几乎所有的软件公司都有一套强大且复杂的自动化测试用例,用来夜以继日地保证产品的正确性和稳定性。 然而&…

selenium爬虫爬取当当网书籍信息 | 最新!

如果对selenium不了解的话可以到下面的链接中看基础内容: selenium爬取有道翻译-CSDN博客 废话不多说了下面是代码并且带有详细的注释: 爬取其他类型的书籍和下面基本上是类似的可以自行更改。 # 导入所需的库 from selenium import webdriver from …

6.3.3分离音频和视频

6.3.3分离音频和视频 Camtasia4有一个很实用的功能,那就是能够把视频片段中的视频和音频分离开来,这在多媒体作品创作中非常有用。 1.启动Camtasia音频编辑器。 2.选择【文件】|【打开】命令,在弹出的“打开文件”对…

企业面临哪些能源消耗问题,能源消耗监测管理系统是如何解决这些问题?

随着全球环境问题的日益严重,能源问题一直被世界广泛关注。在企业运营过程中,能源消耗问题也是一大挑战。企业在生产和运营过程中需要大量的能源支持,包括电、水、气、热等多种能源。由于能源价格的不稳定性,使得企业在能源消耗方…

【北亚企安数据恢复】RAIDZ多块磁盘离线导致服务器崩溃的数据恢复案例

服务器数据恢复环境: ORACLE SUN ZFS某型号存储,共40块磁盘组建存储池,其中的36块磁盘分为三组,每组12块,单个组使用ZFS特有的RAIDZ管理所有磁盘,RAIDZ级别为2;另外的4块磁盘作为全局热备。存储…

Dubbo分层设计之Exchange层

前言 Dubbo 框架采用分层设计,自上而下共分为十层。Exchange 层位于倒数第三层,它在 协议层 的下方、数据传输层的上方。 第一次看源码的时候,大家应该都会有一个疑问:都已经有 Transport 层了,为啥还要定义 Exchange…

JAVA调试webservice接口

java程序调试webservice接口可以使用调用工具进行调试,对应的调试工具 可在这个目录下面下载 SoapUI 下载地址:https://www,soapui.org/ 一、webservice项目可以使用soapUi 可以使用工具进行调试的前提是这个接口地址必须在前端的浏览器能够正常的打…

uniapp 获取外设键盘输入(扫码器/扫码枪/读卡器等)

前言 在使用uniapp开发收银机等设备时,常常会用到使用键盘输入的外设,如使用扫码器/扫码枪读取条形码/二维码等,及使用读卡器读取卡ID(需要读卡器支持键盘输入卡ID,此种方式只支持读取未加密的卡ID信息,读…

通过OpenIddict设计一个授权服务器03-客户凭证流程

在本部分中,我们将把 OpenIddict 添加到项目中,并实施第一个授权流程:客户端凭证流。 添加 OpenIddict 软件包 首先,我们需要安装 OpenIddict NuGet 软件包 dotnet add package OpenIddict dotnet add package OpenIddict.AspN…

uniapp+vue3打包问题记录

**背景:**打包app出现问题,只显示底部导航的文字,其他一片空白 1. pages.json文件:tabBar中的iconPath图标格式不支持svg,只支持:png, jpg, jpeg的格式,当图片改为.png的时候可以正常显示 2. …

【数学建模】2024年华数杯国际赛B题-光伏发电Photovoltaic Power 思路、代码、参考论文

1 问题背景 中国电力构成包括传统能源(如煤炭、石油、天然气)、可再生能源(如水电、风能、太阳能、核能)和其他形式的电力。这些发电模式在满足中国巨大的电力需求方面发挥着至关重要的作用。据最新数据显示,中国总发电量超过20万亿千瓦时,居世界第一。…

idea社区版 MybatisCodeHelperPro插件使用介绍

文章目录 一、插件介绍二、idea社区版安装MybatisCodeHelperPro插件三、问题记录1. DatabaseHelper插件 加载不了部分数据库链接的列信息2. DatabaseHelper插件 数据库列显示顺序错乱3. MybatisCodeHelperPro插件 数据库字段不提示4. MybatisCodeHelperPro插件 特殊字段增加反引…

Skywalking链路追踪

目录 一、简介1.1、APM系统1.2、SkyWalking 简介 二、快速入门2.1、下载、启动2.2、界面认识 三、持久化存储四、告警通知五、自定义追踪-细粒度追踪service方法 一、简介 1.1、APM系统 APM(Application Performance Monitoring)系统是一种用于监控和管…

VR风景园林虚拟仿真系统编辑工具支持可视化预览成本低

为了帮助更多人快速、高效地构建虚拟现实应用系统,提高开发效率,降低成本投入,VR虚拟现实交互系统编辑器作为一种用于创建和编辑虚拟现实应用程序的工具,采用可视化界面提示和简单操作就能快速制作VR虚拟现实交互系统。 VR虚拟现实…