Spring中的拦截器

news2024/11/15 10:01:08

这里写目录标题

  • 基本概念
    • HandlerInterceptor拦截器
    • HandlerInterceptor讲解
  • MethodInterceptor拦截器
  • 二者的区别

基本概念

在web开发中,拦截器是经常用到的功能。它可以帮我们预先设置数据以及统计方法的执行效率等等。
Spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor。

HandlerInterceptor拦截器

HandlerInterceptor是SpringMVC项目中的拦截器,它拦截的目标是请求的地址,比MethodInterceptor先执行。其工作原理是当请求来时先进行预处理,如下:
在这里插入图片描述
通过HandlerInterceptor实现打印请求开始和结束的日志,代码如下:
引入相关依赖:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter</artifactId>
 </dependency>
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

拦截器:

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class EasyLogControllerInterceptor implements HandlerInterceptor {

    /**
     * 在controller调用之前执行
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info(request.getRequestURI() + "开始执行");
        return true;
    }

    /**
     * 在controller调用中执行
     */
    public void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }

    /**
     * 在controller调用后执行
     */
    public void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        log.info(request.getRequestURI() + "执行结束");
    }

}

controller:

@GetMapping(value = "/test/user")
public String testUser() {
    log.info("test");
    return "string";
}

配置类:

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@RequiredArgsConstructor
public class IntercepterConfig implements WebMvcConfigurer {

    private final EasyLogControllerInterceptor easyLogControllerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addPathPatterns用于添加拦截路径
        //excludePathPatterns用于添加不拦截的路径
        registry.addInterceptor(easyLogControllerInterceptor).addPathPatterns("/test/user");

    }

    //此方法用于配置静态资源路径
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/my/");
    }
}

输出结果:

2023-02-20 21:07:10.681 c.x.d.c.EasyLogControllerInterceptor     : /test/user开始执行
2023-02-20 21:07:10.688 c.xhy.demo01.controller.HelloController  : test
2023-02-20 21:07:10.714 c.x.d.c.EasyLogControllerInterceptor     : /test/user执行结束

HandlerInterceptor讲解

实现一个HandlerInterceptor拦截器可以直接实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter类。这两种方法殊途同归,其实HandlerInterceptorAdapter也就是声明了HandlerInterceptor接口中所有方法的默认实现,而我们在继承他之后只需要重写必要的方法即可。
下面就是HandlerInterceptorAdapter的代码,可以看到一个方法只是默认返回true,另外两个是空方法:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class HandlerInterceptorAdapter implements HandlerInterceptor {

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

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

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

}

这三个方法都是干什么的,有什么作用,什么时候调用,不同的拦截器之间是怎样的调用顺序呢?
在这里插入图片描述
这还得参考一下DispatcherServlet的doDispatch方法:
在这里插入图片描述
代码有点长,但是它封装了SpringMVC处理请求的整个过程。首先根据请求找到对应的HandlerExecutionChain,它包含了处理请求的handler和所有的HandlerInterceptor拦截器;然后在调用hander之前分别调用每个HandlerInterceptor拦截器的preHandle方法,若有一个拦截器返回false,则会调用triggerAfterCompletion方法,并且立即返回不再往下执行;若所有的拦截器全部返回true并且没有出现异常,则调用handler返回ModelAndView对象;再然后分别调用每个拦截器的postHandle方法;最后即使是之前的步骤抛出了异常,也会执行triggerAfterCompletion方法。

MethodInterceptor拦截器

MethodInterceptor是AOP项目中的拦截器,它拦截的目标是方法,即使不是controller中的方法

二者的区别

上面的两种拦截器都能起到拦截的效果,但是他们拦截的目标不一样,实现的机制不同,所以有的时候适用不同的场景。
HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适。当你需要统计请求的响应时间时,MethodInterceptor将不太容易做到,因为它可能跨越很多方法或者只涉及到已经定义好的方法中一部分代码。MethodInterceptor利用的是AOP的实现机制,在本文中只说明了使用方式,关于原理和机制方面介绍的比较少,因为要说清楚这些需要讲出AOP的相当一部分内容。在对一些普通的方法上的拦截HandlerInterceptoer就无能为力了,这时候只能利用AOP的MethodInterceptor。
另外,还有一个跟拦截器类似的东西----Filter。Filter是Servlet规范规定的,不属于Spring框架,也是用于请求的拦截。但是它适合更粗粒度的拦截,在请求前后做一些编解码处理、日志记录等。而拦截器则可以提供更细粒度的,更加灵活的,针对某些请求、某些方法的组合的解决方案。
另外,用过人人网的ROSE框架的人都会非常喜欢它的拦截器功能。因为它实现了全注解的方式,只要在类的名字上加上拦截器的注解即表示这是一个拦截器。而使用这个拦截器的方法或者controller也只需在方法或controller的上面加上这个拦截器的注解。其实这是一个关注点的转变,spring的切面控制在配置文件中,配置文件关注哪些地方需要拦截。而在ROSE中,则是在需要拦截的地方关注我要被谁拦截。

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

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

相关文章

【学习总结】激光雷达与相机外参标定:代码(cam_lidar_calibration)

前段时间尝试了一款激光雷达和相机标定的代码&#xff0c;总结了博客&#xff1a; 【学习总结】激光雷达与相机外参标定&#xff1a;原理与代码 但总觉得那个代码太差劲&#xff0c;而且精度不行&#xff0c;于是又找了些新的代码&#xff0c;体验比之前的好很多&#xff0c;在…

【自然语言处理】主题建模:Top2Vec(理论篇)

主题建模&#xff1a;Top2Vec&#xff08;理论篇&#xff09;Top2Vec 是一种用于 主题建模 和 语义搜索 的算法。它自动检测文本中出现的主题&#xff0c;并生成联合嵌入的主题、文档和词向量。 算法基于的假设&#xff1a;许多语义相似的文档都可以由一个潜在的主题表示。首先…

90后,转行软件测试3年,从月入7000+到月入过万,整理出的这一万字经验分享。

周一发工资了&#xff0c;到手12857.65&#xff0c;美滋滋 今年是我毕业参加工作的第3年&#xff0c;工资终于来到5位数了。上一家公司月薪7000&#xff0c;实际拿到手就6450左右&#xff0c;感觉今年真的是元气满满啊&#xff0c;工资翻倍&#xff0c;良好的人生开端。 想起…

Odoo丨Odoo框架源码研读二:ORM框架与日志

Odoo丨Odoo框架源码研读二&#xff1a;ORM框架与日志 而Odoo在实际开发的大多数场景都是基于它的ORM框架进行的&#xff0c;所以本期我们将带来Odoo框架源码的第二期内容——ORM和日志。 *ORM* Odoo是通过Controller控制器&#xff0c;来控制前后台的交互。上一期我们详细的…

算法专题训练营

动归算法专题 1.拆分词句 是不是,在不在都是可以用动归解决的 状态转义方程不一定都是等式,也有可能是条件 2.三角形 动归算法也不是一定要借助新开空间,也是可以用自己原来的空间 3.背包问题 4.分割回文串-ii 5.不同的子序列 贪心算法专题 只管一步的最优结果, 1.分割平衡…

前缀和差分(C/C++)

目录 1. 前缀和的定义 2. 一维前缀和 2.1 计算公式 2.2 用途 2.3 小试牛刀 3. 二维前缀和 3.1 用途 1. 前缀和的定义 对于一个给定的数列A&#xff0c;他的前缀和数中 S 中 S[ i ] 表示从第一个元素到第 i 个元素的总和。 如下图&#xff1a;绿色区域的和就是前缀和数组…

如何在SpringBoot项目上让接口返回数据脱敏,一个注解即可

1 背景需求是某些接口返回的信息&#xff0c;涉及到敏感数据的必须进行脱敏操作2 思路①要做成可配置多策略的脱敏操作&#xff0c;要不然一个个接口进行脱敏操作&#xff0c;重复的工作量太多&#xff0c;很显然违背了“多写一行算我输”的程序员规范。思来想去&#xff0c;定…

关于数字化营销技术实现之【数据埋点】

1.如何实现数据埋点&#xff1f;小程序数据埋点是指在小程序中收集用户行为数据和业务数据的一种技术手段&#xff0c;以便对用户行为和业务运营进行分析和优化。下面是一些实现小程序数据埋点的方法&#xff1a;使用小程序统计分析工具&#xff1a;小程序平台提供了统计分析工…

约束优化:低维线性时间线性规划算法(Seidel算法)、低维线性时间严格凸二次规划算法

文章目录约束优化&#xff1a;低维线性时间线性规划算法&#xff08;Seidel算法&#xff09;、低维线性时间严格凸二次规划算法带约束优化问题的定义带约束优化问题的分类及时间复杂度低维线性规划问题定义Seidel线性规划算法低维严格凸二次规划问题定义低维情况下的精确最小范…

【LeetCode】剑指 Offer 09. 用两个栈实现队列 p68 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/ 1. 题目介绍&#xff08;09. 用两个栈实现队列&#xff09; 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别…

【大厂高频必刷真题100题】《是子序列吗?》 真题练习第28题 持续更新~

是子序列吗? 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 进阶: 如果有…

火山引擎 DataTester:在广告投放场景下的 A/B 实验实践

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 “我知道在广告上的投资有一半是无用的&#xff0c;但问题是我不知道是哪一半。” ——零售大亨约翰沃纳梅克 这句经典名言&#xff0c;被称为广告界的哥特巴赫猜想…

Python脚本批量下载CDS气象数据

使用Python脚本从 Copernicus Climate Data Store (CDS) 检索气象数据具体地&#xff0c;需要检索变量&#xff08;geopotential、relative_humidity、temperature、u_component_of_wind、v_component_of_wind、vertical_velocity&#xff09;在各种不同的压力水平、不同的日期…

罗克韦尔AB PLC_FactoryTalk无法登录的解决方法

罗克韦尔AB PLC_FactoryTalk无法登录的解决方法 情况说明: 在打开Studio 5000软件时,出现一个弹窗Log On to FactoryTalk - Network,正常情况下输入Windows账户和密码就可以登录成功。 但是却出现了下图所示窗口,其中‘abseme’是Windows账户名,‘WELL’是计算机名称,下图…

SQL零基础入门学习(二)

SQL SELECT 语句 SELECT 语句用于从数据库中选取数据。 结果被存储在一个结果表中&#xff0c;称为结果集。 SQL SELECT 语法 SELECT column1, column2, ... FROM table_name;与 SELECT * FROM table_name;参数说明&#xff1a; column1, column2, …&#xff1a;要选择的…

向上跳空缺口选股公式,选出回补后再启动的标的

一、向上跳空缺口选股公式 思路&#xff1a;先找出缺口&#xff0c;缺口前后有两根K线&#xff0c;缺口低价是前一根K线的最高价&#xff0c;缺口高价是后一根K线的最低价。&#xff08;如上图&#xff09;收盘价低于缺口低价&#xff0c;即实现缺口回补。回补缺口之后&#xf…

“一把梭ViT”来了,谷歌提出可以灵活应对各种图像块尺寸的FlexiViT

原文链接&#xff1a;https://www.techbeat.net/article-info?id4486 作者&#xff1a;seven_ 论文链接&#xff1a; https://arxiv.org/abs/2212.08013 代码链接&#xff1a; https://github.com/google-research/big_vision 视觉Transformer&#xff08;ViT&#xff09;目前…

Linux - 第4节 - Linux进程控制

1.进程创建 1.1.fork函数 在linux中fork函数是非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。#include <unistd.h> pid_t fork(void); 返回值&#xff1a;子进程中返回0&#xff0c;父进程返回子进程id&…

考虑泄流效应的光伏并网点电压系统侧增援调控方法matlab

目录 1主要内容 1.1 泄流效应​编辑 1.2 候选无功补偿站优选方法 1.3 算法步骤 2部分代码 3程序结果 4程序链接 1主要内容 程序主要复现《考虑泄流效应的风电场并网点电压系统侧增援调控方法_于其宜》&#xff0c;将光伏取代风电&#xff0c;考虑某时刻光伏并网的电压增…

3年工作之后是不是还在“点点点”,3年感悟和你分享....

经常都有人问我软件测试前景怎么样&#xff0c;每年也都帮助很多朋友做职业分析和学习规划&#xff0c;也很欣慰能够通过自己的努力帮到一些人进入到大厂。 2023年软件测试行业的发展现状以及未来的前景趋势 最近很多测试人在找工作的时候&#xff0c;明显的会发现功能测试很…