过滤器和监听器

news2024/9/25 15:22:16

1、过滤器Filter

作用是防止SQL注入、参数过滤、防止页面攻击、空参数矫正、Token校验、Session验证、点击率统计等等;

使用Filter的步骤

  1. 新建类,实现Filter抽象类;
  2. 重写init、doFilter、destroy方法;
  3. 在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 {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化逻辑,服务器启动时调用");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截器");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("销毁逻辑,服务器关闭时调用");
    }
}
@ServletComponentScan
@SpringBootApplication
public class SpringbootstudyApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootstudyApplication.class, args);
	}

}

image
image

示例代码:

/**
 * @Author: zhondu
 * @Date: 2023/1/25 18:36
 * @Desc: 过滤器
 */
@Component
public class LogFilter implements Filter {
    public static final Logger logger = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public 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());
        // 还可以打印其他很多信息,请求头之类的,因为这里拿到的是整个request
        long startTime = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        logger.info("-----------LogFilter 结束  耗时:{} ms--------------", System.currentTimeMillis() - startTime);
    }
}

** 执行结果 **
image

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
     */
    @Override
    public 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
     */
    @Override
    public 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 {
    @Resource
    private LogInterceptor logInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 增加过滤器 -- 针对所有的请求 (但是例如登录校验就不是所有的接口都需要校验,例如登录校验是不能校验登录接口本身的)
        registry.addInterceptor(logInterceptor)
                .addPathPatterns("/**") // 针对所有的请求
                .excludePathPatterns("/login"); // 排除掉登录请求-不拦截
    }
}

image

拦截器分为前后两个方法,过滤器只有一个,而且过滤器是容器级别的(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;
    }
}

image

### 区别:
image

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

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

相关文章

演示Ansible中的角色使用方法(ansible roles)

文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径&#xff1a;配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…

使用vue3,vite,less,flask,python从零开始学习硅谷外卖(41-82集)

第41集&#xff1a;这里遇到个大坑&#xff0c;因为这种项目有很多页面&#xff0c;有时候有的页面忘了保存就会出错&#xff0c;还很难排查&#xff0c;浪费了我快半天的时间。可以把vscode的代码自动保存打开&#xff0c;以后就不会踩坑了。 第42集&#xff1a;没啥好说的。 …

判断字符串中的字符的类型isdecimal();isalpha();isdigit();isalnum()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断字符串中的字符的类型 isdecimal()&#xff1b;isalpha()&#xff1b;isdigit()&#xff1b;isalnum() [太阳]选择题 对于代码中isdecimal()和isalnum()输出的结果是? s "ABc123&…

亿级高并发电商项目-- 实战篇 --万达商城项目 十一(编写商品搜索功能、操作商品同步到ES、安装RabbitMQ与Erlang,配置监听队列与消息队列)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

Sandboxie-沙箱软件-Plus版本(Qt)-主框架程序-SandMan.exe-创建语言文件-tr-Qt-语言国际化

文章目录1.功能介绍2.Qt语言国际化3.设置软件的语言版本4.作者答疑1.功能介绍 沙箱软件的增强版本采用Qt架构开发&#xff0c;核心模块与经典版本相同&#xff0c;本文主要介绍SandMan.exe这个主程序代码。在main.cpp这个入口函数里&#xff0c;有主窗口入口&#xff0c;如下所…

2.5|iot冯|方元-嵌入式linux系统开发入门|2.13+2.18

一、 Linux 指令操作题&#xff08;共5题&#xff08;共 20 分&#xff0c;每小题 4分&#xff09;与系统工作、系统状态、工作目录、文件、目录、打包压缩与搜索等主题相关。1.文件1.1文件属性1.2文件类型属性字段的第1个字符表示文件类型&#xff0c;后9个字符中&#xff0c;…

【物联网】智慧农业病虫害精准辨识竞赛思路及代码分享

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 比赛官网: https://www.dataglobal.cn/cmpt/signUpInfo200.html 任务描述 请参赛者设计智慧农业病虫害检测系统&#xff0c;给出一体化问题解决方案&#xff0c;鼓励参赛选手结合某一果园/农作物实际情况建立…

使用 URLSearchParams 解析和管理URL query参数

介绍 首先 URLSearchParams是一个构造函数&#xff0c;会生成一个URLSearchParams对象&#xff0c;参数类型&#xff1a; 不传 &#xff5c; string &#xff5c; object &#xff5c; URLSearchParams&#xff0c; 并且遇到特殊字符它会自动帮我们encode 和 decode const ur…

Java模块化概述

3 模块化 3.1 模块化概述 Java语言随着这些年的发展已经成为了一]影响深远的编程语言&#xff0c;无数平台,系统都采用Java语言编写。但是&#xff0c;伴随着发展&#xff0c;Java也越来越庞大&#xff0c;逐渐发展成为-门“臃肿” 的语言。而且&#xff0c;无论是运行个大型的…

Vulnhub 渗透练习(五)—— lazysysadmin1

环境搭建 下载链接 vmware 打开靶机&#xff0c;nat 网络适配&#xff0c;攻击机同样。 信息收集 一个一个的看过去&#xff0c;这边就不贴图了。 漏洞挖掘 用 kail 的 wpscan 扫一下 wordpress&#xff0c;没发现漏洞。 ┌──(geng㉿geng)-[~] └─$ wpscan --url http…

【Linux06-基础IO】4.5万字的基础IO讲解

前言 本期分享基础IO的知识&#xff0c;主要有&#xff1a; 复习C语言文件操作文件相关的系统调用文件描述符fd理解Linux下一切皆文件缓冲区文件系统软硬链接动静态库的理解和制作动静态编译 博主水平有限&#xff0c;不足之处望请斧正&#xff01; C语言文件操作 #再谈文件…

SQLSERVER2019安装步骤过程

第一步官网下载SQLSERVER软件包 目前官网只能下载最新版本2022版本。 通过迅雷下载网址 SQL Server 2019 Enterprise (x64) - DVD (Chinese-Simplified)企业版 ed2k://|file|cn_sql_server_2019_enterprise_x64_dvd_2bfe815a.iso|1632086016|58C258FF0F1D006DD3C1F5F17AF3E…

ELK_Elasticsearch环境搭建

目录 一、Windows安装elasticsearch 1、安装JDK 2、下载和解压 3、配置文件 4、启动 5、检查ES是否启动成功 6、浏览器访问 二、 Windows安装Kibana 一、Windows安装elasticsearch 1、安装JDK 安装JDK&#xff0c;至少1.8.0_73以上版本&#xff0c;验证&#xff1a;j…

dbForge Source Control for SQL Server 2.5.X Crack

SQL Server功能概述 的 dbForge 源代码管理 dbForge Source Control for SQL Server 是一个可视化的 SSMS 插件&#xff0c;具有简单易用的界面&#xff0c;可帮助您轻松跟踪 SQL Server 数据库对象中的更改内容、更改时间和原因。该工具使您能够将数据库连接到多个版本控制系统…

【Python学习笔记】40.Python3 SMTP发送邮件

前言 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;由它来控制信件的中转方式。 Python3 SMTP发送邮件 python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了…

CSS基础选择器,你认识多少?

前言在上一文初识CSS中&#xff0c;我们了解到了其格式&#xff1a;选择器{ }在初步尝试使用时&#xff0c;我们笼统的直接输入了p { }以选择p标签来对其操作&#xff0c;而这一章节里&#xff0c;我们再进一步探索有关基础选择器的相关内容&#xff0c;理解选择器的作用。选择…

2019蓝桥杯真题平方序列(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小明想找到两个正整数 X 和 Y&#xff0c;满足2019<X<Y;2019^2, X^2, Y^2组成等差数列。 请你求出在所有可能的解中&#xff0c;XY 的最小值是多少&#xff1f…

QT(17)- QNetworkAccessManager

QT&#xff08;17&#xff09;- QNetworkAccessManager1 简介2 公有类型3 函数3.1 addStrictTransportSecurityHosts3.2 autoDeleteReplies3.3 cache3.4 clearAccessCache3.5 clearConnectionCache3.6 connectToHost3.7 connectToHostEncrypted3.8 cookieJar3.9 deleteResource…

Metasploit框架基础(一)

文章目录前言一、基础认知二、批量POC/EXP的构想三、poc检测框架的简单实现四、xray五、Meatsploit框架参考前言 Metasploit 一款渗透测试框架漏洞利用的集合与构建和定制满足你的需求的基础漏洞利用和验证的工具 这几个说法都是百度或者官方文档中出现的手法&#xff0c;说…

ASEMI代理FGH60N60SFD,安森美FGH60N60SFD原装IGBT

编辑-Z 安森美FGH60N60SFD原装IGBT参数&#xff1a; 型号&#xff1a;FGH60N60SFD 集电极到发射极电压&#xff08;VCES&#xff09;&#xff1a;600V 栅极到发射极电压&#xff08;VGES&#xff09;&#xff1a;20V 收集器电流&#xff08;IC&#xff09;&#xff1a;120…