Spring Boot实战:拦截器

一.拦截器快速入门

1.1了解拦截器

什么是拦截器

概念 :拦截器是Spring框架提供的核⼼功能之⼀, 主要⽤来拦截⽤⼾的请求, 在指定⽅法前后, 根据业务需要执⾏预先设定的代码。
也就是说, 允许开发⼈员提前预定义⼀些逻辑, 在⽤⼾的请求响应前后执⾏. 也可以在⽤⼾请求前阻⽌其执⾏.
在拦截器当中,开发⼈员可以在应⽤程序中做⼀些通⽤性的操作, ⽐如通过拦截器来拦截前端发来的请求, 判断Session中是否有登录⽤⼾的信息. 如果有就可以放⾏, 如果没有就进⾏拦截.

想象一下你去一个需要门禁的办公楼,拦截器就像是那个门禁系统。当你(请求)想要进入办公楼(访问某个资源)时,门禁系统(拦截器)会先检查你是否符合条件(比如是否持有有效的门禁卡或是否已经通过身份验证)。如果符合条件,门禁系统会放行,让你进入办公楼;如果不符合条件,门禁系统会阻止你进入,并可能要求你进行其他操作(比如登记或联系相关人员)。

在SpringBoot中,拦截器就是这样一种机制,它可以在请求到达控制器之前或之后“拦截”请求,并根据预定义的规则对请求进行处理。

 

拦截器在SpringBoot中主要有以下几个作用:

  1. 身份验证和权限控制
    • 就像门禁系统检查门禁卡一样,拦截器可以检查用户的身份验证状态和权限。例如,当用户尝试访问一个需要登录才能查看的页面时,拦截器会检查用户是否已经登录。如果用户未登录,拦截器可以重定向用户到登录页面或返回错误信息。
  2. 日志记录
    • 拦截器可以在请求到达控制器之前或之后记录日志信息。这对于监控和调试应用程序非常有用,因为它可以帮助你了解请求是如何被处理的,以及处理过程中发生了哪些事情。
  3. 请求预处理和响应后处理
    • 在请求到达控制器之前,拦截器可以对请求进行预处理,比如修改请求参数、设置请求头等。在控制器处理完请求并生成响应后,拦截器还可以对响应进行后处理,比如修改响应头、添加额外的数据到响应中等。
  4. 异常处理
    • 拦截器还可以捕获并处理请求处理过程中发生的异常。例如,如果控制器在处理请求时抛出了异常,拦截器可以捕获这个异常,并根据异常类型进行相应的处理,比如返回自定义的错误页面或错误信息。

 1.2拦截器的基本使用

拦截器的使⽤步骤分为两步:
  1.  定义拦截器
  2. 注册配置拦截器

1.⾃定义拦截器:实现HandlerInterceptor接⼝,并重写其所有⽅法

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler) throws Exception {log.info("LoginInterceptor ⽬标⽅法执⾏前执⾏..");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler, ModelAndView modelAndView) throws Exception {log.info("LoginInterceptor ⽬标⽅法执⾏后执⾏");}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("LoginInterceptor 视图渲染完毕后执⾏,最后执⾏");}
}

 

  • preHandle()⽅法:⽬标⽅法执⾏前执⾏. 返回true: 继续执⾏后续操作; 返回false: 中断后续操作.
  • postHandle()⽅法:⽬标⽅法执⾏后执⾏
  • afterCompletion()⽅法:视图渲染完毕后执⾏,最后执⾏(后端开发现在⼏乎不涉及视图, 暂不了解)

2.注册配置拦截器:实现WebMvcConfigurer接⼝,并重写addInterceptors⽅法 

@Configuration
public class WebConfig implements WebMvcConfigurer {//⾃定义的拦截器对象@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册⾃定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求)}
}
3.启动服务, 试试访问任意请求, 观察后端⽇志
可以看到preHandle ⽅法执⾏之后就放⾏了, 开始执⾏⽬标⽅法, ⽬标⽅法执⾏完成之后执⾏
postHandleafterCompletion⽅法.
4.我们把拦截器中preHandle⽅法的返回值改为false, 再观察运⾏结果

可以看到, 拦截器拦截了请求, 没有进⾏响应.

1.2拦截器详解

 

拦截器的⼊⻔程序完成之后,接下来我们来介绍拦截器的使⽤细节。拦截器的使⽤细节我们主要介绍
两个部分:
  1. 拦截器的拦截路径配置
  2. 拦截器实现原理

 

拦截路径是指我们定义的这个拦截器, 对哪些请求⽣效.
我们在注册配置拦截器的时候, 通过 addPathPatterns() ⽅法指定要拦截哪些请求. 也可以通过
excludePathPatterns() 指定不拦截哪些请求.
上述代码中, 我们配置的是 /** , 表⽰拦截所有的请求.
⽐如⽤⼾登录校验, 我们希望可以对除了登录之外所有的路径⽣效。
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {//⾃定义的拦截器对象@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册⾃定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/user/login");//设置拦截器拦截的请求路径(/** 表⽰拦截所有请求)}}
在拦截器中除了可以设置 /** 拦截所有资源外,还有⼀些常⻅拦截路径设置:
以上拦截规则可以拦截此项⽬中的使⽤ URL,包括静态⽂件(图⽚⽂件, JS 和 CSS 等⽂件)

1.3拦截器执行流程

正常的调⽤顺序:

 有了拦截器之后,会在调⽤ Controller 之前进⾏相应的业务处理,执⾏的流程如下图

 

1.添加拦截器后, 执⾏Controller的⽅法之前, 请求会先被拦截器拦截住. 执⾏ preHandle() ⽅法,
这个⽅法需要返回⼀个布尔类型的值. 如果返回true, 就表⽰放⾏本次操作, 继续访问controller中的 ⽅法. 如果返回false,则不会放⾏(controller中的⽅法也不会执⾏).
2.controller当中的⽅法执⾏完毕后,再回过来执⾏ postHandle() 这个⽅法以afterCompletion() ⽅法,执⾏完毕之后,最终给浏览器响应数据.

 1.4登录校验

学习拦截器的基本操作之后,接下来我们需要完成最后⼀步操作:通过拦截器来完成图书管理系统中的登录校验功能.
1.定义拦截器
从session中获取⽤⼾信息, 如果session中不存在, 则返回false,并设置http状态码为401, 否则返回true.
import com.example.demo.constant.Constants;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler) throws Exception {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constants.SESSION_USER_KEY) != null) {return true;}response.setStatus(401);return false;}
}
http状态码401: Unauthorized
Indicates that authentication is required and was either not provided or has failed. If the
request already included authorization credentials, then the 401 status code indicates that
those credentials were not accepted.
中⽂解释: 未经过认证. 指⽰⾝份验证是必需的, 没有提供⾝份验证或⾝份验证失败. 如果请求已经包含授权凭据,那么401状态码表⽰不接受这些凭据

2.注册配置拦截器

 

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {//⾃定义的拦截器对象@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册⾃定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径(/**表⽰拦截所有请求).excludePathPatterns("/user/login")//设置拦截器排除拦截的路径.excludePathPatterns("/**/*.js") //排除前端静态资源.excludePathPatterns("/**/*.css").excludePathPatterns("/**/*.png").excludePathPatterns("/**/*.html");}
}
3.删除之前的登录校验代码
    @RequestMapping("/getListByPage")public Result getListByPage(PageRequest pageRequest, HttpSession session) {log.info("获取图书列表, pageRequest:{}", pageRequest);
// //判断⽤⼾是否登录
// if (session.getAttribute(Constants.SESSION_USER_KEY)==null){
// return Result.unlogin();
// }
// UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
// if (userInfo==null || userInfo.getId()<0 || "".equals(userInfo.getUserName())){
// return Result.unlogin();
// }//⽤⼾登录, 返回图书列表PageResult<BookInfo> pageResult =bookService.getBookListByPage(pageRequest);log.info("获取图书列表222, pageRequest:{}", pageResult);return Result.success(pageResult);}

4运⾏程序, 通过Postman进⾏测试:

4.1查看图书列表

观察返回结果: h
也可以通过Fiddler抓包观察

4.2登录

4.3再次查看图书列表 

数据进⾏了返回

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

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

相关文章

ThinkPHP6与金仓数据库(Kingbase)集成:模型查询的解决方案

摘要&#xff1a; ThinkPHP6是一款流行的PHP框架&#xff0c;支持多种数据库。然而&#xff0c;对于金仓数据库&#xff08;Kingbase&#xff09;这种相对小众的数据库系统&#xff0c;开发者在使用ThinkPHP6进行模型查询时可能会遇到一些兼容性问题。本文将提供一种解决方案&a…

仿推特社区源码修复版,含pc端和H5端,可以封装成app

简介&#xff1a; 新鲜出炉的仿推特社区源码修复版&#xff0c;含pc端和H5端&#xff0c;可以封装成app。这玩意绝对可以算是精品代码了。 手机h5端可以封装成软件也不错的。 推特的风格还是不错的&#xff0c;不然世界首富马斯克也不会花费440亿美金收购它了。 阅览&#…

nginx 405错误是什么意思

405错误&#xff1a;方法不被允许 当Web服务器收到一个它不支持的HTTP请求方法时&#xff0c;就会返回405错误。 原因 405错误通常是由于客户端发出了不兼容或不支持的HTTP请求方法。例如&#xff0c;客户端可能请求一个只能通过GET方法访问的资源&#xff0c;但使用了POST方…

图片转文字怎么操作?教你几招图片转文字小妙招

在日常的工作学习中&#xff0c;我们每天可能会接触到大量的图片资料&#xff0c;无论是会议纪要、书籍扫描页、还是网络上的有用信息截图&#xff0c;如果能快速将这些图片中的文字提取出来&#xff0c;无疑将极大提升我们的工作效率。下面给大家分享几种能够将图片转换成文字…

简单中间件模型

中间件是软件开发过程中架构的一个通用概念&#xff0c;其目的在于为运行的主程序提供一个供外部自定义拓展的能力。比如&#xff1a;wen服务的controller层中间件针对request请求处理的前后进行通用的扩展处理、redux中间件针对store数据获取前后的扩展处理。。。   本文简单…

OrangePi AIpro学习3 —— vscode开发昇腾DVPP程序

目录 一、VScode配置 1.1 下载和安装 1.2 安装和配置需要的插件 二、构建项目 2.1 项目架构 2.2 解决代码高亮显示 2.3 测试编译 2.4 总结出最简单的代码 2.5 vscode报错找不到头文件解决方法 三、代码简单讲解 3.1 初始化部分 3.2 拷贝数据到NPU显存中 3.3 准备裁…

python-报数(赛氪OJ)

[题目描述] 有 n 人围成一圈&#xff0c;顺序排号。 从第 1 个人开始报数&#xff08;从 1 到 3 报数&#xff09;&#xff0c;凡是报到 3 的人退出圈子&#xff0c;问最后留下的是原来的第几号的那位。输入格式&#xff1a; 初始人数 n 。输出格式&#xff1a; 最后一人的初始…

python游戏开发之五子棋游戏制作

五子棋是一种源自中国的传统棋类游戏&#xff0c;起源可以追溯到古代。它是一种两人对弈的游戏&#xff0c;使用棋盘和棋子进行。棋盘通常是一个 1515 的网格&#xff0c;棋子分为黑白两色&#xff0c;双方轮流在棋盘上落子。游戏的目标是通过在棋盘上落子&#xff0c;使自己的…

【深度学习】基于YOLOV5模型的图像识别-目标检测的性能指标详解与计算方法

目标检测是计算机视觉中的重要任务&#xff0c;主要目的是在图像中识别并定位特定的物体。YOLO&#xff08;You Only Look Once&#xff09;系列模型作为目标检测领域的代表性方法之一&#xff0c;凭借其高效和准确的特点&#xff0c;广泛应用于实际场景中。本文通过详细介绍目…

C++之移动语义与左值右值深入学习:从入门到精通!

简介 本文详细阐述了 C 中关于移动语义、左值右值等技术的基本概念和常用技巧。 问题的产生 每一项技术的诞生都是为了解决某一个问题&#xff0c;移动语义、左值右值也是一样&#xff0c;因此我们先来看看问题产生的背景。 先来看一段代码&#xff1a; #include <iost…

JavaEE: Thread类

Thread的常见构造方法 Thread的常见属性 ID 是线程的唯一标识,不同线程不会重复名称是在使用各种调试工具时会用到的状态表示线程当前所处的情况优先级高的线程理论上来说更容易被调度到关于后台线程,需要记住:JVM会在一个进程的所有非后台线程结束后,才会结束运行是否存活,即r…

社交及时通讯平台完整版源码,uniapp技术,可打包成app

源码简介&#xff1a; 全原生&#xff0c;从底层开始结构就完全不一样&#xff0c;mongodb的库&#xff0c;uniapp混编手端&#xff0c;二开难度要比视酷或者酷信容易很多。全开源&#xff0c;带开发文档。前端用的是uniapp技术&#xff0c;所以是多端合一&#xff0c;可以做h…

【JVM基础14】——垃圾回收-强引用、软引用、弱引用、虚引用的区别

目录 1- 引言&#xff1a;为什么分多种引用类型2- ⭐核心&#xff1a;2-1 强引用2-2 软引用2-3 弱引用2-4 虚引用 3- 小结&#xff1a;3-1 强引用、软引用、弱引用、虚引用的区别&#xff1f; 1- 引言&#xff1a;为什么分多种引用类型 在 Java 中&#xff0c;引用类型被分为强…

linux 6.10.0 CXL/reg.c 详解

文章目录 前言Ref正文1. cxl_setup_regs2. cxl_probe_regs()3. cxl_probe_component_regs()4. cxl_probe_device_regs()5. cxl_map_device_regs()6. cxl_count_regblock() / cxl_find_regblock_instance() 前言 CXL 是一个比较新的技术&#xff0c;内核版本迭代太快&#xff0…

python爬虫预备知识三-多进程

python实现多进程的方法&#xff1a;fork、multiprocessing模块创建多进程。 os.fork方法 os.fork方法只适合于unix/linux系统&#xff0c;不支持windows系统。 fork方法调用一次会返回两次&#xff0c;原因在于操作系统将当前进程&#xff08;父进程&#xff09;复制出一份…

在Linux中,什么叫做线程

在Linux中&#xff0c;什么叫做线程&#xff1f; CPU调度的基本单位。 在Linux中&#xff0c;什么叫做进程&#xff1f; 内核视角&#xff1a; 承担分配系统资源的基本实体。 一个进程内部可以有多个执行流。 task_struct可以理解为轻量级进程。 线程是进程内部的一个分支…

【python】Python中位运算算法详细解析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

数据库扩展新篇章:主流分库分表中间件全解析

摘要&#xff1a; 随着企业数据量的激增&#xff0c;传统的单体数据库架构已经无法满足日益增长的性能需求和数据管理复杂性。分库分表技术作为解决这一问题的有效手段&#xff0c;通过将数据水平或垂直地分散到多个数据库中&#xff0c;提高了系统的扩展性和处理能力。本文将详…

LISA: Reasoning Segmentation via Large Language Model

发表时间&#xff1a;CVPR 2024 论文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2024/papers/Lai_LISA_Reasoning_Segmentation_via_Large_Language_Model_CVPR_2024_paper.pdf 作者单位&#xff1a;CUHK Motivation&#xff1a;尽管感知系统近年来取得了显…

鸡舍环控系统

在现代养殖业中&#xff0c;科技的进步正悄然改变着传统模式&#xff0c;其中&#xff0c;基于物联网和自动控制技术的鸡舍环控系统正逐渐成为行业内的新宠。这套系统不仅能够集成温湿度、光照度等参数的监测与控制&#xff0c;还能通过智能化手段减轻日常养殖工作量&#xff0…