SpringBoot的Web拦截器

拦截器与Filter的区别

首先拦截器(Intercepter)过滤器(Filter)都是Web项目中针对Request请求的处理组件,在请求到达业务处理逻辑前,进行预处理,包括监控、安全相关的职责。

所处位置

首先SpringBoot的拦截器本质是SpringMVC的一部分,SpringMVC的核心是DispatcherServlet ,DispatcherServlet 是一个特殊的 Servlet。它实现了 Servlet 接口,并遵循 Servlet 的生命周期。在 Spring MVC 中,DispatcherServlet 是最顶层的 Servlet,它扩展了 Servlet 的功能,提供了 Spring MVC 特有的请求处理机制。

也就是说SpringMVC是基于DispatcherServlet 工作,而DispatcherServlet 是基于J2EE的Servlet的一种二次抽象封装。

过滤器(Filter)工作在 Servlet 规范中,它们在请求进入 DispatcherServlet 之前被调用,也就是说,它们在 Spring MVC 的上下文之外工作。

 拦截器(Intercepter)则是SpringMVC内部的概念,它工作在 Spring MVC 的 DispatcherServlet 中,这意味着它们在 Spring 的整个请求处理流程中有多个介入点。

总的来讲,在职能上,过滤器和拦截器都可以对请求和响应进行预处理,比如设置请求属性、修改请求和响应内容等。具体实现时由于过滤器在 Spring 的请求处理流程之外,因此它们无法访问 Spring 的上下文或 Bean,在Spring项目中不如拦截器方便。可以理解过滤器(Filter)是Web容器级的,而拦截器(Intercepter)是框架级的。

值处理

 拦截器(Intercepter)可以介入到请求的处理流程中的以下阶段:

  • preHandle:在控制器方法执行之前调用,可以决定是否继续执行后续的拦截器或控制器。如果返回 true,请求继续向下传递;如果返回 false,请求将被中断,后续的拦截器和控制器将不会被调用。
  • postHandle:在控制器方法执行之后,视图渲染之前调用。此时可以对控制器的返回值进行操作。
  • afterCompletion:在请求处理完成之后,也就是渲染了视图后调用。这个阶段可以用来进行资源清理工作。

过滤器(Filter)主要介入以下阶段:

  • doFilter:在请求到达 DispatcherServlet 之前调用。过滤器可以对请求和响应进行预处理,比如设置请求属性、修改请求和响应内容等。

拦截器(Intercepter) preHandle 方法具有返回值,这是一个布尔值,用于控制请求是否继续向下传递。这个返回值提供了一种机制,允许拦截器根据预处理的结果来决定是否继续执行后续的拦截器或控制器。例如,如果一个拦截器用于权限检查,并且当前用户没有权限执行某个操作,那么它可以返回 false 来阻止请求继续传递,并可能转发到错误页面或返回一个错误响应。

过滤器(Filter)的 doFilter 方法没有返回值。过滤器通过直接操作请求和响应对象来实现其功能。如果需要中断请求或改变请求的流向,过滤器可以通过修改请求对象或抛出异常来实现。例如,如果过滤器检测到非法请求,它可以修改请求对象,将其转发到一个错误处理页面,或者直接设置响应状态码和响应内容,然后结束请求。

总之,拦截器通过返回值提供了更灵活的控制机制,可以在请求处理的不同阶段决定是否继续处理请求。而过滤器则通过直接操作请求和响应对象来实现控制,它们在请求进入 Spring MVC 之前提供了一种预处理机制。

拦截器的使用

使用拦截器主要包含两步:

  1. 自定义拦截器类
  2. 注册拦截器到Spring中

开发拦截器

自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类。然后实现三个方法:

  • preHandler(HttpServletRequest request, HttpServletResponse response, Object handler)
  • postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)

preHandler方法

该方法在处理之前最先被调用,用来进行一些前置初始化操作或是对当前请求做预处理,也可以进行一些判断来决定请求是否要继续进行下去。该方法的返回至是 Boolean 类型,当它返回 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当它返回为 true 时会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候就会调用当前请求的 Controller 方法。

postHandler方法

postHandler是当前请求处理完成之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。针对大部分前后端分离的项目,此方法使用较少。

afterCompletion方法

需要在当前对应的 Interceptor 类的 postHandler 方法返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理。一般不使用该方法。

我们编写用于请求认证的拦截器:

@Compont //对于Spring内部,建议使用注解,使其统一交给Spring进行bean管理
public class RefererIntercepter extends HandlerInterceptorAdapter {@Autowiredprivate SystemService system;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String referer = request.getHeader("Referer");if(system.checkReferer(referer)){return true;}return false;}//继承HandlerInterceptorAdapter 的方式,对于不使用的postHandle、afterCompletion可以不用实现
}
@Compont //对于Spring内部,建议使用注解,使其统一交给Spring进行bean管理
public class LoginCheckIntercepter extends HandlerInterceptorAdapter {@Autowiredprivate UserService userService;@Autowiredprivate CookieService cookieService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Cookie[] cookie = request.getCookies();String id = cookieService.getTokenId(cookie);String seesionId = request.getSessionId();if(!userService.timeoutSession(sessionId) && userService.isInvaild(id)){userService.refresh(seesionId);return true;}return false;}//继承HandlerInterceptorAdapter 的方式,对于不使用的postHandle、afterCompletion可以不用实现
}

注册拦截器

基于WebMvcConfigurer接口,实现SpringMVC的Web配置类,通过addInterceptors将拦截器注入:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowired private RefererIntercepter  referer;@Autowired LoginCheckIntercepter loginCheck;private @Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册referer拦截,order设置为最先拦截,并指定url前缀为innerPage的接口registry.addInterceptor(referer).order(0).addPathPatterns("/innerPage/**");//注册登录认证拦截,排除url前缀为exit和test的接口registry.addInterceptor(loginCheck).order(1).addPathPatterns("/admin/oldLogin").excludePathPatterns("/exit/**","test/**");}
}

补充:WebMvcConfigurer方法

  • addInterceptors(InterceptorRegistry registry): 该方法用于注册拦截器(Interceptor),可以通过 registry.addInterceptor(拦截器Bean) 添加自定义拦截器,并使用 addPathPatterns 指定拦截路径或 excludePathPatterns 指定排除路径。

@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).order(1)//拦截顺序.addPathPatterns("/api/**").excludePathPatterns("/api/exit/**");//剔除的URL
}
  • addCorsMappings(CorsRegistry registry): 用于添加跨域请求配置。可以在 CorsRegistry 中配置哪些路径需要跨域支持,以及支持哪些域名、方法和头信息等。

@Override
public void addCorsMappings(CorsRegistry registry) {// 添加跨域请求配置,允许指定路径下的所有域名进行跨域请求registry.addMapping("/api/**").allowedOrigins("http://example.com").allowedMethods("GET", "POST").allowedHeaders("*").allowCredentials(true);
}
  • addResourceHandlers(ResourceHandlerRegistry registry): 通过该方法可以添加静态资源的处理规则。通常用于指定静态资源的路径和位置,如图片、JavaScript 文件和 CSS 文件等。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {// 配置静态资源的访问路径和位置registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
  • configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer): 允许配置默认的 Servlet 处理,例如启用或禁用默认的 Servlet 处理。

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {// 启用默认的 Servlet 处理configurer.enable();
}
  • configureViewResolvers(ViewResolverRegistry registry): 用于配置视图解析器,它可以将控制器返回的视图名称解析为具体的视图实现。

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {// 配置视图解析器,指定 JSP 文件的位置和后缀registry.jsp("/WEB-INF/views/", ".jsp");
}
  • configureContentNegotiation(ContentNegotiationConfigurer configurer): 用于配置内容协商策略,即如何根据请求头中的信息决定响应的格式(如 JSON、XML 等)。

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {// 配置内容协商策略,决定响应的格式configurer.favorPathExtension(true).ignoreAcceptHeader(true).useRegisteredExtensionsOnly(false).defaultContentType(MediaType.APPLICATION_JSON);
}
  • addViewControllers(ViewControllerRegistry registry): 用于注册特定的视图控制器,可以实现 URL 到视图的直接映射,而不需要通过控制器方法。

@Override
public void addViewControllers(ViewControllerRegistry registry) {// 注册一个视图控制器,直接映射 URL 到视图页面registry.addViewController("/home").setViewName("home");
}
  • configureMessageConverters(List<HttpMessageConverter<?>> converters): 允许配置或添加自定义的消息转换器,这些转换器负责处理 HTTP 请求和响应的转换。

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 添加自定义的消息转换器到转换器列表中converters.add(new MappingJackson2HttpMessageConverter());
}
  • extendMessageConverters(List<HttpMessageConverter<?>> converters): 用于在现有消息转换器的基础上添加额外的转换器,而不替换默认的转换器。

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {// 在现有消息转换器列表中添加额外的自定义转换器converters.add(new MyCustomMessageConverter());
}

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

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

相关文章

Nature Communications 可远程操控食欲的口服软体机器人

肥胖对人群的的影响是深远的&#xff0c;它不仅关系到个人的健康&#xff0c;还与全球公共卫生挑战密切相关。据世界卫生组织的数据&#xff0c;全球每8人中就有1人患有肥胖症。肥胖增加了患2型糖尿病、心血管疾病、某些癌症等多种健康问题的风险&#xff0c;并对社会经济产生重…

【北京迅为】《STM32MP157开发板使用手册》-第十八章 Debian文件系统

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

OpenCV结构分析与形状描述符(20)计算一个包围给定点集的最小外接圆函数minEnclosingCircle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 找到一个包围二维点集的最小面积的圆。 该函数使用迭代算法来寻找一个二维点集的最小外接圆。这意味着函数将会通过反复逼近的过程来计算出能够…

misc音频隐写

一、MP3隐写 &#xff08;1&#xff09;题解&#xff1a;下载附件之后是一个mp3的音频文件&#xff1b;并且题目提示keysyclovergeek;所以直接使用MP3stego对音频文件进行解密&#xff1b;mp3stego工具是音频数据分析与隐写工具 &#xff08;2)mp3stego工具的使用&#xff1a;…

BMP280气压传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.传感器数据获取流程 三、程序设计 main.c文件 bmp280.h文件 bmp280.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 BMP280是一款基于博世公司APSM工艺的小封装低功耗数字复合传感器&#xff0c;它可以测…

大模型书籍丨国内顶尖院校出品,非常火爆的LLM大模型入门中文书来了

最近有一本人工智能入门的书比较火&#xff0c;这本书集合了最新的产品、技术&#xff0c;并通过顶尖院校的教授书写而成。我今天阅读了第一章&#xff0c;感觉浅显易懂&#xff0c;顺便把笔记也做出来了&#xff0c;供大家参考。 大语言模型入门 第一部分 背景与基础知识 第…

[数据集][目标检测]电动车入梯进电梯电单车入梯检测数据集VOC+YOLO格式7106张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;7106 标注数量(xml文件个数)&#xff1a;7106 标注数量(txt文件个数)&#xff1a;7106 标注…

未来数据中心网络的创新光互连解决方案

随着应用场景的发展&#xff0c;企业对数据中心网络及光模块的需求也在不断变化。对于长距离波分复用应用&#xff0c;企业优先考虑性能&#xff0c;追求更长的传输距离和更高的光谱效率。相比之下&#xff0c;对于数据中心内部的短距离应用&#xff0c;企业更注重成本&#xf…

002 JavaClent操作RabbitMQ

Java Client操作RabbitMQ 文章目录 Java Client操作RabbitMQ1.pom依赖2.连接工具类3.简单模式4.工作队列模式&#xff08;work&#xff09;公平调度示例 5.发布/订阅模式&#xff08;fanout&#xff09;交换机绑定示例代码 6.路由模式&#xff08;direct&#xff09;7.Topic匹配…

LVS--负载均衡调度器

文章目录 集群和分布式集群分布式 LVS介绍LVS特点LVS工作原理LVS集群架构 LVS集群中的术语CIPVIPRSDIPRIP LVS集群的工作模式NAT模式DR模式DR的工作原理DR的特点:DR的网络配置1.配置负载均衡器2.配置后端服务器lo接口的作用 3.测试连接&#xff1a; DR的典型应用场景 TUN模式 L…

《深度学习》【项目】 OpenCV 身份证号识别

目录 一、项目实施 1、自定义函数 2、定位模版图像中的数字 1&#xff09;模版图二值化处理 运行结果&#xff1a; 2&#xff09;展示所有数字 运行结果&#xff1a; 3、识别身份证号 1&#xff09;灰度图、二值化图展示 运行结果 2&#xff09;定位身份证号每一个数…

❤Node08-Express-jwt身份认证

❤Node08-Express-jwt身份认证 1、token基本概念​ Session认证的局限性​ Session 认证机制需要配合Cookie才能实现。由于 Cookie 默认不支持跨域访问&#xff0c;所以&#xff0c;当涉及到前端跨域请求后端接口的时候&#xff0c;需要做很多额外的配置&#xff0c;才能实现…

【JVM】JVM栈帧中的动态链接 与 Java的面向对象特性--多态

栈帧 每一次方法调用都会有一个对应的栈帧被压入栈&#xff08;虚拟机栈&#xff09;中&#xff0c;每一个方法调用结束后&#xff0c;都会有一个栈帧被弹出。 每个栈帧中包括&#xff1a;局部变量表、操作数栈、动态链接、方法返回地址。 JavaGuide&#xff1a;Java内存区域…

Debian项目实战——环境搭建篇

Debian系统安装 准备工作 1、系统镜像&#xff1a;根据自己的需要选择合适的版本格式&#xff1a;x86 / arm 架构 | 最好下载离线安装版本 | 清华镜像源 2、制作工具&#xff1a;balenaEtcher 3、系统媒介&#xff1a;16G以上U盘最佳 烧录镜像 打开balenaEtcher进行烧录&am…

改变事件

窗口的某些属性的状态发生改变时就会触发该事件 对应的事件类型包括 QEvent::ToolBarChange, QEvent::ActivationChange, QEvent::EnabledChange, QEvent::FontChange,QEvent::StyleChange, QEvent::PaletteChange, QEvent::WindowTitleChange, QEvent::IconTextChange, QEve…

【练习9】大数加法

链接&#xff1a;大数加法__牛客网 (nowcoder.com) 分析&#xff1a; 当作竖式计算 import java.util.*;public class Solution {public String solve (String s, String t) {StringBuffer ret new StringBuffer();//i是字符串s的最后一个字符的索引int i s.length() - 1;//j…

新能源汽车安全问题如何解决?细看“保护罩”连接器的守护使命

「当前市场上绝大部分电池的安全系数远远不够」。 在一场世界动力电池大会上&#xff0c;宁德时代的董事长曾毓群这样犀利直言。 从汽车开始向电动化转型升级那天起&#xff0c;动力电池的安全隐患就一直是个老生常谈的话题了。曾毓群的这句话&#xff0c;直接点明了行业的发展…

参数传了报错没传参数识别不到参数传丢

【记一次参数传值了但报错未传值的问题解决历程】 问题描述&#xff1a;同一个接口&#xff0c;用测试类调可以成功&#xff0c;用postman调用一直报错少参数&#xff0c;后又尝试了用idea自带的http调用&#xff0c;同样报错参数未传值。 如图&#xff0c;传值了报错未传值。…

Java并发:互斥锁,读写锁,Condition,StampedLock

3&#xff0c;Lock与Condition 3.1&#xff0c;互斥锁 3.1.1&#xff0c;可重入锁 锁的可重入性&#xff08;Reentrant Locking&#xff09;是指在同一个线程中&#xff0c;已经获取锁的线程可以再次获取该锁而不会导致死锁。这种特性允许线程在持有锁的情况下&#xff0c;可…

AI网盘搜索 1.2.6 智能文件搜索助手,一键搜索所有资源

对于经常需要处理大量文件的人来说&#xff0c;AI网盘检索简直是救星。它提供了智能对话式搜索功能&#xff0c;只需用自然语言描述就能找到需要的文件。此外&#xff0c;它还广泛支持各种文件类型&#xff0c;从文档到图片&#xff0c;全面覆盖。精准定位功能让您能够快速找到…