SpringMVC(五)【拦截器】

前言

        今天来把 SpringMVC 最后一部分学完,虽然课时很短,但是学起来还是很慢的,不过确收获很大。不得不感慨学大数据确实有必要把 SSM、SpringBoot 等各种 JavaEE 技术好好学一学,收获很大,尽管我们到现在 Java 代码写了应该20 W 行差不多,但是关于框架的代码我写的还是比较少的,主要是通过算法和 JavaFX 来练习 Java 基础语法。

1、拦截器

1.1、概念

  •  拦截器是一种动态拦截方法调用的机制,在 SpringMVC 中动态拦截控制器方法的执行
  • 作用
    • 在指定方法调用前后执行预先设定的代码
    • 阻止原始方法的执行(权限判断)

拦截器和过滤器的区别

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

1.2、入门案例

1.2.1、拦截器功能类

        在 controller 包下新建一个包 interceptor ,毕竟拦截器是 SpringMVC 的内容,创建自定义拦截器类(记得添加注解 @Component 让 SpringMVC 来对它进行管理)只需要实现 HandlerInterceptor 接口:

@Component
public class ProjectInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {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("afterCompletion");}
}

        这里需要注意的是 preHandle 方法的返回值,如果返回值为 false 代表直接截断请求,所以后面的控制器方法不会被执行,后面的 postHandle 和 afterCompletion 方法也不会执行。

        如果返回 true 则代表不拦截,所以它会执行控制器方法以及 postHandle 和 afterCompletion 方法

         在之前的 SpringMvcSupport 类中添加拦截器,需要配置两个参数:拦截器对象(因为拦截器已经被 SpringMVC 所管理了,所以我们直接通过自动装配获得),拦截哪个请求。

访问 localhost:81/books:

上面我们配置的拦截器只能拦截 /books 这一个请求,如果我们想要拦截 /books/2 后者 /books/100 呢,只需要添加一个参数 "/books/*" 即可:

    @Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}

1.2.2、简化开发

        现在我们的 SpringMvcConfig 是空的,只是带有一堆注解,我们可以把 SpringMvcSupport 和 SpringMvcConfig 进行合并,其实就是让 SpringMvcConfig 实现 WebMvcConfigurer 接口(和 SpringMvcSupport 很像,后者实现的是 WebMvcConfigurationSupport 接口):

@Configuration
@ComponentScan("com.lyh.controller")
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");registry.addResourceHandler("/css/**").addResourceLocations("/css/");registry.addResourceHandler("/js/**").addResourceLocations("/js/");registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");}}

        因为我们已经把 SpringMvcSupport 和 SpringMvcConfig 合并了,所以现在我们就不需要让 SpringMvcConfig 扫描 "com.lyh.config" 包了 。

有无拦截器的区别

可以看到,单个拦截器的时候,如果在 preHandle 方法返回 false,将直接终止执行(afterCompletion 方法也不会执行,但是这种情况在多个拦截器的情况下有所不同)。 

1.3、拦截器参数

        我们说拦截器可以帮我们做一些判断,来决定是否允许这个请求进一步进入 controller 方法,那它必然有一些上下文参数

1.3.1、preHandle 方法

  1. HttpServletRequest request
  2. HttpServletResponse response,
  3. Object handler

        对于 request 和 response 这两个对象,我们很容易想到可以拿它们来干什么,比如 request.getHeader("Content-type") 来获得请求头中的 Content-type 属性值。

        而这里的 handler 其实是 HandlerMethod 类,它对反射技术中的 Method 对象进行了封装。我们可以通过它来获得原始执行的方法,具体可以干什么以后用到再学。

1.3.2、postHandle 方法

        postHandle 方法没有 handler 对象,但是它有一个 ModelAndView 对象,如果我们页面跳转的话,可以通过它来设置一些属性,但是我们到目前为止都是返回 json 并不返回页面,所以这里不做学习。

1.3.3、afterCompletion 方法

        afterCompletion 方法同样除了 request 和 response 对象之外,它有一个 Exception 类型的对象,也就是说如果我们的表现层抛出异常的话,我们可以在这里拿到它,但是我们上一篇已经用了 SpringMVC 统一的异常处理器,所以这里也没啥用。

        总之,这三个方法实用性最强的就是 preHandle 方法,它可以决定是否放行请求的下一步执行。

1.4、拦截器链配置

  • 当配置多个拦截器时,形成拦截器链
  • 拦截器的拦截顺序取决于我们 addIterceptors 方法中注册拦截器的顺序

1.4.2、创建拦截器类

我们在 interceptor 包下再创建一个拦截器类:

@Component
public class ProjectInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle2");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle2");;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion2");}
}

配置拦截器: 

访问 localhost:85/books

可以看到,拦截器的拦截顺序取决于我们 addIterceptors 方法中注册拦截器的顺序: pre1 -> pre2 -> controller  -> post2 -> post1 -> after2  -> after1。

注意:多个的拦截器情况下,比如下图:

  • 如果 pre3 返回 flase(pre1 和 pre2都返回 true),那么程序并不是直接终止,而是依然会执行 after2 和 after1;
  • 如果 pre2 返回 flase(pre1返回 true),那么程序并不是直接终止,而是依然会执行 after1;
  • 如果 pre1 返回 flase,那么程序直接终止。

 总结

        至此,SpringMVC 的学习结束,SSM 现在已经是一个程序员必知必会的东西了,可以说是一个应届生校招的基本技能,而不是亮点。接下来再学学 SpringBoot ,这是我们大数据开发中正儿八经会用到的东西,完了做个项目巩固巩固。

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

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

相关文章

Redis几种常见的应用方式

1.登录认证 redis最常见的应用就是,登录认证把。再首次登录返回给前端token,把用户名和登录状态缓存到redis一段时间,每次其他请求进来过滤器那这token解析出来的用户名或其他关键的key值,再redis里面查询缓存,有则直…

【算法】二分查找

快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、二分查找二、查找元素的第一个和最后一个位置三、x的平方根四、搜索插入位置五、山脉数组的峰顶索引…

【Leetcode每日一题】 分治 - 排序数组(难度⭐⭐)(60)

1. 题目解析 题目链接:912. 排序数组 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 算法思路: 快速排序作为一种经典的排序算法,其核心思想在于通过“分而治之”的策略&#xff…

eCongnition 根据栅格类别图分类分割结果

目录 1、导入标签文件 2、根据栅格类别计算对象类别 3、导出栅格计算的类别 1、导入标签文件 导入栅格类别文件Label.tif 参考:eCongnition 对图像进行多尺度分割-CSDN博客 2、根据栅格类别计算对象类别 对类别栅格创建 mode[Maximum] 特征,该特征…

SQL Serve---嵌套查询

定义 嵌套查询:主要用于复杂的查询中。在SQL语言中,一个Select From Where语句称为一个查询块,将一个查询块嵌套在另一个查询的Where子句或Having短语中的查询称为嵌套查询。 子查询的类型 使用别名的子查询 使用IN和NOT IN的子查询 使用比较…

Java基础之循环控制语句、函数、数组

Java基础 1.循环控制语句: break、continue public static void main(String[] args) {/*TODO 循环控制语句 - break需要和 for 以及 while 循环搭配使用 当在循环中执行了 break语句 那么就可以退出当前循环*/int sum 0;for (int i 1; i < 1000; i) {sum i;if (i >…

基于SSM的列车订票管理系统(含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的列车订票管理系统3拥有两种角色&#xff1b;管理员、用户 管理员&#xff1a;用户管理、车票管理、购票指南管理、系统管理等 用户&#xff1a;发布帖子、登录注册、购票等 1.…

数据结构速成--串

由于是速成专题&#xff0c;因此内容不会十分全面&#xff0c;只会涵盖考试重点&#xff0c;各学校课程要求不同 &#xff0c;大家可以按照考纲复习&#xff0c;不全面的内容&#xff0c;可以看一下小编主页数据结构初阶的内容&#xff0c;找到对应专题详细学习一下。 目录 …

【Linux冯诺依曼体系结构】

目录 1.冯诺依曼体系结构原理 1.冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 输入单元&#…

最新SpringBoot项目财务管理系统

采用技术 最新SpringBoot项目财务管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统登录页面 管理员功能 管理员功能页面 员工管理页面 部…

SpringBoot多数据源(五)

SpringBoot多数据源-集成多个mybatis框架 1.基本框架2.使用2.1项目结构2.2 依赖导入2.3 application.yml配置2.4 创建读与写的SqlSessionFactoryBean 3.总结 1.基本框架 通过启动多个SqlSessionFactoryBean&#xff0c;每个SqlSessionFactoryBean对应一个datasource和指定位置的…

STM32G431RBT6移植FreeRTOS

引言&#xff1a; 本文专门为参加了蓝桥杯嵌入式赛道的同学准备&#xff0c; 大家可能会有这样一个问题&#xff0c; 比完赛之后&#xff0c; 对于像继续使用STM32G431RBT6学习FreeRTOS的&#xff0c; 发现网上的教程使用的板子基本上都是F1和F4的&#xff0c; 其实呢&#xff…

二叉树的最大深度 - LeetCode 热题 37

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 37 天 二叉树第 2 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最…

JAVA面向对象(下 )(一、继承和方法重写)

一、继承 1.1 什么是继承 生活中继承是指&#xff1a; 继承财产>延续财产 继承/遗传 父母的长相&#xff0c;基因 > 延续上一代的基因 继承技能、专业、职位 >延续 继承中华民族的传统文化 > 延续 青出于蓝而胜于蓝 或 长江后浪推前浪&#xff0c;前浪被拍在…

IP xfrm 命令说明2-sp

命令内容: ip xfrm policy {delete | get } {SELECTOR | index INDEX } dir DIR [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ptype PTYPE ]ip xfrm policy {deleteall | list } [ SELECTOR ] [ dir DIR ] [ index INDEX ] [ ptype PTYPE ] [

最高人民法院关于技术调查官参与知识产权案件诉讼活动的若干规定

最高人民法院关于技术调查官参与知识产权案件诉讼活动的若干规定 &#xff08;2019年1月28日最高人民法院审判委员会第1760次会议通过&#xff0c;自2019年5月1日起施行&#xff09; 法释〔2019〕2号 为规范技术调查官参与知识产权案件诉讼活动&#xff0c;根据《中华人民…

【图像分割】光流生成标签(matlab)

文章目录 1. 框架2. opticalFlow_label3. 光流 1. 框架 2. opticalFlow_label close all; clear; clc; % 使用光流进行标签的生成 %% 视频帧的读取 npy_data readNPY(train.npy);%% 提取标签的坐标 first_label squeeze(npy_data(2,1,:,:)); h fspecial("gaussian&quo…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中&#xff0c;WITH 子句提供了一种编写辅助语句的方法&#xff0c;以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单&#xff0c;便于阅读。这些语句通常称为通用表表达式&#xff08;Common Table Express…

普通局部变量和静态局部变量区别

存储位置 普通局部变量存储在栈上静态局部变量存储在静态存储区 生命周期 当函数执行完毕时, 普通局部变量会被销毁静态局部变量的生命周期则是整个程序运行期间, 即使函数调用结束, 静态局部变量的值也会被保留 初始化 普通局部变量在每次函数调用时都会被初始化, 他们的…

快速了解开发过程中VO、DTO、BO、 DO、PO、POJO、Entity的概念、区别、作用

​ 目录 ​前言 VO&#xff08;Value Object&#xff0c;值对象&#xff09; DTO&#xff08;Data Transfer Object&#xff0c;数据传输对象&#xff09; BO&#xff08;Business Object&#xff0c;业务对象&#xff09; DO&#xff08;Data Object&#xff0c;数据对象…