WEB三大组件之Filter

在很多项目中通常需要用到filter来实现用户身份识别,并将识别出来的用户信息,保存到ThreadLocal对应的上下文,这样在后续的请求链路中,在任何地方都可以直接获取当前的登录用户了。

来看一下Java WEB三大组件之一的过滤器Filter,是如何在技术派中发挥作用的

使用场景

实现类路径:com/github/paicoding/forum/web/hook/filter/ReqRecordFilter.java

1.Filter基础知识点

来了解一下Filter的基础把。

Filter称为过滤器,主要用来拦截http请求,来做一些其他的事情

流程说明

一个http请求过来之后

  •         首先进入filter,执行相关的业务逻辑
  •         若判定通行,则进入Servlet逻辑,Servlet执行完毕后,又返回Filter,最后在返回给请求方
  •         判定失败,直接返回,不需要将请求发给Servlet

应用场景

通过上面的流程,可以推算下具体的使用场景:

  •         在filter层,来获取用户的身份
  •         可以考虑在filter层做一些常规的校验(如参数校验。referer校验、权限控制等)
  •         可以在filter层做运维、安全防护相关的工作(如全链路打点,可以在filter层分配一个traceId;也可以在这一层做限流等)

2. 实现说明:

filter的基本使用比较简单,实现Filter接口即可,如;

@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "reqRecordFilter", asyncSupported = true)
public class ReqRecordFilter implements Filter {private static Logger REQ_LOG = LoggerFactory.getLogger("req");/*** 返回给前端的traceId,用于日志追踪*/private static final String GLOBAL_TRACE_ID_HEADER = "g-trace-id";@Autowiredprivate GlobalInitService globalInitService;@Autowiredprivate StatisticsSettingService statisticsSettingService;@Overridepublic void init(FilterConfig filterConfig) {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {long start = System.currentTimeMillis();HttpServletRequest request = null;StopWatch stopWatch = new StopWatch("请求耗时");try {stopWatch.start("请求参数构建");request = this.initReqInfo((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);stopWatch.stop();stopWatch.start("cors");CrossUtil.buildCors(request, (HttpServletResponse) servletResponse);stopWatch.stop();stopWatch.start("业务执行");filterChain.doFilter(request, servletResponse);stopWatch.stop();} finally {stopWatch.start("输出请求日志");buildRequestLog(ReqInfoContext.getReqInfo(), request, System.currentTimeMillis() - start);// 一个链路请求完毕,清空MDC相关的变量(如GlobalTraceId,用户信息)MdcUtil.clear();ReqInfoContext.clear();stopWatch.stop();if (!isStaticURI(request) && !EnvUtil.isPro()) {log.info("{} - cost:\n{}", request.getRequestURI(), stopWatch.prettyPrint(TimeUnit.MILLISECONDS));}}}@Overridepublic void destroy() {}

上面有三个方法:

  •         init: 初始化执行
  •         destory: 销毁时执行
  •         dofilter: 重点关注这个,filter规则命中请求,都会走进来

                三个参数,注意第三个FilterChain,这里是经典的责任链模式

                执行filterChain.doFilter(request, servletResponse); 表示会继续将请求执行下去;若不执行这一句,表示这一次的http请求到此为止,后面免得不走下去了。

3.filter注册

过滤注册到Spring容器有多种使用姿势,除上面使用的@WebFilter之外还有其他的使用姿势。

3.1 WebFilter注解

使用WebFilter注解,标注到实现自己额的过滤器上,有几个参数需要注意,其中urlPatterns最为常用,表示这个filter使用与那些url请求(默认场景下全部都被拦截)

属性名 

类型

描述

filterNameString指定过滤器的name属性,等价于<filter-name>

value

String[]该属性等价于urlPatterns属性。但是两者不应该同时使用。
urlPatternsString[]指定一组过滤器的URL匹配模式。等价于<url-pattern>标签
servletNamesString[]

指定过滤器将应用于哪些Servlet。取值是@WebServlet中的name属性的取值,或者是web.xml中<servlet-name>的取值

dispatcherTypesDispatcherTypes指定过滤器的转发模式。具体取值包括: ASYNC、ERROR、FORWARD、INCLUDE、REQUEST
initParamsWebInitParm[]指定一组过滤器初始化参数。等价于<init-param>标签
asyncSupportedboolean声明过滤器是否支持异步操作模式,等价于<async-supported>标签
descriptionString该过滤器的描述信息,等价于<description>
displayNameString该过滤器的显示名,通常配合工具使用,等价于<display-name>

使用这个注解时,请注意,需要在启动类/配置类添加@ServletComponentScan注解来启用

如:

3.2 FilterRegistrationBean

上面这一种比较简单,但是再指定Filter的优先级的时候比较麻烦,不如下面这种方式简单

4.实例说明

接下来我们看一下,filter在技术派中的具体表现,干了那几件事:

身份识别 ,并保存身份到ReqInfoContext上下文中:

记录请求记录:

Filter实现请求日志记录-CSDN博客等。

请求日志的case:

小结

1. Filter使用

自定义Filter的实现

        实现Filter接口

        doFilter方法中,显示调用chain.doFilter(request , response); 表示请求继续;否则表示请求被过滤。

注册生效

@ServletComponentScan自动扫描带有@WebFilter注解的Filter

创建Bean: FilterRegistrationBean来包装自定义的Filter

2. IoC/DI

在SpringBoot中Filter可以和一般的Bean一样使用,直接通过Autowired注入其依赖的Spring Bean对象。

3.优先级

通过创建FilterRegistrationBean的时候指定优先级,如下

此外注意,@WebFilter申明的Filter,优先级为2147483647(优先级最低)

@Order注解不能指定Filter优先级

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

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

相关文章

L2-042 老板的作息表(PTA)

文章目录 L2-042 老板的作息表题目描述sort排序函数 L2-042 老板的作息表 题目描述 新浪微博上有人发了某老板的作息时间表&#xff0c;表示其每天 4:30 就起床了。但立刻有眼尖的网友问&#xff1a;这时间表不完整啊&#xff0c;早上九点到下午一点干啥了&#xff1f; 本题就…

UnityShader:IBL

效果&#xff1a; 实现&#xff1a; Shader "MyShader/IBL" {Properties{_CubeMap ("环境贴图", Cube) "white" {}_Exposure("曝光",float)1.0_Color("颜色",color)(1,1,1,1)_NormalMap("法线贴图",2d)"bu…

Python——pgzero游戏打包exe执行时报错

Python——pgzero游戏打包exe执行时报错 记录一次使用 pgzero 开发游戏&#xff0c;使用 pyinstaller 打包时报错 目录结构&#xff1a; 1. 第一次报错 打包指令&#xff1a; pyinstaller -Fw .\code.py结果打开报错 报错如下&#xff1a; Traceback (most recent call…

【Web】记录[长城杯 2022 高校组]b4bycoffee题目复现

目录 前言 环境准备 简单分析 EXP(两种打法) 生成Payload 恶意类 ①Spring命令执行回显类 ②Filter型内存马 前言 本地jar包运行打通了&#xff0c;远程500&#xff0c;nss靶机有问题&#xff0c;换了bugku就可( 主要记录下做题过程&#xff0c;纯菜狗&#xff0c;小…

Linux——开发工具yum与vim

Linux——开发工具yum与vim 文章目录 Linux——开发工具yum与vim一、Linux 软件包管理器-yum1.1 什么是软件包1.2 yum的使用 二、linux下的编辑器-vim2.1 vim的基本概念2.2 vim的基本操作插入模式下的基本命令底行模式下的基本指令 2.3 vim的配置 一、Linux 软件包管理器-yum …

8-图像缩放

其实&#xff0c;就是开辟一个zoomwidth&#xff0c;zoomheight的内存&#xff0c;再分别赋值即可。 void CDib::Scale(float xZoom, float yZoom) { //指向原图像指针 LPBYTE p_data GetData(); //指向原像素的指针 LPBYTE lpSrc; //指向缩放图像对应像素的指针 LPBYTE lpDs…

数据结构——lesson8二叉树的实现

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

论文阅读——BLIP

BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation &#xff08;1&#xff09;单模态编码器&#xff0c;它分别对图像和文本进行编码。图像编码器用ViT&#xff0c;并使用附加的 [CLS] 标记来表示全局图像特征。文本…

springcloud:4.1 GateWay

概述 Gateway 简介 Spring Cloud Gateway基于Spring 5.0、SpringBoot 2.0和Project Reactor等技术开发 旨在为微服务架构提供一种简单有效的、统一的API路由管理方式&#xff0c;并为微服务架构提供安全、监控、指标和弹性等功能 其目标是替代Zuul特点 易于编写谓词和过滤器&…

解决谷歌浏览器最新chrome94版本CORS跨域问题

项目场景&#xff1a; 谷歌浏览器升级到chrome94版本出现CORS跨域问题 问题描述 解决谷歌浏览器最新chrome94版本CORS跨域问题。 CORS跨域问题&#xff1a; 升级谷歌浏览器最新chrome94版本后&#xff0c;提示Access to XMLHttpRequest at ‘http://localhost:xxxx/api’ fro…

zabbix企业微信接入结合海螺问问编写的shell脚本

前言 博客懒得写详细了&#xff0c;视频剪的累死了&#xff0c;看视频就好了 白帽小丑的个人空间-白帽小丑个人主页-哔哩哔哩视频 shell脚本 #!/bin/bash #set -x CorpID"" #我的企业下面的CorpID Secret"" #创建的应用那…

C到C++的敲门砖-1

文章目录 关键字命名空间输入和输出缺省参数函数重载 关键字 相较于C语言32个关键字&#xff1a; autodoubleintstructbreakelselongswitchcaseenumregistertypedefcharexternreturnunionconstfloatshortunsignedcontinueforsignedvoiddefaultgotosizeofvolatiledoifwhilesta…

用python写网络爬虫:2.urllib库的基本用法

文章目录 urllib库抓取网页data参数timeout参数更灵活地配置参数登录代理Cookies 参考书籍 建议新入门的小伙伴先看我同一专栏的文章&#xff1a;用python写网络爬虫&#xff1a;1.基础知识 urllib库 urllib是python中一个最基础的HTTP库&#xff0c;一般是内置的&#xff0c;…

2024年 前端JavaScript Web APIs 第三天 笔记

3.1-表单全选反选案例 <!DOCTYPE html><html><head lang"en"><meta charset"UTF-8"><title></title><style>* {margin: 0;padding: 0;}table {border-collapse: collapse;border-spacing: 0;border: 1px solid …

网络安全实训Day5

写在前面 昨天忘更新了......讲的内容不多&#xff0c;就一个NAT。 之前记的NAT的内容&#xff1a;blog.csdn.net/Yisitelz/article/details/131840119 网络安全实训-网络工程 NAT 公网地址与私网地址 公网地址 可以在互联网上被寻址&#xff0c;由运营商统一分配全球唯一的I…

在 Windows 上利用Qwen大模型搭建一个 ChatGPT 式的问答小助手

本文首发于公众号&#xff1a;Hunter后端 原文链接&#xff1a;在 Windows 上利用Qwen大模型搭建一个 ChatGPT 式的问答小助手 最近 ChatGPT 式的聊天机器人比较火&#xff0c;可以提供各种问答功能&#xff0c;阿里最近推出了 Qwen1.5 系列的大模型&#xff0c;提供了各个参数…

在线BLOG网|基于springboot框架+ Mysql+Java+JSP技术的在线BLOG网设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 系统功能设计 数据库E-R图设计 lunwen参考 摘要 研究…

【C#算法实现】可见的山峰对数量

文章目录 前言一、题目要求二、算法设计及代码实现2.1 算法思想2.2 代码实现 前言 本文是【程序员代码面试指南&#xff08;第二版&#xff09;学习笔记】C#版算法实现系列之一&#xff0c;用C#实现了《程序员代码面试指南》&#xff08;第二版&#xff09;栈和队列中的可见的…

OpenCV-Java 开发简介

返回目录&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a; 如何在“Microsoft Visual Studio”中使用OpenCV编译应用程序 下一篇&#xff1a;暂无 ​ 警告&#xff1a; 本教程可能包含过时的信息。 从 OpenCV 2.4.4 开始&…

java集合框架——Map集合概述

前言&#xff1a; 之前接触了单列合集&#xff0c;现在又接触了双列合集。整理下心得&#xff0c;打好基础&#xff0c;daydayup&#xff01;&#xff01; Map集合 Map集合称为双列集合&#xff0c;也被称为“键值对集合”。格式&#xff1a;{key1value1,key2value2...}&#…