参考:SpringBoot中filter的使用详解及原理_u014627099的博客-CSDN博客_filter springboot

Arthas实践--快速排查Spring Boot应用404/401问题 | 横云断岭的专栏

1. 处理请求流程

Request -》 filter1 -〉 filter2 -》 controller


Request《- filter1 《- filter2 《-   controller

2. filter原理【本质就是责任链设计】

请求会经过一个个编写的filter,最后进入controller 。然后返回一个个filter,最后给到请求方

3. 源码:​​​​​​https://github.com/bailuoxi66/snapUpDemo/tree/master/springBoot-Redis-Demo/springboot-filter

4. 代码相关

1. 要想使用filter,需要写一个方法继承Filter类。我们自己写了两个Filter类。其中

@Order里面的数字越小代表越先被该filter过滤
@WebFilter代表这是个Filter类,以便于启动类进行扫描的时候确认

2. FirstFilter

package com.example.springbootfilter.filterInfo;import org.springframework.core.annotation.Order;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;/*** @author :luoyu* @version :1.0* @date : 2021/12/31 10:47 上午* @description*/@Order(1)
@WebFilter(filterName = "firstFilter", urlPatterns = "/*")
public class FirstFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("first filter 1");filterChain.doFilter(servletRequest, servletResponse);System.out.println("first filter 2");}@Overridepublic void destroy() {}
}

3. SecondFilter

package com.example.springbootfilter.filterInfo;import org.springframework.core.annotation.Order;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author :luoyu* @version :1.0* @date : 2021/12/31 10:47 上午* @description*/@Order(2)
@WebFilter(filterName = "secondFilter", urlPatterns = "/*")
public class SecondFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("second filter 1");HttpServletRequest request = (HttpServletRequest) servletRequest;System.out.println("before:" + servletRequest);System.out.println(request.getRequestURL());String uri = request.getRequestURI();System.out.println(uri);if (uri.contains("Test")){System.out.println("过滤。。。");servletResponse.getWriter().write("secondfilter already");return;}filterChain.doFilter(servletRequest, servletResponse);System.out.println("after:" + servletResponse);System.out.println("second filter 2");}@Overridepublic void destroy() {}
}

4. SessionFilter

package com.example.springbootfilter.filterInfo;import org.springframework.core.annotation.Order;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author :luoyu* @version :1.0* @date : 2021/12/31 12:01 下午* @description*/
@Order(3)
@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"})
public class SessionFilter implements Filter {//不需要登录就可以访问的路径(比如:注册登录等)String[] includeUrls = new String[]{"/login","/test1"};@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String uri = request.getRequestURI();System.out.println("filter url:"+uri);//是否需要过滤boolean needFilter = isNeedFilter(uri);if (!needFilter) { //不需要过滤直接传给下一个过滤器filterChain.doFilter(servletRequest, servletResponse);} else {response.getWriter().write("sessionFilter already");}}/*** 是否需要过滤* @params [uri]* @return boolean* @author luoyu* @date 2021/12/31 1:35 下午**/public boolean isNeedFilter(String uri) {for (String includeUrl : includeUrls) {if(includeUrl.equals(uri)) {return false;}}return true;}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void destroy() {}
}

4. controller类

5. SpringBoot的主入口方法。注意:因为我们使用的是注解注入Filter,

所以需要加入:@ServletComponentScan


@SpringBootApplication
@ServletComponentScan
public class SpringbootFilterApplication {public static void main(String[] args) {SpringApplication.run(SpringbootFilterApplication.class, args);}}

6. 运行结果

1. 正常没有过滤逻辑

请求:http://localhost:8080/test1

运行结果:

可以看到代码执行流程,首先请求会被FirstFilter截获,打印出first filter1,然后执行filterChain.doFilter(servletRequest, servletResponse),这句话代表请求会转发给过滤器链上的下一个对象,也就是SecondFilter,所以打印出second filter 1 。接下来执行SecondFilter里面的 filterChain.doFilter(servletRequest, servletResponse) ,请求会转发给下一个对象,到达SessionFilter打印filter url:/test1.然后根据是否过滤逻辑,发现不需要过滤直接给到下一个filter。调用filterChain.doFilter(servletRequest, servletResponse),但是没有其他filter了。所以会转发给controller。打印出controller里面对应方法的内容【“method in controller”】,接下来去虚拟机栈栈帧里面获取信息,调用SecondFilter打印出second filter 2. 同理调用FirstFilter打印出first filter 2。

2. filter过滤逻辑

请求:http://localhost:8080/api/filterTest.json

运行结果:

first filter 1
second filter 1
before:org.apache.catalina.connector.RequestFacade@5d98f8e7
http://localhost:8080/api/filterTest.json
/api/filterTest.json
过滤。。。
first filter 2

可以看到没有进入controller。因为命中率这里的逻辑:

也就是说:这里断开了,没有了后续。

3. SessionFilter拦截非法请求

因为从整个请求链路来看:经过了firstfilter-》scondfilter -》sessionfilter

首先secondfilter没有拦截,因为url没有包含“Test”字符,所以到达了sessionfilter

但是被sessionfilter拦截了。因为needFilter是true,需要拦截

4. 请求被filter拦截。通过arthas确认是哪一个filter拦截的。

开启arthas监听模式:在Arthas里面,把整个请求经过哪些filter处理,都打印成树。这里找下嵌套最深层

可以看到这里是:SessionFilter里面进行了拦截

arthas:所有结果

[arthas@86617]$ trace javax.servlet.Filter *
Press Q or Ctrl+C to abort.
Affect(class count: 18 , method count: 100) cost in 266 ms, listenerId: 1
`---ts=2021-12-31 14:08:34;thread_name=http-nio-8080-exec-4;id=30;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@5c1bd44c`---[6.468228ms] org.springframework.web.filter.OncePerRequestFilter:doFilter()+---[0.888623ms] org.springframework.web.filter.OncePerRequestFilter:getAlreadyFilteredAttributeName() #97|   `---[0.851397ms] org.springframework.web.filter.OncePerRequestFilter:getAlreadyFilteredAttributeName()|       `---[0.800084ms] org.springframework.web.filter.OncePerRequestFilter:getFilterName() #170|           `---[0.07793ms] org.springframework.web.filter.GenericFilterBean:getFilterName()|               `---[0.024575ms] javax.servlet.FilterConfig:getFilterName() #298+---[0.019792ms] javax.servlet.ServletRequest:getAttribute() #98+---[2.108542ms] org.springframework.web.filter.OncePerRequestFilter:skipDispatch() #100|   `---[2.07759ms] org.springframework.web.filter.OncePerRequestFilter:skipDispatch()|       +---[1.977538ms] org.springframework.web.filter.OncePerRequestFilter:isAsyncDispatch() #127|       |   `---[1.94646ms] org.springframework.web.filter.OncePerRequestFilter:isAsyncDispatch()|       |       +---[0.013899ms] javax.servlet.http.HttpServletRequest:getDispatcherType() #146|       |       `---[0.072898ms] javax.servlet.DispatcherType:equals() #146|       `---[0.02551ms] javax.servlet.http.HttpServletRequest:getAttribute() #130+---[0.105523ms] org.springframework.web.filter.OncePerRequestFilter:shouldNotFilter() #100|   `---[0.031155ms] org.springframework.web.filter.OncePerRequestFilter:shouldNotFilter()+---[0.027592ms] javax.servlet.ServletRequest:setAttribute() #115+---[2.759263ms] org.springframework.web.filter.OncePerRequestFilter:doFilterInternal() #117|   `---[2.69305ms] org.springframework.web.filter.CharacterEncodingFilter:doFilterInternal()|       +---[0.056953ms] org.springframework.web.filter.CharacterEncodingFilter:getEncoding() #192|       |   `---[0.020965ms] org.springframework.web.filter.CharacterEncodingFilter:getEncoding()|       +---[0.058125ms] org.springframework.web.filter.CharacterEncodingFilter:isForceRequestEncoding() #194|       |   `---[0.016392ms] org.springframework.web.filter.CharacterEncodingFilter:isForceRequestEncoding()|       +---[0.038208ms] javax.servlet.http.HttpServletRequest:setCharacterEncoding() #195|       +---[0.035288ms] org.springframework.web.filter.CharacterEncodingFilter:isForceResponseEncoding() #197|       |   `---[0.011489ms] org.springframework.web.filter.CharacterEncodingFilter:isForceResponseEncoding()|       `---[2.412639ms] javax.servlet.FilterChain:doFilter() #201|           `---[2.367289ms] org.springframework.web.filter.OncePerRequestFilter:doFilter()|               +---[0.092118ms] org.springframework.web.filter.OncePerRequestFilter:getAlreadyFilteredAttributeName() #97|               |   `---[0.067511ms] org.springframework.web.filter.OncePerRequestFilter:getAlreadyFilteredAttributeName()|               |       `---[0.046879ms] org.springframework.web.filter.OncePerRequestFilter:getFilterName() #170|               |           `---[0.025428ms] org.springframework.web.filter.GenericFilterBean:getFilterName()|               |               `---[0.007377ms] javax.servlet.FilterConfig:getFilterName() #298|               +---[0.011038ms] javax.servlet.ServletRequest:getAttribute() #98|               +---[0.140236ms] org.springframework.web.filter.OncePerRequestFilter:skipDispatch() #100|               |   `---[0.115496ms] org.springframework.web.filter.OncePerRequestFilter:skipDispatch()|               |       +---[0.072747ms] org.springframework.web.filter.OncePerRequestFilter:isAsyncDispatch() #127|               |       |   `---[0.041142ms] org.springframework.web.filter.OncePerRequestFilter:isAsyncDispatch()|               |       |       +---[0.008436ms] javax.servlet.http.HttpServletRequest:getDispatcherType() #146|               |       |       `---[0.006054ms] javax.servlet.DispatcherType:equals() #146|               |       `---[0.010302ms] javax.servlet.http.HttpServletRequest:getAttribute() #130|               +---[0.034537ms] org.springframework.web.filter.OncePerRequestFilter:shouldNotFilter() #100|               |   `---[0.009114ms] org.springframework.web.filter.OncePerRequestFilter:shouldNotFilter()|               +---[0.019467ms] javax.servlet.ServletRequest:setAttribute() #115|               +---[1.971268ms] org.springframework.web.filter.OncePerRequestFilter:doFilterInternal() #117|               |   `---[1.937453ms] org.springframework.web.filter.FormContentFilter:doFilterInternal()|               |       +---[0.196208ms] org.springframework.web.filter.FormContentFilter:parseIfNecessary() #88|               |       |   `---[0.171456ms] org.springframework.web.filter.FormContentFilter:parseIfNecessary()|               |       |       `---[0.148937ms] org.springframework.web.filter.FormContentFilter:shouldParse() #99|               |       |           `---[0.122507ms] org.springframework.web.filter.FormContentFilter:shouldParse()|               |       |               +---[0.020572ms] javax.servlet.http.HttpServletRequest:getContentType() #113|               |       |               +---[0.033034ms] javax.servlet.http.HttpServletRequest:getMethod() #114|               |       |               `---[0.020836ms] org.springframework.util.StringUtils:hasLength() #115|               |       +---[0.011308ms] org.springframework.util.CollectionUtils:isEmpty() #89|               |       `---[1.685984ms] javax.servlet.FilterChain:doFilter() #93|               |           `---[1.664666ms] org.springframework.web.filter.OncePerRequestFilter:doFilter()|               |               +---[0.081575ms] org.springframework.web.filter.OncePerRequestFilter:getAlreadyFilteredAttributeName() #97|               |               |   `---[0.065688ms] org.springframework.web.filter.OncePerRequestFilter:getAlreadyFilteredAttributeName()|               |               |       `---[0.051453ms] org.springframework.web.filter.OncePerRequestFilter:getFilterName() #170|               |               |           `---[0.030805ms] org.springframework.web.filter.GenericFilterBean:getFilterName()|               |               |               `---[0.007209ms] javax.servlet.FilterConfig:getFilterName() #298|               |               +---[0.010989ms] javax.servlet.ServletRequest:getAttribute() #98|               |               +---[0.13897ms] org.springframework.web.filter.OncePerRequestFilter:skipDispatch() #100|               |               |   `---[0.122124ms] org.springframework.web.filter.OncePerRequestFilter:skipDispatch()|               |               |       +---[0.078663ms] org.springframework.web.filter.OncePerRequestFilter:isAsyncDispatch() #127|               |               |       |   `---[0.053971ms] org.springframework.web.filter.OncePerRequestFilter:isAsyncDispatch()|               |               |       |       +---[0.005793ms] javax.servlet.http.HttpServletRequest:getDispatcherType() #146|               |               |       |       `---[0.013142ms] javax.servlet.DispatcherType:equals() #146|               |               |       `---[0.011082ms] javax.servlet.http.HttpServletRequest:getAttribute() #130|               |               +---[0.021786ms] org.springframework.web.filter.OncePerRequestFilter:shouldNotFilter() #100|               |               |   `---[0.005747ms] org.springframework.web.filter.OncePerRequestFilter:shouldNotFilter()|               |               +---[0.012466ms] javax.servlet.ServletRequest:setAttribute() #115|               |               +---[1.293744ms] org.springframework.web.filter.OncePerRequestFilter:doFilterInternal() #117|               |               |   `---[1.262514ms] org.springframework.web.filter.RequestContextFilter:doFilterInternal()|               |               |       +---[0.021243ms] org.springframework.web.context.request.ServletRequestAttributes:<init>() #96|               |               |       +---[0.278449ms] org.springframework.web.filter.RequestContextFilter:initContextHolders() #97|               |               |       |   `---[0.256751ms] org.springframework.web.filter.RequestContextFilter:initContextHolders()|               |               |       |       +---[0.132398ms] javax.servlet.http.HttpServletRequest:getLocale() #112|               |               |       |       +---[0.025818ms] org.springframework.context.i18n.LocaleContextHolder:setLocale() #112|               |               |       |       +---[0.017864ms] org.springframework.web.context.request.RequestContextHolder:setRequestAttributes() #113|               |               |       |       `---[0.016344ms] org.apache.commons.logging.Log:isTraceEnabled() #114|               |               |       +---[0.705757ms] javax.servlet.FilterChain:doFilter() #100|               |               |       |   `---[0.661857ms] com.example.springbootfilter.filterInfo.FirstFilter:doFilter()|               |               |       |       `---[0.569476ms] javax.servlet.FilterChain:doFilter() #27|               |               |       |           `---[0.532086ms] com.example.springbootfilter.filterInfo.SecondFilter:doFilter()|               |               |       |               +---[0.037252ms] javax.servlet.http.HttpServletRequest:getRequestURL() #30|               |               |       |               +---[0.012403ms] javax.servlet.http.HttpServletRequest:getRequestURI() #31|               |               |       |               `---[0.266668ms] javax.servlet.FilterChain:doFilter() #38|               |               |       |                   `---[0.228648ms] com.example.springbootfilter.filterInfo.SessionFilter:doFilter()|               |               |       |                       +---[0.009811ms] javax.servlet.http.HttpServletRequest:getRequestURI() #29|               |               |       |                       +---[0.089258ms] com.example.springbootfilter.filterInfo.SessionFilter:isNeedFilter() #33|               |               |       |                       |   `---[0.058013ms] com.example.springbootfilter.filterInfo.SessionFilter:isNeedFilter()|               |               |       |                       `---[0.030816ms] javax.servlet.http.HttpServletResponse:getWriter() #38|               |               |       +---[0.148522ms] org.springframework.web.filter.RequestContextFilter:resetContextHolders() #103|               |               |       |   `---[0.083649ms] org.springframework.web.filter.RequestContextFilter:resetContextHolders()|               |               |       |       +---[0.023226ms] org.springframework.context.i18n.LocaleContextHolder:resetLocaleContext() #120|               |               |       |       `---[0.009855ms] org.springframework.web.context.request.RequestContextHolder:resetRequestAttributes() #121|               |               |       +---[0.00996ms] org.apache.commons.logging.Log:isTraceEnabled() #104|               |               |       `---[0.013286ms] org.springframework.web.context.request.ServletRequestAttributes:requestCompleted() #107|               |               `---[0.019486ms] javax.servlet.ServletRequest:removeAttribute() #121|               `---[0.008947ms] javax.servlet.ServletRequest:removeAttribute() #121`---[0.010701ms] javax.servlet.ServletRequest:removeAttribute() #121

上述结论一致。

SpringBoot filter 责任链相关推荐

  1. Filter责任链模式

    Filter责任链的创建 org.apache.catalina.core.ApplicationFilterFactory#createFilterChain,  此方法是被org.apache.c ...

  2. 使用SpringBoot实现责任链模式

    背景 当我们需要对一个对象进行多次操作时,每个操作支持个性化定制,后续还可能增加更多的操作时就可以使用责任链模式,本篇将使用SpringBoot实现简易责任链 例子 如下代码范例是校验一名粉丝是不是& ...

  3. java责任链模式审批请假_Java设计模式-责任链模式

    Java设计模式-责任链模式 Java版本:jdk1.8 IDE:IDEA 一 前言 本文介绍责任链模式以及Java下的实现. 二 概念 1.什么是责任链模式 责任链模式(Chain of Respo ...

  4. 责任链模式之Tomcat Filter应用

    责任链模式之Tomcat Filter应用 责任链模式是一种对象的行为型模式. 其定义为:很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象处理此请求.发 ...

  5. SpringCloud SpringBoot uniapp vue b2b2c 微服务 多商家入驻直播带货商城 分销商城 秒杀 高并发电商之责任链模式

    责任链模式 推荐分布式微服务电商源码 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收 ...

  6. 从Servlet、Dubbo、Mybatis聊聊责任链究竟怎么用

    作者:atheva 来源:https://dwz.cn/1TtgW7Ud 责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链 ...

  7. 一起学设计模式 - 责任链模式

    责任链模式(ChainOfResponsibilityPattern)属于 行为型模式的一种,将请求沿着一条链传递,直到该链上的某个对象处理它为止. 概述 定义如下:一个请求有多个对象来处理,这些对象 ...

  8. 折腾Java设计模式之责任链模式

    责任链模式 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计 ...

  9. 23种设计模式——责任链模式

    一.责任链模式 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的 ...

  10. 巧用『责任链模式』来优化 参数多重校验,非常优雅!

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

最新文章

  1. html标记汇总,HTML标记语法汇总.doc
  2. 面试官:MySQL 表设计要注意什么?
  3. 珂朵莉的约数(牛客练习赛9)
  4. 【CMD】复制并覆盖目标文件
  5. TPL Dataflow .Net 数据流组件,了解一下?
  6. 前端学习(2863):简单秒杀系统学习之优化cookie
  7. Diccuz!NT的dll版本号控制技巧
  8. WinMerge 操作界面汉语版(截图),以及简单功能介绍
  9. 【激光雷达3D】【论文翻译】PointPillars: Fast Encoders for Object Detection from Point Clouds
  10. iphone多线程事件循环
  11. lintcode 订单
  12. Aruba无线AP入坑心得
  13. win7下 文件名太长无法删除,无法更名问题
  14. 艾滋hiv最新研究进展(2022年4月)
  15. 【论文】多核实时操作系统的确定性调度设计
  16. TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
  17. 服务器虚拟机光驱,vSphere client中的光驱配置方式
  18. NVIDA CUDA显卡计算能力 GeForce RTX 2060 compute_capability
  19. Matlab在不同坐标系中绘图(对数、极坐标、双轴图)以及极坐标和直角坐标的相互转换
  20. JSP SSH机械设备台账管理系统myeclipse开发mysql数据库MVC模式java编程网页设计

热门文章

  1. mysql导入GP_GP数据库gpload数据导入详细操作
  2. 以太坊平台评估 私有链和联盟链的机会与挑战
  3. HPSocket C++控制台版DEMO
  4. 教程丨如何在AdsPower浏览器内快速配置UCloud 服务器
  5. win10计算机安全策略设置,win10系统重置本地安全策略所有设置的操作方法
  6. 很多人觉得FPGA难学,因为他们没总结出数电的尽头是模电!
  7. 国内主要OTT平台背后的那些CDN服务商
  8. premiere学习笔记01帧定格,时间码,透明视频,调整图层,转场及批量转场,插件安装,音频调整,关键帧,马赛克,蒙版,嵌套序列
  9. html 展开 折叠,HTML实现点击展开和收起
  10. 如何下载南开区卫星地图高清版大图