SpringMVC 拦截器详解

目录

一、介绍

二、过滤器与拦截器的简单对比

三、自定义拦截器

四、注册拦截器

五、案例演示-登录拦截器

5.1 自定义拦截器

5.2 注册拦截器


如果能帮到你将是我的荣幸❣️

 一、介绍

  • SpringMVC提供的拦截器类似于JavaWeb中的过滤器,只不过SpringMVC拦截器只拦截被前端控制器拦截的请求,即拦截控制器方法的执行,而过滤器拦截从前端发送的任意请求。

  • 熟练掌握SpringMVC拦截器对于我们开发非常有帮助,在没使用权限框架(shiro,spring security)之前,一般使用拦截器进行认证和授权操作。

  • SpringMVC拦截器有许多应用场景,比如:登录认证拦截器,字符过滤拦截器,日志操作拦截器等等。

二、过滤器与拦截器的简单对比

过滤器

  • 依赖于servlet容器
  • 在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。
  • 使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

拦截器

  • 依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架
  • 在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。
  • 由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。
  • 但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理

三、自定义拦截器

SpringMVC拦截器的实现一般有两种方式:

  • 自定义的Interceptor类要实现了Spring的HandlerInterceptor接口

  • 继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter。

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {}

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}
}

HandlerInterceptor接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。

  • preHandle(): 这个方法在Controller处理请求之前被调用,SpringMVC中的Interceptor是链式调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。

    该方法的返回值是布尔值Boolean 类型的:

    • 当它返回为false 时,表示请求结束,后续的Interceptor和Controller都不会再执行

    • 当返回值为true时就会继续调用下一个Interceptor的preHandle 方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法。

  • postHandle():这个方法在Controller方法处理当前请求之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。

    • postHandle方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor的postHandle方法反而会后执行。

  • afterCompletion():这个方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

拦截器流程图

单个拦截器执行流程图  

 多个拦截器执行流程图

我们可以配置多个拦截器,每个拦截器中都有三个方法。总结多个拦截器中的方法执行规律如下:

  • preHandle:Controller方法处理请求前执行,根据拦截器定义的顺序,正向执行

  • postHandle:Controller方法处理请求后执行,根据拦截器定义的顺序,逆向执行。需要所有的preHandle方法都返回true时才会调用。

  • afterCompletion:View视图渲染后处理方法:根据拦截器定义的顺序,逆向执行。preHandle返回true就会调用。

四、注册拦截器

自定义拦截器规则编写完成后,还不行,还需要写配置文件,或者配置类。

目的是让我们的拦截器知道,哪些控制器方法的访问需要执行拦截器,哪些不需要执行。

如今主流的都是springboot框架,我们就不需要写配置文件了,直接编写一个配置类搞定。

  • 配置类需要实现WebMvcConfigurer接口,或者继承它的实现类WebMvcConfigurerAdapter

  • 然后重写里面的addInterceptors添加拦截器方法,具体需要添加哪个拦截器,拦截哪些路径,不拦截哪些路径,都在这里配置。

五、案例演示-登录拦截器

接下来编写一个登录拦截器,这个拦截器可以实现认证操作。就是当我们还没有登录的时候,如果发送请求访问我们系统资源时,拦截器不放行,请求失败。只有登录成功后,拦截器放行,请求成功。登录拦截器只要在preHandle()方法中编写认证逻辑即可,因为是在请求执行前拦截。代码实现如下:

5.1 自定义拦截器

/**
 *  登录拦截器
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object user = request.getSession().getAttribute("user");
        if (user == null){
            log.info("当前无用户登录,拦截此次请求");
            response.setHeader("content-type","text/html;charset=UTF-8");//指定编码,防止乱码
            response.getWriter().write(JSON.toJSONString(Result.fail(50004,"当前无用户登录,无法访问")));
            return false;
        }else {
            log.info("当前{} 号用户已登录,放行",user);
            return true;
        }
    }
}

5.2 注册拦截器

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
            	.addPathPatterns("/**") // 对所有的路径都进行拦截
                .excludePathPatterns("/common/login");
    }
}

说明:

.addPathPatterns("/**")   对所有的路径都进行拦截
.excludePathPatterns("/common/login","/swagger-ui.html/*");  对这两条路径进行了放行,前提是这两个路径要存在对应的控制器方法。否则一旦被添加到addPathPatterns中的路径拦截到了,即使excludePathPatterns方法放行了,也无法放行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++网络编程 TCP套接字基础知识,利用TCP套接字实现客户端-服务端通信

1. TCP 套接字编程流程 1.1 概念 流式套接字编程针对TCP协议通信,即是面向对象的通信,分为服务端和客户端两部分。 1.2 服务端编程流程: 1)加载套接字库(使用函数WSAStartup()),创建套接字&…

MySQL Windows版本下载及安装时默认路径的修改

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、MySQL 下载二、默认路径修改1、安装前准备【非常重要】2、启动安装程序总结1、MySQL下载2、MySQL默认路径修改前言 MySQL 被Oracle收购后,各种操作规范及约束也相应的跟着来了,这不,只…

【前端实习评审】对小说详情模块更新的后端接口压力流程进行了人群优化

大家好,本篇文章分享一下【校招VIP】免费商业项目“推推”第一期书籍详情模块 前端同学的开发文档周最佳作品。该同学来自安徽科技学院土木工程专业。本项目亮点难点: 1.热门书籍在更新点的访问压力; 2.书籍更新通知的及时性和有效性&#xf…

重学C++系列之友元

一、什么是友元 在C中,为了提高程序的效率,在一些场景下,引入友元,但同时类的封装性就会被破坏。 二、怎么实现友元 友元关键字(friend) // 在类中声明另一个类的成员函数来做为友元函数 // 以关键字&…

Centos部署Springboot项目详解

准备启动jar包,app.jar放入指定目录。 一、命令启动 1、启动命令 java -jar app.jar 2、后台运行 nohup java -jar app.jar >/dev/null 2>&1 & 加入配置参数命令 nohup java -Xms512M -Xmx512M -jar app.jar --server.port9080 spring.profiles…

基于鲸鱼优化算法的5G信道估计(Matlab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑…

Unity 工具之 NuGetForUnity 包管理器,方便在 Unity 中的进行包管理的简单使用

Unity 工具之 NuGetForUnity 包管理器,方便在 Unity 中的进行包管理的简单使用 目录 Unity 工具之 NuGetForUnity 包管理器,方便在 Unity 中的进行包管理的简单使用 一、简单介绍 二、NuGetForUnity 的下载导入 Unity 三、NuGetForUnity 在 Unity 的…

Jetbrains idea 代码关闭 注释自动渲染 导致换行不生效

方法1 关闭注释自动渲染 取消勾选 方法2 结尾使用 <br> 强制换行

vector使用

文章目录 vector的介绍vector的使用vector的初始化vector iterator迭代器的使用vector 空间增长问题vector的增删改查 迭代器失效总结 vector的介绍 文档介绍 vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着…

【雕爷学编程】MicroPython动手做(02)——尝试搭建K210开发板的IDE环境3

4、下载MaixPy IDE&#xff0c;MaixPy 使用Micropython 脚本语法&#xff0c;所以不像 C语言 一样需要编译&#xff0c;要使用MaixPy IDE , 开发板固件必须是V0.3.1 版本以上&#xff08;这里使用V0.5.0&#xff09;, 否则MaixPy IDE上会连接不上&#xff0c; 使用前尽量检查固…

宝塔设置云服务器mysql端口转发,实现本地电脑访问云mysql

环境&#xff1a;centos系统使用宝塔面板 实现功能&#xff1a;宝塔设置云服务器mysql端口转发&#xff0c;实现本地电脑访问mysql 1.安装mysql、PHP-7.4.33、phpMyAdmin 5.0 软件商店》搜索 mysql安装即可 软件商店》搜索 PHP安装7.4.33即可&#xff08;只需要勾选快速安装&…

iOS开发-实现快速登录弹窗与微信微博QQ三方登录切换控件

iOS开发-实现快速登录弹窗与微信微博QQ三方登录切换控件。 之前开发中实现快速登录弹窗与微信微博等了切换控件。 一、效果图 二、实现代码 实现背景渐变UIBlurEffect self.blurEffect [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; self.effectView [[UIVisu…

linux上适用的反汇编调试软件(对标od)

ubuntu下类似于od软件 经过搜索&#xff0c;在Ubuntu上选用edb-debugger进行动态调试&#xff0c; 下载链接: https://github.com/eteran/edb-debugger 但是依赖反汇编引擎: https://github.com/capstone-engine/capstone 安装 先安装capstone 先下载release的版本&#xf…

基于量子同态加密的安全多方凸包协议

摘要安全多方计算几何(SMCG)是安全多方计算的一个分支。该协议是为SMCG中安全的多方凸包计算而设计的。首先&#xff0c;提出了一种基于量子同态加密的安全双方值比较协议。由于量子同态加密的性质&#xff0c;该协议可以很好地保护量子电路执行过程中数据的安全性和各方之间的…

组合模式-树形结构的处理

A公司需要筛选出年龄35岁及以上(如果是领导&#xff0c;年龄为45岁及以上)的人。其组织架构图如下。 图 A公司部分组织架构图 图 传统解决方案 public class Development {private String name;public Development(String name) {this.name name;}List<Employee> emplo…

需求分析案例:消息配置中心

本文介绍了一个很常见的消息推送需求&#xff0c;在系统需要短信、微信、邮件之类的消息推送时&#xff0c;边界如何划分和如何设计技术方案。 1、需求 一个系统&#xff0c;一般会区分多个业务模块&#xff0c;并拆分成不同的业务系统&#xff0c;例如一个商城的架构如下&am…

flutter(01) windows桌面版 编译环境安装指南

1 flutter环境安装 flutter官网参考&#xff1a;Install | Flutter 先下载flutter SDK>&#xff1a;flutter sdk下载--官网&#xff0c;之后解压到C:\Users\XXX\data&#xff08;这里以该路径为例&#xff0c;但可以为其他自定义路径&#xff09;目录下&#xff0c;在这里…

栈和队列模拟实现(C++)

文章目录 0.码云完整代码1.deque的认识1.1介绍1.2图析1.3性能比较 2.stack的学习2.1模拟实现2.2测试函数 3.queue的学习3.1模拟实现3.2测试函数 4.优先级队列的学习4.0仿函数的引入4.1介绍4.2例题4.3模拟实现 5.测试函数 0.码云完整代码 点击 栈 队列 优先级队列 跳转码云获取…

鸿鹄协助管理华为云与炎凰Ichiban

炎凰对华为云的需求 在炎凰日常的开发中&#xff0c;对于服务器上的需求&#xff0c;我们基本都是采用云服务。目前我们主要选择的是华为云&#xff0c;华为云的云主机比较稳定&#xff0c;提供的云主机配置也比较多样&#xff0c;非常适合对于不同场景硬件配置的需求&#xff…

石子合并(区间dp模板)

题目描述&#xff1a; dp分析&#xff1a; 解题代码&#xff1a; #include<iostream> using namespace std;const int N1e36;int f[N][N]; int a[N]; int s[N];int main(){int n;cin>>n;for(int i1;i<n;i){scanf("%d",&s[i]);s[i]s[i-1];//前缀和…