SpringMvc中拦截器的配置及应用

news2024/10/2 12:25:39

拦截器原理

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

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

实现自定义拦截器

@Component
public class SampleInterceptor implements HandlerInterceptor {
    // 在controller执行前的逻辑
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 在controller执行之前执行的逻辑
        System.out.println("Pre-handle logic");
        return true; // 返回 true,将允许请求继续传递到处理程序;
        //返回 false,将阻止请求传递给处理程序
    }
    // 在controller执行后、并在视图渲染前执行的逻辑
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
       
        System.out.println("Post-handle logic");
    }
    //在服务器响应结束后执行的逻辑
    @Override
    public 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 {
    @Autowired
    LoginTicketInterceptor loginTicketInterceptor;
  
    @Override
    public 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 {
    @Autowired
    StringRedisTemplate redisTemplate;//redis客户端
    @Autowired
    UserMapper userMapper;//根据用户id查询用户所有信息

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取用户的cookie
        Cookie[] 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 {
    @Autowired
    LoginTicketInterceptor loginTicketInterceptor;
    //配置文件中配置配置需要过滤的路径形式为:路径,路径,...
    @Value("${allow.pages}")
    String allowPages;

    @Override
    public 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.coloradmin.cn/o/1402272.html

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

相关文章

【C++干货基地】namespace超越C语言的独特魅力(文末送书)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

学习笔记之——3D Gaussian SLAM,SplaTAM配置(Linux)与源码解读

SplaTAM全称是《SplaTAM: Splat, Track & Map 3D Gaussians for Dense RGB-D SLAM》&#xff0c;是第一个&#xff08;也是目前唯一一个&#xff09;开源的用3D Gaussian Splatting&#xff08;3DGS&#xff09;来做SLAM的工作。 在下面博客中&#xff0c;已经对3DGS进行了…

[计算机提升] Bitlocker驱动器加密与关闭

4.12 Bitlocker驱动器加密与关闭 BitLocker驱动器加密是一种安全功能&#xff0c;主要用于保护计算机中的数据免受未经授权的访问和泄漏。它通过加密Windows操作系统卷上存储的所有数据提供保护。 BitLocker的使用可确保计算机即使在无人参与、丢失或被盗的情况下也不会被篡改…

Cesium叠加超图二维服务、三维场景模型

前言 Cesium作为开源的库要加超图的服务则需要适配层去桥接超图与Cesium的数据格式。这个工作iClient系列已经做好&#xff0c;相比用过超图二维的道友们可以理解&#xff1a;要用Openlayer加载超图二维&#xff0c;那就用iClient for Openlayer库去加载&#xff1b;同样的要用…

如何用GPT进行绘图?

详情点击链接&#xff1a;如何用GPT进行绘图&#xff1f; 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#xff0c;AI画图&#xff0c;图像识别&#xff0c;文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Claude2二定制自己的GP…

【python题解11】 输入两个非负十进制整数A和B以及D(进制数),输出A+B的D(1< D ≤ 10)进制数。

1. 题目&#xff1a;输入两个非负十进制整数A和B以及D&#xff08;进制数&#xff09;&#xff0c;输出AB的D&#xff08;1< D ≤ 10&#xff09;进制数。 输入格式: 在一行中依次给出三个整数A、B和D&#xff08;进制数&#xff09;。 输出格式: AB的D进制数。 2. 主要考…

如何使用 Helm 在 K8s 上集成 Prometheus 和 Grafana|Part 3

在本教程的前两部分&#xff0c;我们分别了解和学习了Prometheus 和 Grafana 的基本概念和使用的前提条件&#xff0c;以及使用 Helm 在 Kubernetes 上安装 Prometheus。 在今天的教程中&#xff0c;我们将为你介绍以下内容&#xff1a; 安装 Grafana&#xff1b;集成 Promethe…

开源网安推出“国产替代续航惠企计划”,实现“两不三保”目标

​随着全球安全威胁态势越发严峻&#xff0c;国内网络安全监管趋严&#xff0c;Adobe、Tableau、Salesforce、Nutanix、Citrix、checkmarx等外企陆续裁员离华&#xff0c;国产替代从战略层的备选项&#xff0c;也将逐步变为需要快速落地的必选项。 为了确保用户能高效应对外企离…

[C++]:12:模拟实现list

[C]:12:模拟实现list 一.看一看SGI的stl_list的源码&#xff1a;1.基础结构构造函数1.节点结构&#xff1a;2.节点构造函数&#xff1a;3.链表结构&#xff1a;4.链表的构造函数&#xff1a; 2.析构1.节点析构&#xff1a;2.链表的析构&#xff1a; 3.迭代器 二.模拟实现list1.…

十二款·富文本编辑器:数字创作的瑞士军刀

在数字化时代&#xff0c;内容创作已经成为我们日常生活中不可或缺的一部分。无论是撰写一封电子邮件、准备一份报告、还是在社交媒体上分享心情&#xff0c;文字都是我们表达和沟通的基石。而在这个过程中&#xff0c;富文本编辑器就如同一把瑞士军刀&#xff0c;为我们提供了…

商品详情APP端原数据淘宝数据采集API接口代码接入示例

商品详情APP端原数据API接口&#xff08;接口接入入口&#xff09;的作用是提供APP端商品的详细信息&#xff0c;包括价格、描述、图片、折后价、优惠券信息等。通过调用这个API接口&#xff0c;开发者可以获取到APP端商品详情相关的数据&#xff0c;从而进行数据分析&#xff…

怎么录屏?这里有一份超详细教程!

随着科技的发展&#xff0c;录屏已经成为人们日常生活中经常需要使用的功能&#xff0c;无论是录制游戏、教学演示、在线会议等都需要用到录屏。可是您知道怎么录屏才是最好的吗&#xff1f;接下来&#xff0c;本文将为您介绍三种流行的录屏方法&#xff0c;并提供详细的分步骤…

【遥感数字图像处理(朱文泉)】各章博文链接汇总及思维导图

遥感数字图像处理课程汇总 第0章 绪论第一章 数字图像基础第二章 数字图像存储与处理第三章 空间域处理方法第四章 变换域处理方法第五章 辐射校正第六章 几何校正第七章 图像去噪声第八章 图像增强第九章 感兴趣目标及对象提取第十章 特征提取与选择第十一章 遥感数字图像分类…

Unity 编辑器篇|(九)编辑器美化类( GUIStyle、GUISkin、EditorStyles) (全面总结 | 建议收藏)

目录 1. GUIStyle1.1 参数总览1.2 样式代码 2. GUISkin2.1 参数总览2.2 创建自定义Skin 3. EditorStyles2.1 参数总览1.2 反射获取所有EditorStyles 1. GUIStyle GUIStyle是一个用于定制GUI控件样式的类&#xff0c;它包含了控件的外观属性&#xff0c;如字体、颜色、背景等。…

springboot 3 + mysql8 + flyway 数据库版本管理

1、flyway flyway官方文档地址&#xff1a;https://documentation.red-gate.com/fd 对于不怎么看文档的我来说&#xff1a; 1&#xff09;flyway是个管理数据库版本的工具&#xff0c;可以对不同环境的sql进行迁移操作。 2&#xff09;优点&#xff1a;初始化、后期数据的管理…

dpdk网络转发环境的搭建

文章目录 前言ip命令的使用配置dpdk-basicfwd需要的网络结构测试dpdk-basicfwddpdk-basicfwd代码分析附录basicfwd在tcp转发时的失败抓包信息DPDK的相关设置 前言 上手dpdk有两难。其一为环境搭建。被绑定之后的网卡没有IP&#xff0c;我如何给它发送数据呢&#xff1f;当然&a…

动物免疫(羊驼免疫)-泰克生物

在过去几十年里&#xff0c;抗体研究和应用的领域已经经历了革命性的变化。在这个进程中&#xff0c;一种特殊来源的抗体 —— 来自骆驼科动物&#xff08;包括羊驼&#xff09;的单链抗体&#xff08;也称纳米抗体&#xff09;引起了全球科学家的广泛关注。 羊驼等骆驼科动物…

vectorCast添加边界值分析测试用例

1.1创建项目成功后会自动生成封装好的函数,在这些封装好的函数上点击右键,添加边界值分析测试用例,如下图所示。 1.2生成的用例模版是不可以直接运行的,需要我们分别点击它们,让它们自动生成相应测试用例。如下图所示,分别为变化前和变化后。 1.3点击选中生成的测试用例,…

家庭教育小知识青春期孩子如何教育?

孩子进入青春期后&#xff0c;很多家长都纷纷感叹&#xff0c;与孩子相处太难了。那个曾经乖巧、黏人的孩子&#xff0c;好像一夜之间浑身长满刺&#xff0c;变得叛逆、敏感、暴躁、将父母拒之门外、甚至是辱骂、羞辱父母。 让父母更挫败的是&#xff0c;曾经通过说教、讲道理…

sqlmap使用教程(1)

一、sqlmap简介 sqlmap是一个自动化SQL注入测试工具&#xff0c;它支持的数据库有MySQL、MSSQL、Oracle、PostgreSQL、Access、IBM DB2、SQLite、Firebird、Sybase和SAP MaxDB。sqlmap默认使用以下5种SQL注入技术&#xff1a; 基于布尔的盲注&#xff1a;根据返回页面判断条件…