[Spring]拦截器

news/2024/9/22 14:11:24/文章来源:https://www.cnblogs.com/DCFV/p/18425224

Interceptor 介绍

image

拦截器(Interceptor)同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。
你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置......
在 Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或多个)。
Spring Interceptor是一个非常类似于Servlet Filter 的概念 。

Interceptor 作用

  1. 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等;
  2. 权限检查:如登录检测,进入处理器检测是否登录;
  3. 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如 Apache 也可以自动记录)
  4. 通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现。

自定义 Interceptor

如果你需要自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类,并且需要重写下面下面 3 个方法:

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

  • postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 方法在当前请求处理完成之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。

  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法需要在当前对应的 Interceptor 类的 postHandler 方法返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理。

接下来结合实际代码进行学习。
LogInterceptor 类:

public class LogInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {long startTime = System.currentTimeMillis();System.out.println("\n-------- LogInterception.preHandle --- ");System.out.println("Request URL: " + request.getRequestURL());System.out.println("Start Time: " + System.currentTimeMillis());request.setAttribute("startTime", startTime);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("\n-------- LogInterception.postHandle --- ");System.out.println("Request URL: " + request.getRequestURL());}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("\n-------- LogInterception.afterCompletion --- ");long startTime = (Long) request.getAttribute("startTime");long endTime = System.currentTimeMillis();System.out.println("Request URL: " + request.getRequestURL());System.out.println("End Time: " + endTime);System.out.println("Time Taken: " + (endTime - startTime));}
}

OldLoginInterceptor 类:

public class OldLoginInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("\n-------- OldLoginInterceptor.preHandle --- ");System.out.println("Request URL: " + request.getRequestURL());System.out.println("Sorry! This URL is no longer used, Redirect to /admin/login");response.sendRedirect(request.getContextPath()+ "/admin/login");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("\n-------- OldLoginInterceptor.postHandle --- ");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("\n-------- OldLoginInterceptor.afterCompletion --- ");}
}

配置拦截器 :

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LogInterceptor());registry.addInterceptor(new OldLoginInterceptor()).addPathPatterns("/admin/oldLogin");registry.addInterceptor(new AdminInterceptor()).addPathPatterns("/admin/*").excludePathPatterns("/admin/oldLogin");}
}

LogInterceptor 拦截器用于拦截所有请求;
OldLoginInterceptor 用来拦截链接 “ / admin / oldLogin”,它将重定向到新的 “ / admin / login”。;
AdminInterceptor用来拦截链接 “/admin/*”,除了链接 “ / admin / oldLogin”。

自定义 Controller 验证拦截器

@Controller
public class LoginController {@RequestMapping("/index")public String index(Model model){return "index";}@RequestMapping(value = "/admin/login")public String login(Model model){return "login";}
}

同时依赖 thymeleaf 模板构建两个页面。
index.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8" /><title>Spring Boot Mvc Interceptor example</title>
</head><body>
<div style="border: 1px solid #ccc;padding: 5px;margin-bottom:10px;"><a th:href="@{/}">Home</a>   |   <a th:href="@{/admin/oldLogin}">/admin/oldLogin (OLD URL)</a>
</div><h3>Spring Boot Mvc Interceptor</h3><span style="color:blue;">Testing LogInterceptor</span>
<br/><br/>See Log in Console..</body>
</html>

login.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8" /><title>Spring Boot Mvc Interceptor example</title>
</head>
<body><div style="border: 1px solid #ccc;padding: 5px;margin-bottom:10px;"><a th:href="@{/}">Home</a>   |   <a th:href="@{/admin/oldLogin}">/admin/oldLogin (OLD URL)</a>
</div><h3>This is Login Page</h3><span style="color:blue">Testing OldLoginInterceptor & AdminInterceptor</span>
<br/><br/>
See more info in the Console.</body></html>

运行程序并测试效果
一切准备完毕,启动该项目。打开网址: http://localhost:8080/index

关于该请求在后台的执行过程,用图解的方式进行展示:

如果此时点击 /admin/oldLogin (OLD URL) 或者在网址栏输入:http://localhost:8080/admin/oldLogin

控制台打印结果:

-------- LogInterception.preHandle --- 
Request URL: http://localhost:8080/admin/oldLogin
Start Time: 1576329730709-------- OldLoginInterceptor.preHandle --- 
Request URL: http://localhost:8080/admin/oldLogin
Sorry! This URL is no longer used, Redirect to /admin/login-------- LogInterception.afterCompletion --- 
Request URL: http://localhost:8080/admin/oldLogin
End Time: 1576329730709
Time Taken: 0-------- LogInterception.preHandle --- 
Request URL: http://localhost:8080/admin/login
Start Time: 1576329730716-------- AdminInterceptor.preHandle --- -------- AdminInterceptor.postHandle --- -------- LogInterception.postHandle --- 
Request URL: http://localhost:8080/admin/login-------- AdminInterceptor.afterCompletion --- -------- LogInterception.afterCompletion --- 
Request URL: http://localhost:8080/admin/login
End Time: 1576329730718
Time Taken: 2

image

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

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

相关文章

win10x64位+nmake编译geos3.7.1

说明:使用nmake进行编译,最新的geos3.13似乎已经不能用nmake进行编译了,不过3.7.1已经够用了。 1、 解压geos-3.7.1,定位到根目录下的namke.opt文件,这个文件控制着nmake编译的一些参数。 2、 打开nmake.opt,找到如下片段: ###########################################…

Nuxt Kit API :路径解析工具

title: Nuxt Kit API :路径解析工具 date: 2024/9/22 updated: 2024/9/22 author: cmdragon excerpt: 摘要:本文介绍了Nuxt Kit中用于解析路径的API工具,包括resolvePath、resolveAlias、findPath和createResolver。这些工具助力开发者处理模块路径、别名、文件扩展名,提…

使用GPU 加速 Polars:高效解决大规模数据问题

Polars 最近新开发了一个可以支持 GPU 加速计算的执行引擎。这个引擎可以对超过 100GB 的数据进行交互式操作能。本文将详细讨论 Polars 中DF的概念、GPU 加速如何与 Polars DF协同工作,以及使用新的 CUDA 驱动执行引擎可能带来的性能提升。 https://avoid.overfit.cn/post/b…

我的网站集成ElasticSearch初体验

最近,我给我的网站(https://www.xiandanplay.com/)尝试集成了一下es来实现我的一个搜索功能,因为这个是我第一次了解运用elastic,所以如果有不对的地方,大家可以指出来,话不多说,先看看我的一个大致流程 这里我采用的sdk的版本是Elastic.Clients.Elasticsearch, Ver…

Flipper Zero极客的便携式多功能工具设备

官网:Flipper Zero — 极客的便携式多功能工具设备 Flipper Zero是近两年比较热门的硬件工具,官方固件主要涵盖的功能为Sub-Ghz,125kHz,NFC,红外。 基本信息资料都可以在官方网站找到比较详细的文档解释。本篇主要是一个基础入门,这系列也是给自己学习此硬件一个上手研究…

C盘扩容免费工具

1.diskgenius 下载 https://www.diskgenius.cn/download.php 解压即可使用,无需安装 2.下载 安装Windows_PE环境 https://www.diskgenius.cn/help/windows_aik_adk_installnotes.php?Version=0A000000&Build=22631&Lang=936 官方软件,安全五毒 3.运行diskgenius ,点…

Leetcode 2464. 有效分割中的最少子数组数目

1.题目基本信息 1.1.题目描述 给定一个整数数组 nums。 如果要将整数数组 nums 拆分为 子数组 后是 有效的,则必须满足: 每个子数组的第一个和最后一个元素的最大公约数 大于 1,且 nums 的每个元素只属于一个子数组。 返回 nums 的 有效 子数组拆分中的 最少 子数组数目。如果…

debian 系统服务器搭建

在VMWare中安装Debian12.5虚拟机后, 需要开始进行一些设置:1. 先设置网络模式为桥接模式, 这样和主机在同一个局域网,方便后续ssh连接 2. 第1步设置后,重启Debian,登录后, 查看IP和Mac地址, 192.168.31.16,00:0c:29:6c:31:e6 3. 设置路由器,固定IP: 192.168.31.105。 …

初识算法

持续更新数据结构与算法专题,欢迎关注.......1.1 什么是算法? 定义 在数学和计算机科学领域,算法是一系列有限的严谨指令,通常用于解决一类特定问题或执行计算In mathematics and computer science, an algorithm (/ˈlɡərɪəm/) is a finite sequence of rigorous inst…

解锁Java线程池:实战技巧与陷阱规避

线程池作为初学者常感困惑的一个领域,本次“巧手打字通课堂”将深入剖析其中几个最为普遍的误区。专业在线打字练习网站-巧手打字通,只输出有价值的知识。一 前言 线程池作为初学者常感困惑的一个领域,本次“巧手打字通课堂”将深入剖析其中几个最为普遍的误区。为了更清晰地…

FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播

​之前的文章《利用RTMP协议构建电脑与手机的直播Demo》介绍了如何使用RTMP Streamer实现完整的RTMP直播流程,另一篇文章《利用SRT协议构建手机APP的直播Demo》介绍了如何使用SRT Streamer实现完整的SRT直播流程,接下来介绍如何使用EasyPusher-Android实现完整的RTSP直播流程…

小飞机配置

小飞机配置把两个文件的文件复制到小飞机的安装路径中小飞机路径:打开文件所在的位置将MSI Afterburner中的文件复制找到RTSS安装路径RTSS设置中文小飞机监控设置选择自己需要显示内容进行OSD显示