过滤器和监听器
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…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
