过滤器和监听器
1、过滤器Filter
作用是防止SQL注入、参数过滤、防止页面攻击、空参数矫正、Token校验、Session验证、点击率统计等等;
使用Filter的步骤
- 新建类,实现Filter抽象类;
- 重写init、doFilter、destroy方法;
- 在SpringBoot入口中添加注解@ServletComponentScan,以注册Filter;
注意:通过@Order注解设置过滤器的执行顺序,越小的越先被执行;
import org.springframework.core.annotation.Order;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;/*** @ClassName: FilterDemo* @Author: 中都* @Date: 2021/12/29 22:11* @Description: 过滤器*/
@Order(1)
@WebFilter(filterName = "FilterDemo",urlPatterns = "/*")
public class FilterDemo implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("初始化逻辑,服务器启动时调用");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("拦截器");filterChain.doFilter(servletRequest,servletResponse);}@Overridepublic void destroy() {System.out.println("销毁逻辑,服务器关闭时调用");}
}
@ServletComponentScan
@SpringBootApplication
public class SpringbootstudyApplication {public static void main(String[] args) {SpringApplication.run(SpringbootstudyApplication.class, args);}}
示例代码:
/*** @Author: zhondu* @Date: 2023/1/25 18:36* @Desc: 过滤器*/
@Component
public class LogFilter implements Filter {public static final Logger logger = LoggerFactory.getLogger(LogFilter.class);@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// filterChain是过滤器执行链,因为可以有多个过滤器的// 打印请求信息HttpServletRequest request = (HttpServletRequest) servletRequest;logger.info("-----------LogFilter 开始--------------");// 接口和方法类型(get post)logger.info("请求地址:{} {}", request.getRequestURL().toString(), request.getMethod());logger.info("远程地址:{}", request.getRemoteAddr());// 还可以打印其他很多信息,请求头之类的,因为这里拿到的是整个requestlong startTime = System.currentTimeMillis();filterChain.doFilter(servletRequest, servletResponse);logger.info("-----------LogFilter 结束 耗时:{} ms--------------", System.currentTimeMillis() - startTime);}
}
** 执行结果 **
2、监听器
监听对象的增删改查等操作,然后做出相应处理,用户统计在线人数、在线用户、系统加载时的信息初始化等等;
/*** @Author: zhondu* @Date: 2023/1/26 10:18* @Desc: 拦截器 Spring特有的,常用于登录校验 权限校验 请求日志打印*/
@Component
public class LogInterceptor implements HandlerInterceptor {public static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);/*** 拦截器 -- 请求进入方法之前的拦截处理* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {logger.info("-----------LogInterceptor 开始--------------");// 接口和方法类型(get post)logger.info("请求地址:{} {}", request.getRequestURL().toString(), request.getMethod());logger.info("远程地址:{}", request.getRemoteAddr());long startTime = System.currentTimeMillis();request.setAttribute("requestStartTime",startTime);// 返回true 才会继续走,否则就直接结束了,所以可以用于 登录校验 权限校验return true;}/*** 拦截器 -- 走完方法之后返回前端的拦截处理* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {long startTime = (Long) request.getAttribute("requestStartTime");logger.info("-----------LogInterceptor 结束 耗时:{} ms--------------", System.currentTimeMillis() - startTime);}
}
拦截器还需要加一个全局配置的:
import com.zhondu.wiki.interceptor.LogInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import javax.annotation.Resource;/*** @Author: zhondu* @Date: 2023/1/26 10:26* @Desc:*/
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {@Resourceprivate LogInterceptor logInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 增加过滤器 -- 针对所有的请求 (但是例如登录校验就不是所有的接口都需要校验,例如登录校验是不能校验登录接口本身的)registry.addInterceptor(logInterceptor).addPathPatterns("/**") // 针对所有的请求.excludePathPatterns("/login"); // 排除掉登录请求-不拦截}
}
拦截器分为前后两个方法,过滤器只有一个,而且过滤器是容器级别的(Tomcat netty等),拦截器是应用级别的,例如web应用
3、AOP
AOP也可以打印参数相关的信息,但是与过滤器拦截器不同,他依靠的不是request,而是连接点JoinPoint,
需要引入依赖:
<!--AOP--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.70</version></dependency>
package com.zhondu.wiki.aspect;import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;/*** @Author: zhondu* @Date: 2023/1/26 11:49* @Desc: AOP*/
@Aspect
@Component
public class LogAspect {public static final Logger logger = LoggerFactory.getLogger(LogAspect.class);// 定义一个切点 监控所有的controller@Pointcut("execution(public * com.zhondu.*.controller..*Controller.*(..))")public void controllerPointcut() {}// 前置通知@Before("controllerPointcut()")public void doBefore(JoinPoint joinPoint) throws Throwable {// 开始打印请求日志ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();Signature signature = joinPoint.getSignature();String name = signature.getName();// 打印请求信息logger.info("------------- 开始 -------------");logger.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());logger.info("类名方法: {}.{}", signature.getDeclaringTypeName(), name);logger.info("远程地址: {}", request.getRemoteAddr());// 打印请求参数Object[] args = joinPoint.getArgs();// LOG.info("请求参数: {}", JSONObject.toJSONString(args));Object[] arguments = new Object[args.length];for (int i = 0; i < args.length; i++) {if (args[i] instanceof ServletRequest|| args[i] instanceof ServletResponse|| args[i] instanceof MultipartFile) {continue;}arguments[i] = args[i];}// 排除字段,敏感字段或太长的字段不显示String[] excludeProperties = {"password", "file"};PropertyPreFilters filters = new PropertyPreFilters();PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();excludefilter.addExcludes(excludeProperties);logger.info("请求参数: {}", JSONObject.toJSONString(arguments, excludefilter));}/*** 环绕通知* @param proceedingJoinPoint* @return* @throws Throwable*/@Around("controllerPointcut()")public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = proceedingJoinPoint.proceed();// 排除字段,敏感字段或太长的字段不显示String[] excludeProperties = {"password", "file"};PropertyPreFilters filters = new PropertyPreFilters();PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();excludefilter.addExcludes(excludeProperties);logger.info("返回结果: {}", JSONObject.toJSONString(result, excludefilter));logger.info("------------- 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);return result;}
}
### 区别:
相关文章:

过滤器和监听器
1、过滤器Filter 作用是防止SQL注入、参数过滤、防止页面攻击、空参数矫正、Token校验、Session验证、点击率统计等等; 使用Filter的步骤 新建类,实现Filter抽象类;重写init、doFilter、destroy方法;在SpringBoot入口中添加注解…...
Acwing 第 91 场周赛
Powered by:NEFU AB-IN B站直播录像! Link 文章目录Acwing 第 91 场周赛A AcWing 4861. 构造数列题意思路代码B AcWing 4862. 浇花题意思路代码C AcWing 4863. 构造新矩阵题意思路代码Acwing 第 91 场周赛 A AcWing 4861. 构造数列 题意 略 思路 将每个数的每一位…...

JavaEE|套接字编程之UDP数据报
文章目录一、DatagramSocket API构造方法常用方法二、DatagramPacket API构造方法常用方法E1:回显服务器的实现E2:带有业务逻辑的请求发送一、DatagramSocket API 在操作系统中,把socket对象当成了一个文件处理。等价于是文件描述符表上的一项。 普通的文件…...

如何使用Python创建一个自定义视频播放器
目录 1、安装vlc的64位版本。 2、安装python的vlc模块。 3、编写如下代码,包含了播放,暂停,停止、音量控制功能。 4、来看一看运行结果。 5、如果遇到播放不了的问题,解决方式如下: 这个例子使用VLC作为视频播放器…...
Elasticsearch进行优化-使用索引拆分(Split)和索引收缩(shrink )
一、索引拆分和收缩的场景 在Elasticsearch集群部署的初期我们可能评估不到位,导致分配的主分片数量太少,单分片的数据量太大,导致搜索时性能下降,这时我们可以使用Elasticsearch提供的Split功能对当前的分片进行拆分,…...
数论 —— 高斯记号(Gauss mark)
定义 数学上,高斯记号(Gauss mark)是指对取整符号和取小符号的统称,用于数论等领域。 设 x∈Rx \in \textbf{R}x∈R,用 [x][x][x] 表示不超过 xxx 的最大整数。也可记作 [x][x][x]。设 x∈Rx \in \textbf{R}x∈R&…...
【随笔】程序员眼中的 CPU,“没有灵魂的躯体”
引言 先引用一段比较有意思的论述: 现实中每个人是由两部分构成,灵魂和躯体,灵魂依附于躯体游走于世间,现实中我们面对的每个人其实面对的是其灵魂而非肉体,肉体不过是表象而已。 灵魂本性乃一恶物,寄生于…...

算法的时间复杂度
算法在编写成可执行程序后,运行时需要消耗时间资源和空间(内存)资源,因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的。 时间复杂度主要衡量一个算法运行的快慢,而空间复杂度主要衡量一个算法运…...
华为OD机试 - 叠放书籍(Python) | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 寻找路径 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 五键键盘 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - IPv4 地址转换成整数 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 对称美学 | 备考思路,刷题要点,答疑 …...

进程间通信(重点)
概念 进程是一个独立的资源分配单元,不同进程之间的资源是独立的进程并非孤立的,不同进程需要进行信息的交互和状态的传递,因此需要进程之间的通信【IPC: Inter processes communication】 如qq聊天,qq在每个人的手机上是独立的…...

Reverse入门[不断记录]
文章目录前言一、[SWPUCTF 2021 新生赛]re1二、[SWPUCTF 2021 新生赛]re2三、[GFCTF 2021]wordy[花指令]四、[NSSRound#3 Team]jump_by_jump[花指令]五、[NSSRound#3 Team]jump_by_jump_revenge[花指令]前言 心血来潮,想接触点Reverse,感受下Reverse&am…...

如何实现外网访问内网ip?公网端口映射或内网映射来解决
本地搭建服务器应用,在局域网内可以访问,但在外网不能访问。如何实现外网访问内网ip?主要有两种方案:路由器端口映射和快解析内网映射。根据自己本地网络环境,结合是否有公网IP,是否有路由权限,…...

[acwing周赛复盘] 第 91 场周赛20230218
[acwing周赛复盘] 第 91 场周赛20230218 一、本周周赛总结二、 4861. 构造数列1. 题目描述2. 思路分析3. 代码实现三、4862. 浇花1. 题目描述2. 思路分析3. 代码实现四、4863. 构造新矩阵1. 题目描述2. 思路分析3. 代码实现六、参考链接一、本周周赛总结 这周挺难的。T1 贪心分…...
蓝桥12届
小蓝准备用 256MB 的内存空间开一个数组,数组的每个元素都是 32 位 二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间,请问 256MB 的空间可以存储多少个 32 位二进制整数?1MB 1024KB 1KB 1024字节(byte) 1字节 8位…...
华为OD机试 - 斗地主(JS)
斗地主 题目 斗地主起源于湖北十堰房县, 据传是一位叫吴修全的年轻人根据当地流行的扑克玩法“跑得快”改编的, 如今已风靡整个中国,并流行于互联网上 牌型: 单顺,又称顺子,最少5张牌,最多12张牌(3...A),不能有2, 也不能有大小王,不计花色 例如:3-4-5-7-8,7-8-9-1…...

【MyBatis】| MyBatis的注解式开发
目录 一:MyBatis的注解式开发 1. Insert注解 2. Delete注解 3. Update注解 4. Select注解 5. Results注解 一:MyBatis的注解式开发 MyBatis中也提供了注解式开发⽅式,采⽤注解可以减少Sql映射⽂件的配置。 当然,使⽤注…...

python自制PDF转换.PNG格式图片(按每页生成图片完整源码)小工具!
使用PyQt5应用程序制作PDF转换成图片的小工具,可以导入PDF文档后一键生成对应的PNG图片。 PDF图片转换小工具使用的中间件: python版本:3.6.8 UI应用版本:PyQt5 PDF文件操作非标准库:PyPDF2 PNG图片生成库࿱…...

Go 数组和切片反思
切片的底层数据结构是数组,所以,切片是基于数组的上层封装,使用数组的场景,也完全可以使用切片。 类型比较 我看到 go 1.17 有对切片和数组转换的优化,禁不住纳闷,有什么场景是必须数组来完成的呢&#x…...

win10电脑性能优化设置
win10电脑性能优化设置 目录win10电脑性能优化设置1.桌面图标显示2.wini2.1 “系统”2.1.1专注助手 关2.1.2 电源和睡眠 设置为从不2.1.3 存储 开2.2 网络和Internet2.3 个性化2.4 应用2.5 账户2.6 游戏2.7 隐私墨迹书写和键入个性化:关活动历史记录:全部…...

作为初学者必须要了解的几种常用数据库!
现在已经存在了很多优秀的商业数据库,如甲骨文(Oracle)公司的 Oracle 数据库、IBM 公司的 DB2 数据库、微软公司的 SQL Server 数据库和 Access 数据库。同时,还有很多优秀的开源数据库,如 MySQL 数据库,Po…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...