首页 > 其他分享 >WEB三大组件之Filter

WEB三大组件之Filter

时间:2024-03-15 22:29:05浏览次数:23  
标签:WEB 请求 request Filter 过滤器 stopWatch 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";

    @Autowired
    private GlobalInitService globalInitService;

    @Autowired
    private StatisticsSettingService statisticsSettingService;

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public 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));
            }
        }
    }

    @Override
    public 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优先级

标签:WEB,请求,request,Filter,过滤器,stopWatch,filter,三大
From: https://blog.csdn.net/qq_64948664/article/details/136716188

相关文章

  • 深入了解WebAssembly:编译与测试指南
    在当今的Web开发中,WebAssembly(简称Wasm)作为一种新型的低级字节码格式,正在逐渐流行。它提供了一种高效的方式,使得在Web浏览器中运行性能密集型应用程序成为可能。这里我们将深入探讨如何编译和测试Wasm文件,以及相关的最佳实践和工具。1.WebAssembly简介: WebAssembly(Wasm)是一......
  • RestController:Spring Framework 中用于创建 RESTful Web 服务的注解
    RestController 是SpringFramework中用于创建RESTfulWeb服务的注解。它简化了构建RESTfulWeb服务的过程,使得开发者能够更专注于业务逻辑的实现,而不是底层的HTTP请求和响应处理。一、RestController的基本概念RestController 是SpringWeb模块中的一个核心注......
  • webrtc
    一、什么是WebRTCWebRTC(WebReal-TimeCommunication)是一个由Google、Mozilla、Opera等公司发起的开源项目,它支持网页浏览器进行实时音视频对话。它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和音频流或者其他任意数据的传......
  • 不只是答题:用WebSocket和SpringBoot让双人PK变得刺激又好玩
    引入......
  • 筛选器Filter
    参考:https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.01、什么是筛选器通过使用ASP.NETCore中的筛选器,可在请求处理管道中的特定阶段之前或之后运行代码。可以创建自定义筛选器,用于处理横切关注点。横切关注点的示例包括错误处......
  • web学习笔记(三十三)
    目录1.严格模式1.1严格模式的概念:1.2严格模式在语义上更改的地方:1.3如何开启严格模式 1.4严格模式应用上的变化 2.原型链1.严格模式1.1严格模式的概念:   严格模式有点像es5向es6过渡而产生的一种模式,因为es6的语法要求都比较严格,而我们在es5的代码编写过程......
  • Python爬虫案例:简单获取股票、指数、三大报表数据
    Python爬虫案例:简单获取股票、指数、三大报表数据文章目录Python爬虫案例:简单获取股票、指数、三大报表数据介绍1.准备工作2.以不同股票、指数为行,爬取不同日期的数据调用tushare库获取数据,并保存到本地baostock库获取单支股票的详细信息3.爬取三大报表数据使用ak......
  • Python之Web开发中级教程----创建Django子应用
    Python之Web开发中级教程----创建Django子应用基于上一个教程的Django项目(可以先看上一集,链接如下:)https://mp.csdn.net/mp_blog/creation/editor/1367248972.创建子应用pythonmanager.pystartappbookadmin.py:跟网站的后台管理站点配置相关。apps.py:用于配置当前应用......
  • 什么是布隆过滤器(Bloom Filter)?以及布隆过滤器的详细说明。
    什么是布隆过滤器(BloomFilter)?以及布隆过滤器的详细说明。布隆过滤器(BloomFilter):​ 是一种空间效率高、时间复杂度低的数据结构,用于判断一个元素是否属于一个集合。它通过使用多个哈希函数和位数组来实现快速的成员存在性检测,但有一定的误判率。结构:位数组(BitArray):布隆过......
  • RunOnWeb - 创建新协议,支持html调用本地可执行文件,支持浏览器互相调用
     浏览器调用exe?  Yes! 谷歌Chrome启动微软Edge?   Yes!RunOnWeb协议 创建新协议,支持html调用本地可执行文件,支持浏览器互相调用 【最新版本】:Ver1.0.0【更新日期】:2024.3.15【作者】:阿色【下载】点击下载RunOnWeb协议安装程序及源文件:https://......