SpringMvc中拦截器的配置及应用

拦截器原理

在 Spring MVC 中,拦截器(Interceptor)是一种机制,用于拦截请求并在处理程序(Controller)执行之前或之后执行一些操作。拦截器允许您在请求的不同阶段(如处理程序执行前、处理程序执行后、视图渲染前、视图渲染后等)添加自定义逻辑。

其中问号就是拦截器处理的范围。

实现自定义拦截器

@Component
public class SampleInterceptor implements HandlerInterceptor {// 在controller执行前的逻辑@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 在controller执行之前执行的逻辑System.out.println("Pre-handle logic");return true; // 返回 true,将允许请求继续传递到处理程序;//返回 false,将阻止请求传递给处理程序}// 在controller执行后、并在视图渲染前执行的逻辑@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {System.out.println("Post-handle logic");}//在服务器响应结束后执行的逻辑@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {System.out.println("After-completion logic");}
}

将自定义拦截器添加到SpringMvc中

@Configuration
public class InterceptorRoll implements WebMvcConfigurer {@AutowiredLoginTicketInterceptor loginTicketInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//registry.addInterceptor() 方法可以向注册表中添加拦截器。InterceptorRegistration interceptorRegistration = registry.addInterceptor(loginTicketInterceptor);//添加拦截器生效路径,以及拦截器忽略的路径...}
}

使用拦截器实现权限验证逻辑

关键鉴权逻辑图解:

1.在请求controller之前先经过拦截器,从cookie中获取用户标识,根据用户标识,从redis中取出登录凭证

2.如果登录凭证有效,则设置一个线程与用户信息进行绑定,并将用户信息存入到视图模型中

3.如果凭证无效则跳转到登录页面

4.在用户请求完之后,销毁线程与用户名的绑定

实现:

1.创建工具类ThreadHolder

package com.duhong.util;import com.duhong.entity.User;
import org.springframework.data.redis.core.StringRedisTemplate;public class ThreadHolder {static ThreadLocal<User> users=new ThreadLocal<>();/*** 设置线程信息* @param user*/public static void setHolder(User user){users.set(user);}/*** 获取当前线程的信息* @return*/public static User getHolder(){return users.get();}/*** 解除线程与当前用户的绑定*/public static void remove(){users.remove();}
}

2.创建自定义拦截器

@Component
public class LoginTicketInterceptor implements HandlerInterceptor {@AutowiredStringRedisTemplate redisTemplate;//redis客户端@AutowiredUserMapper userMapper;//根据用户id查询用户所有信息public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//获取用户的cookieCookie[] cookies = request.getCookies();String loginOwner=null;System.out.println("开始鉴权");for(Cookie cookie:cookies){if(cookie.getName().equals("loginOwner")){loginOwner=cookie.getValue();break;};}LoginTicket ticket=new LoginTicket();//如果loginOwner不等于null,从redis中获取登录签证if(loginOwner!=null) {String s = redisTemplate.opsForValue().get(RedisUtil.getTicket(loginOwner));ticket = RedisUtil.getObject(s);//用户已被授权if (ticket != null && ticket.getStatus() == 1) {User user = userMapper.selectById(ticket.getUserId());//将用户信息与当前线程绑定ThreadHolder.setHolder(user);return true;}}//如果签证不等于null,而且签证的状态无效则跳转到登录页面response.sendRedirect("/site/login");return false;}/*** 在视图层渲染之前将用户信息存入模型* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {if(ThreadHolder.getHolder()!=null&&modelAndView!=null){//从当前线程中获取用用户信息modelAndView.addObject("loginUser",ThreadHolder.getHolder());}}/*** 在服务器响应完本次信息之后,解除当前线程与用户信息的绑定* @param request* @param response* @param handler* @param ex* @throws Exception*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {ThreadHolder.remove();}
}

3.将拦截器加入到SpringMvc中并设置拦截规则

package com.duhong.config;import com.duhong.filter.LoginTicketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.Arrays;
import java.util.List;@Configuration
public class InterceptorRoll implements WebMvcConfigurer {@AutowiredLoginTicketInterceptor loginTicketInterceptor;//配置文件中配置配置需要过滤的路径形式为:路径,路径,...@Value("${allow.pages}")String allowPages;@Overridepublic void addInterceptors(InterceptorRegistry registry) {InterceptorRegistration interceptorRegistration = registry.addInterceptor(loginTicketInterceptor);interceptorRegistration.addPathPatterns("/**");String[] split = allowPages.split(",");for (String allowpage : split) {System.out.println(allowpage);//忽略指定页面interceptorRegistration.excludePathPatterns(allowpage);}//忽略静态资源interceptorRegistration.excludePathPatterns("/css/**","/img/**","/js/**");}
}

如有收获,就点个赞吧!

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

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

相关文章

AI大模型中的Bert

1.全方位上下文理解&#xff1a;与以前的模型&#xff08;例如GPT&#xff09;相比&#xff0c;BERT能够双向理解上下文&#xff0c;即同时考虑一个词 的左边和右边的上下文。这种全方位的上下文理解使得BERT能够更好地理解语言&#xff0c;特别是在理解词义、 消歧等复杂任务上…

智慧安防GB28181视频监控EasyCVR v3.5系统增加录像保存地址的配置

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入。在网络传输上&#xff0c;平台支持设备通过4G、5G、WIFI、有线等方式进行视频流的快捷传输&#xff0c;视频流经平台处理后可对外进行多格式的分发&#xff0c;实现多展示终端观看&am…

消息中间件之Kafka(二)

1.Kafka线上常见问题 1.1 为什么要对topic下数据进行分区存储? 1.commit log文件会受到所在机器的文件系统大小的限制&#xff0c;分区之后可以将不同的分区放在不同的机器上&#xff0c; 相当于对数据做了分布式存储&#xff0c;理论上一个topic可以处理任意数量的数据2.提…

TCP高并发服务器简介(select、poll、epoll实现与区别)

select、poll、epoll三者的实现&#xff1a; select实现TCP高并发服务器的流程&#xff1a; 一、创建套接字&#xff08;socket函数&#xff09;&#xff1a;二、填充服务器的网络信息结构体&#xff1a;三、套接字和服务器的网络信息结构体进行绑定&#xff08;bind函数&…

大模型笔记【3】 gem5 运行模型框架LLama

一 LLama.cpp LLama.cpp 支持x86&#xff0c;arm&#xff0c;gpu的编译。 1. github 下载llama.cpp https://github.com/ggerganov/llama.cpp.git 2. gem5支持arm架构比较好&#xff0c;所以我们使用编译LLama.cpp。 以下是我对Makefile的修改 开始编译&#xff1a; make UNAME…

Kotlin协程的JVM实现源码分析(下)

协程 根据 是否保存切换 调用栈 &#xff0c;分为&#xff1a; 有栈协程&#xff08;stackful coroutine&#xff09;无栈协程&#xff08;stackless coroutine&#xff09; 在代码上的区别是&#xff1a;是否可在普通函数里调用&#xff0c;并暂停其执行。 Kotlin协程&…

【git分支管理策略】

文章目录 前言一、分支管理策略简介二、git基本操作三、git分支远程分支本地分支 四、gitflow分支管理策略分支定义gitflow分支管理策略评价 五、GITHUB FLOW分支管理策略分支使用流程创建分支&#xff08;Create a branch&#xff09;新增提交(add and commit)提出 Pull 请求&…

C++泛型编程-类模板的项目实战实现基础的Vector的编写

请设计一个数组模板类&#xff08; Vector &#xff09;&#xff0c;完成对 int 、 char 、 float 、 double 以 及任意的自定义类等类型元素进行管理。 需求 a. 实现构造函数 b. 实现拷贝构造函数 c. 实现 cout << 操作 d. 实现下标访问符 [] 的重载操作 …

CTF-PWN-堆-【chunk extend/overlapping-1】

文章目录 chunk extend/overlappingfastbin与topchunk相邻free时候不会合并unsortedbinchunk中与topchunk相邻的被free时会合并extend向后overlapping先修改header&#xff0c;再free&#xff0c;再malloc先free&#xff0c;再修改header&#xff0c;再malloc extend向前overla…

Filter简单了解

1、filter能干嘛 过滤器实际上就是对web资源进行拦截&#xff0c;做一些处理后交给下一个过滤器或者servlet处理&#xff0c;通常都是拦截request的&#xff0c;也可以对response进行拦截处理&#xff1b; 2、面试考点&#xff1a;filter能干嘛&#xff08;应用场景&#xff0…

多维时序 | Matlab实现CNN-GRU-Mutilhead-Attention卷积门控循环单元融合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现CNN-GRU-Mutilhead-Attention卷积门控循环单元融合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现CNN-GRU-Mutilhead-Attention卷积门控循环单元融合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍…

退出微软账号,edge/必应退出账号

微软账号退出&#xff1a;搜的教程都是说改成本地帐号&#xff0c;但是我的已经是本地帐号&#xff0c;操作没用。 但是找到了退出edge/必应浏览器账号的方法&#xff0c;见下图。 参考链接&#xff1a;奶酪真好次个人动态-奶酪真好次动态记录-哔哩哔哩视频 (bilibili.com)

【Linux】基本指令收尾

文章目录 日期查找打包压缩系统信息Linux和Windows互传文件 日期 这篇是基本指令的收尾了&#xff0c;还有几个基本指令我们需要说一下 首先是Date&#xff0c;它是用来显示时间和日期 直接输入date的话显示是有点不好看的&#xff0c;所以我们可以根据自己的喜欢加上分隔符&…

使用 Vector 在 Kubernetes 中收集日志

多年来&#xff0c;我们一直在使用 Vector 在我们的 Kubernetes 平台中收集日志&#xff0c;并成功地将其应用于生产中以满足各种客户的需求&#xff0c;并且非常享受这种体验。因此&#xff0c;我想与更大的社区分享它&#xff0c;以便更多的 K8s 运营商可以看到潜力并考虑他们…

【 CSS 】基础1

“坚持就是胜利。” - 温斯顿丘吉尔 【 CSS 】基础 1 CSS 简介 CSS 是层叠样式表 ( Cascading Style Sheets ) 的简称.有时我们也会称之为 CSS 样式表或级联样式表。CSS 也是一种标记语言CSS 主要用于设置 HTML 页面中的文本内容&#xff08;字体、大小、对齐方式等&#xff…

Python使用gRPC入门,定义proto文件和收发消息

gRPC 一开始由 google 开发&#xff0c;是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。 本文通过一个简单的 Hello World 例子来向您介绍 gRPC 。 Grpc官方文档地址&#xff1a;Quick start | Python | gRPC gRPC 是什么&#xff1f; gRPC 也是基于以下理念&#…

Python武器库开发-武器库篇之Quake360-API使用(四十七)

Python武器库开发-武器库篇之Quake360-API使用(四十七) Quake360是一款网络资产搜索引擎&#xff0c;旨在帮助用户快速定位和识别网络上的资产信息。它具有强大的搜索功能&#xff0c;可以搜索并展示各种类型的网络资产&#xff0c;包括域名、IP地址、子域名、端口信息等。同时…

Unity编程#region..#endregion以及面板提示语标签[Tooltip(““)]

C#中的#region..#endregion 在Unity中&#xff0c;#region和#endregion是用于代码折叠的预处理指令。它们并不是Unity特有的&#xff0c;而是C#语言本身提供的功能。 #region用于标记一段代码的开始&#xff0c;而#endregion用于标记一段代码的结束。在编辑器中&#xff0c;可…

橡木桶陈酿:木材选择、烤制程度与陈酿时间

在威士忌的酿造过程中&#xff0c;橡木桶陈酿是一个至关重要的环节。橡木桶不仅为威士忌提供了特别的香气和风味&#xff0c;还赋予其丰富的颜色和味蕾。本文将深入探讨橡木桶陈酿的奥秘&#xff0c;特别是木材选择、烤制程度以及陈酿时间对威士忌风味的影响&#xff0c;以雷盛…

【Linux】解决普通用户无法进行sudo提权

当某个普通用户进行sudo指令提权的时候&#xff0c;可能存在无法操作的问题&#xff0c;如下图&#xff1a; 这个图中有一个细节&#xff0c;我们使用sudo进行提权的时候&#xff0c;用的可是zhangsan的密码&#xff0c;因此有人可能会有疑问&#xff0c;这不是有问题吗&#x…