SpringMVC-2-Spring MVC拦截器详解:从入门到精通

SpringMVC-2-Spring MVC拦截器详解:从入门到精通

今日目标

能够编写拦截器并配置拦截器

1.拦截器【理解】

1 拦截器介绍

1.1 拦截器概念和作用

  • 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行

  • 作用:
    1. 在指定的方法调用前后执行预先设定的代码

    2. 阻止原始方法的执行

    3. 总结:增强

  • 核心原理:AOP思想

1.2 拦截器和过滤器的区别

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术

  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强

1.3 拦截器应用场景

拦截器本质上是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:

  • 登录验证,判断用户是否登录。

  • 权限验证,判断用户是否有权限访问资源,如校验token

  • 日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。

  • 处理cookie、本地化、国际化、主题等。

  • 性能监控,监控请求处理时长等。

2 入门案例

2.1 实现步骤

1 创建web工程(Maven web结构)
2 导入坐标(SpringMVC+Servlet)
3 SpringMVCConfig 配置类 配置前缀”/pages/”和后缀”.jsp”
4 ServletConfig 配置类创建IOC容器和拦截请求路径”/”
5 自定义控制器类(StudentController)
6 开发视图页面/pages/success.jsp

2.2 代码实现

【第一步】创建web工程(Maven结构)

【第二步】导入坐标(SpringMVC+Servlet)

<dependencies> <!--spring-webmvc-->  <dependency> <groupId>org.springframework</groupId>  <artifactId>spring-webmvc</artifactId>  <version>5.3.15</version> </dependency>  <!--servlet-->  <dependency> <groupId>javax.servlet</groupId>  <artifactId>javax.servlet-api</artifactId>  <version>4.0.1</version>  <scope>provided</scope> </dependency> 
</dependencies> 

【第三步】创建SpringMvc配置文件

/**
* SpringMVC配置类
*/
@Configuration //1.标识当前是配置类 指定这个类为配置类,替代application.xml
@ComponentScan("com.zbbmeta")//2.配置扫描web层包 代替<context:component-scan base-package="com.zbbmeta" />
@EnableWebMvc //如果使用接口的方式,拦截器需要添加这个注解。不建议使用这种方式,两种方式只能配置一种,否则会有冲突
public class SpringMvcConfig {
}

【第四步】创建Web容器初始化的配置类

public class ServletConfig  extends AbstractAnnotationConfigDispatcherServletInitializer {// 暂时不管,整合Spring才需要@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[0];}//在tomcat启动时调用,用于创建springmvc框架的IOC容器对象//加载springmvc配置类, Tomcat会拿这个配置类去创建IoC容器,产生springmvc容器(本质还是spring容器)@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[] {SpringMvcConfig.class};}// 指定SpringMVC要处理哪些请求, /表示SpringMVC处理项目中的所有请求, 静态资源不要让SpringMVC处理,要放行//设置DispatcherServlet绑定处理请求的路径"/",处理除了jsp的所有资源请求@Overrideprotected String[] getServletMappings() {return new String[] {"/"};}
}

【第五步】创建控制器

package com.zbbmeta.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
@RequestMapping("/student")//RequestMapping可以在类或者方法上添加
public class StudentController {/*** 查找Student*/@RequestMapping("/find")public String find(HttpServletRequest request, HttpServletResponse response) {System.out.println("查找Student");return "find success";}
}

2.3 拦截器代码实现

【第一步】定义拦截器

做法:定义一个类,实现HandlerInterceptor接口即可

package com.zbbmeta.Iinterceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class StudentInterceptor implements HandlerInterceptor {//原始方法调用前执行的内容//返回值类型可以拦截控制的执行,true放行,false终止@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("=================前置通知=================");return true;}//原始方法调用后执行的内容@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("=================后置通知=================");}//原始方法调用完成后执行的内容@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("=================最终通知=================");}
}

【第二步】配置加载拦截器

配置加载拦截器的方式有两种我们分别介绍:

加载拦截器方法1:

注:@Configuration注解已经包含@Component的功能

  1. 在上面添加静态资源的配置类中重写addInterceptors方法

  2. 添加拦截器和多个拦截路径:/book和/book/**

  3. 要注入拦截器对象

package com.zbbmeta.config;import com.zbbmeta.Iinterceptor.StudentInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//注解拦截器和拦截地址   表示添加 StudentInterceptor  取拦截路径是 /student/* 所有请求registry.addInterceptor(new StudentInterceptor()).addPathPatterns("/student/*");}
}
加载拦截器方法2:

使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强)

  1. 在SpringMvcConfig主配置类上实现WebMvcConfigurer接口,接口中全是默认方法

  2. 注入拦截器对象,重写addInterceptors方法

注:与方式一两者只能选一种,不然会有冲突,如果方式一起作用会导致第二种方式的拦截器不起使用。

即:如果项目中出现了一次 extends WebMvcConfigurationSupport ,其他的 extends WebMvcConfigurationSupport 和 implements WebMvcConfigurer 会失效 。

/*** SpringMVC配置类*/
@Configuration //1.标识当前是配置类 指定这个类为配置类,替代application.xml
@ComponentScan("com.zbbmeta")//2.配置扫描web层包 代替<context:component-scan base-package="com.zbbmeta" />
@EnableWebMvc //如果使用接口的方式,拦截器需要添加这个注解。不建议使用这种方式,两种方式只能配置一种,否则会有冲突
public class SpringMvcConfig  implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注解拦截器和拦截地址   表示添加 StudentInterceptor  取拦截路径是 /student/* 所有请求registry.addInterceptor(new StudentInterceptor()).addPathPatterns("/student/*");}
}

2.4 拦截器流程分析

3 拦截器参数

3.1 前置处理

//原始方法调用前执行的内容
//返回值类型可以拦截控制的执行,true放行,false终止
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("=================前置通知=================");return true;
}
  • 参数

    1. request:请求对象

    2. response:响应对象

    3. handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装

  • 返回值 返回值为false,被拦截的处理器将不执行。

3.2 后置处理

//原始方法调用后执行的内容
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("=================后置通知=================");
}
  • 参数 modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行跳转

注意:如果处理器方法出现异常了,该方法不会执行

3.3 完成后处理

//原始方法调用完成后执行的内容
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("=================最终通知=================");
}
  • 参数 ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理

注意:无论处理器方法内部是否出现异常,该方法都会执行。

**思考:postHandle()和afterCompletion()方法都是处理器方法执行之后执行,有什么区别?

4 拦截器链配置

4.1 多个拦截器配置

  • 定义第二个拦截器

package com.zbbmeta.Iinterceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class StudentInterceptor2 implements HandlerInterceptor {//原始方法调用前执行的内容//返回值类型可以拦截控制的执行,true放行,false终止@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("=================Student2前置通知=================");return true;}//原始方法调用后执行的内容@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("=================Student2后置通知=================");}//原始方法调用完成后执行的内容@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("=================Student2最终通知=================");}
}
  • 配置加载第二个拦截器

/*** SpringMVC配置类*/
@Configuration //1.标识当前是配置类 指定这个类为配置类,替代application.xml
@ComponentScan("com.zbbmeta")//2.配置扫描web层包 代替<context:component-scan base-package="com.zbbmeta" />
@EnableWebMvc //如果使用接口的方式,拦截器需要添加这个注解。不建议使用这种方式,两种方式只能配置一种,否则会有冲突
public class SpringMvcConfig  implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注解拦截器和拦截地址   表示添加 StudentInterceptor  取拦截路径是 /student/* 所有请求registry.addInterceptor(new StudentInterceptor()).addPathPatterns("/student/*");registry.addInterceptor(new StudentInterceptor2()).addPathPatterns("/student/*");}
}

提示:可以使用excludePathPatterns()方法排除某些地址不被拦截

  • 执行效果

4.2 多个连接器工作流程分析

  • 当配置多个拦截器时,形成拦截器链

  • 拦截器链的运行顺序参照拦截器添加顺序为准

  • 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行

  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

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

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

相关文章

C的进阶C++学习方向

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;软件配置等领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff01;送给自己和读者的…

L1-028 判断素数 测试点全过

题目 本题的目标很简单&#xff0c;就是判断一个给定的正整数是否素数。 输入格式 输入在第一行给出一个正整数N &#xff08; ≤ 10 &#xff09; &#xff08;≤ 10&#xff09; &#xff08;≤10&#xff09;&#xff0c;随后N行&#xff0c;每行给出一个小于 2 3 1 2^ 31…

Python开发环境(Visual Studio Code、Anaconda、PyInstaller、Enigma Virtual Box)

Python开发环境 [Anaconda、PyInstaller、Enigma Virtual Box] AnacondaAnaconda安装搭建Python环境Anaconda命令 Visual Studio CodeVisual Studio Code中Python设置Visual Studio Code中安装PyQt5Visual Studio Code中使用Qt DesignerVisual Studio Code中Anaconda切换虚拟环…

uniapp 自定义手机顶部状态栏(适配状态栏高度)

开启页面自定义导航栏功能 uniapp 在 pages.json 页面设置了全局的 globalStyle 的 "navigationStyle": "custom" 或单页面的 style 的 "navigationStyle": "custom" 之后页面顶部就没有自带的导航栏了&#xff0c;这时用户可自定义该…

介绍一些编程语言— Perl 语言

介绍一些编程语言— Perl 语言 Perl 语言 简介 Perl 是一种动态解释型的脚本语言。 最初的设计者为拉里・沃尔&#xff0c;它于 1987 1987 1987 年 12 12 12 月 18 18 18 日发表。Perl 借取了 C、sed、awk、shell scripting 以及很多其他编程语言的特性。其中最重要的特性…

仓库管理的重点在哪?仓库管理能有哪些软件?

对于做实体生意的中小商户来说&#xff0c;仓库管理工作是重中之重的&#xff0c;仓库管理的好坏&#xff0c;直接影响着门店销售和财务状况。 但对于很多中小商户来说&#xff0c;没有足够的人力和精力去高效地做好仓库管理工作&#xff0c;而借助仓库管理软件或进销存软件来…

SNAT和DNAT

SNAT和DNAT 一、SNAT策略及应用1.1SNAT策略概述1.2开启SNAT的命令1.2.1 临时打开1.2.2永久打开 1.3SNAT转换1&#xff1a;固定的公网IP地址1.4SNAT转换2&#xff1a;非固定的公网IP地址&#xff08;共享动态IP地址&#xff09;1.5SNAT案例1.5.1实验准备1.5.2配置网关服务器&…

Redis之zset(sorted set)类型解读

目录 基本介绍 常用命令 ZADD key score1 member1 [score2 member2] ZRANGE key start stop [WITHSCORES] ZCARD key ZCOUNT key min max ZREM key member [member ...] ZSCORE key member 基本介绍 Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字…

IDEA启动报错【java.sql.SQLSyntaxErrorException: ORA-00904: “P“.“PRJ_NO“: 标识符无效】

IDEA报错如下&#xff1a; 2023-08-17 11:26:15.535 ERROR [egrant-biz,b48324d82fe23753,b48324d82fe23753,true] 24108 --- [ XNIO-1 task-1] c.i.c.l.c.RestExceptionController : 服务器异常org.springframework.jdbc.BadSqlGrammarException: ### Error queryin…

PDF怎么转成PPT文件免费?一个软件解决

随着科技的不断发展和进步&#xff0c;电子文档已经成为我们日常工作和学习中不可或缺的一部分。PDF作为一种跨平台的文件格式&#xff0c;以其可靠性和易读性而备受推崇。然而&#xff0c;在某些情况下&#xff0c;我们可能需要PDF怎么转成PPT文件免费&#xff0c;以便更好地展…

Day 56

Day 56 583. 两个字符串的删除操作 dp[i][j]&#xff1a;以i-1为结尾的字符串word1&#xff0c;和以j-1位结尾的字符串word2&#xff0c;想要达到相等&#xff0c;所需要删除元素的最少次数。 当word1[i - 1] 与 word2[j - 1]相同的时候,dp[i][j] dp[i - 1][j - 1];当word1…

apache配置安全证书https踩坑记录

apache配置安全证书有如下几步 一、申请证书 这个网上有很多免费的&#xff0c;我用的是阿里云的服务器&#xff0c;在阿里云后台就可以申请免费证书。 二、上传证书 申请好证书后&#xff0c;根据服务器用的什么软件&#xff0c;是apache还是ngnix&#xff0c;下载相应的证书…

六大需求管理工具:满足您的需求管理需求

在项目开发和产品设计中&#xff0c;需求管理是确保项目成功的关键所在。通过使用专业的需求管理工具&#xff0c;团队可以更好地追踪、记录和分析需求&#xff0c;提高工作效率并确保项目按时完成。 市场上有许多需求管理工具可供选择&#xff0c;当下有什么好用的需求管理工…

FlashAttention算法详解

这篇文章的目的是详细的解释Flash Attention&#xff0c;为什么要解释FlashAttention呢&#xff1f;因为FlashAttention 是一种重新排序注意力计算的算法&#xff0c;它无需任何近似即可加速注意力计算并减少内存占用。所以作为目前LLM的模型加速它是一个非常好的解决方案&…

拒绝摆烂!C语言练习打卡第五天

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;每日一练 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、选择题 &#x1f4dd;1.第一题 &#x1f4dd;2.第二题 &#x1f4d…

Linux的基础指令

目录 1、ls指令 .和..意义 2、pwd指令 3、cd指令 ①cd ~ ②cd - 关于cd ..的用法 绝对路径和相对路径 4、touch指令 5、mkdir指令 tree指令 6、rmdir指令 7、rm指令 * 8、man指令 9、cp指令 nano&#xff1a; 10、mv指令 11、cat指令 12、more指令 13、less…

0009Java程序设计-jsp在线学习平台设计与实现

摘 要目 录系统实现开发环境 摘 要 在线学习平台&#xff0c;是一个利用因特网作为平台传送教学内容&#xff0c;实施网上教学&#xff0c;进行网上交流和学习的信息系统。构建在线学习系统平台&#xff0c;可以克服传统课堂教育的局限性&#xff0c;形成一种主动的、协作的、…

[线程/C++]线程同(异)步和原子变量

文章目录 1.线程的使用1.1 函数构造1.2 公共成员函数1.2.1 get_id()1.2.2 join()2.2.3 detach()2.2.5 joinable()2.2.6 operator 1.3 静态函数1.4 call_once 2. this_thread 命名空间2.1 get_id()2.2 sleep_for()2.3 sleep_until()2.4 yield() 3. 线程同步之互斥锁3.1 std:mute…

c#中lambda表达式缩写推演

Del<string> ml new Del<string>(Notify);//泛型委托的实例化&#xff0c;并关联Nofity方法 Del<string> ml new Del<string>(delegate (string str) { return str.Length; });//将Nofity变更为匿名函数 Del<string> ml delegate(string str)…

Ubuntu软件源、pip源大全,国内网站网址,阿里云、网易163、搜狐、华为、清华、北大、中科大、上交、山大、吉大、哈工大、兰大、北理、浙大

文章目录 一、企业镜像源1、阿里云2、网易1633、搜狐镜像4、华为 二&#xff1a;高校镜像源1、清华源2、北京大学3、中国科学技术大学源 &#xff08;USTC&#xff09;4、 上海交通大学5、山东大学6、 吉林大学开源镜像站7、 哈尔滨工业大学开源镜像站8、 西安交通大学软件镜像…