【SpringBoot】过滤器,监听器,拦截器介绍

2023-11-02

一、简介

在这里插入图片描述

在这里插入图片描述

通过两幅图我们可以理解拦截器和过滤器的特点

1、过滤器

过滤器是在请求进入tomcat容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

理解上面这句话我们就可以知道,进入servlet之前,主要是两个参数:ServletRequest,ServletResponse 那我们得到这两个测试可以干哪些事呢?

我们可以通过ServletRequest得到HttpServletRequest,此时你就可以对请求或响应(Request、Response)那就可以对对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息、字符集统一等一些高级功能。它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。(每次热部署后,都会销毁)。

2、拦截器

从上图我们可以看出过滤器只在servlet前后起作用,所以它既不能捕获异常,获得bean对象等,这些是只能是进入servlet里面的拦截器能过做到。拦截器中用于在某个方法或字段被访问之前,进行拦截然后,在之前或之后加入某些操作。比如日志,安全等。一般拦截器方法都是通过动态代理的方式实现。可以通过它来进行权限验证,或者判断用户是否登陆,或者是像12306 判断当前时间是否是购票时间。

对比一下其实我们可以发现,过滤器能做的事拦截器都能做,二拦截器做的事过滤器不一定做的了。

3、监听器

listener是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。其主要可用于以下方面:

  • 1、统计在线人数和在线用户
  • 2、系统启动时加载初始化信息
  • 3、统计网站访问量
  • 4、记录用户访问路径。

常用的监听器 servletContextListener、httpSessionListener、servletRequestListener)

二、如何创建

1、过滤器

自定义Filter 使用Servlet3.0的注解进行配置第三步的@WebFilter就是3.0的注解

1)启动类里面增加 @ServletComponentScan,进行扫描

2)新建一个Filter类,implements Filter,并实现对应的接口

3)@WebFilter 标记一个类为filter,被spring进行扫描

urlPatterns:拦截规则,支持正则

4)控制chain.doFilter的方法的调用,来实现是否通过放行不放行,web应用resp.sendRedirect("/index.html");场景:权限控制、用户登录(非前端后端分离场景)等

application类

@SpringBootApplication
@ServletComponentScan
public class SpringbootstudyApplication {

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

LoginFilter过滤器

//过滤器拦截路径
@WebFilter(urlPatterns = "/api/*", filterName = "loginFilter")
public class LoginFilter  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("拦截中========拦截中========");

          HttpServletRequest hrequest = (HttpServletRequest)servletRequest;
          HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);
          if(hrequest.getRequestURI().indexOf("/index") != -1 ||
                  hrequest.getRequestURI().indexOf("/asd") != -1 ||
                  hrequest.getRequestURI().indexOf("/online") != -1 ||
                  hrequest.getRequestURI().indexOf("/login") != -1
                  ) {
              filterChain.doFilter(servletRequest, servletResponse);
          }else {
              wrapper.sendRedirect("/login");
          }
          
      }

      /**
       * 容器被销毁的时候被调用
       */
      @Override
      public void destroy() {
          System.out.println("拦截器销毁========拦截器销毁========");
      }

}

1、官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners

2、监听器

@WebListener
public class RequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        // TODO Auto-generated method stub
        System.out.println("======销毁监听器========");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("======进入监听器========");
        
    }

3、拦截器

CustomWebMvcConfigurer主拦截器需要:

1:添加@Configuration注解

2:实现WebMvcConfigurer接口
//主拦截器,根据拦截不同路径跳转不同自定义拦截器 (实现WebMvcConfigurer方法)
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer  {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api1/*/**");
        registry.addInterceptor(new TwoIntercepter()).addPathPatterns("/api2/*/**");
        
        //.excludePathPatterns("/api2/xxx/**"); //拦截全部 /*/*/**
        
        WebMvcConfigurer.super.addInterceptors(registry);
    }

}

LoginIntercepter子拦截器

public class LoginIntercepter implements HandlerInterceptor{

    /**
     * 进入controller方法之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("LoginIntercepter------->preHandle");

//        String token = request.getParameter("access_token");
//        
//        response.getWriter().print("fail");
        
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    /**
     * 调用完controller之后,视图渲染之前
     */
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        
        System.out.println("LoginIntercepter------->postHandle");
        
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 整个完成之后,通常用于资源清理
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("LoginIntercepter------->afterCompletion");
        
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
    
    
}

TwoIntercepter同上

三、总结

最后总解一下他们:

过滤器:用于属性甄别,对象收集(不可改变过滤对象的属性和行为)

监听器:用于对象监听,行为记录(不可改变监听对象的属性和行为)

拦截器:用于对象拦截,行为干预(可以改变拦截对象的属性和行为)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【SpringBoot】过滤器,监听器,拦截器介绍 的相关文章

  • Mockito 在调用参数数量可变的方法时使用参数匹配器

    我试图在对具有可变数量参数的方法的调用中使用参数匹配器 Java 中的东西 没有成功 我的代码如下 我还将列出我尝试用来完成此工作的所有行 import static org mockito Mockito public class Met
  • 如何在 Spring Data 中选择不同的结果

    我在使用简单的 Spring Data 查询或 Query 或 QueryDSL 在 Spring Data 中构建查询时遇到问题 如何选择三列 研究 国家 登录 不同的行 并且查询结果将是用户对象类型的列表 Table User Id S
  • 从 java sdk 向对等方发送提案时出现访问被拒绝错误

    我正在尝试使用以下代码查询区块链并收到访问被拒绝错误 我也遇到同样的错误sendTransactionProposal方法也是如此 UserContext adminUserContext RegisterEnrollUser regist
  • 存根方法时出现 InvalidUseOfMatchersException

    我有这个 TestNG 测试方法代码 InjectMocks private FilmeService filmeService new FilmeServiceImpl Mock private FilmeDAO filmeDao Bef
  • 如何将 javax.persistence.Column 定义为 Unsigned TINYINT?

    我正在基于 MySQL 数据库中的现有表创建 Java 持久性实体 Bean 使用 NetBeans IDE 8 0 1 我在这个表中遇到了一个字段 其类型为 无符号 TINYINT 3 我发现可以执行以下操作将列的类型定义为 unsign
  • Java Runtime.getRuntime().freeMemory() 问题

    我搜索并看到了一些线程 但没有一个能够解决我遇到的具体问题 我正在尝试使用以下方式监视我的内存使用情况Runtime getRuntime freeMemory Runtime getRuntime maxMemory and Runtim
  • Java:无法从同一包中的不同类访问静态变量

    这很奇怪 因为我有一个可以访问 Frame dimension getWidth 的 Character 类 及其伙伴 getHeight 但是当我想在 Map 类中使用它时 Eclipse 强调了它并且无法给我反馈 运行该程序最终会出现
  • “java.net.MalformedURLException:未找到协议”读取到 html 文件

    我收到一个错误 java net MalformedURLException Protocol not found 我想读取网络上的 HTML 文件 mainfest uses permission android name android
  • Spring Boot自动装配存储库始终为空[重复]

    这个问题在这里已经有答案了 每次我进入我的服务类时 存储库似乎都没有自动连接 因为它不断抛出 NullPointerException 谁能帮我检查一下我缺少什么吗 这是我的代码 演示应用程序 java package com exampl
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • Jackson XML ArrayList 输出具有两个包装器元素

    我在 Jackson 生成的 XML 输出中得到了两个包装器元素 我只想拥有一个 我有一个 Java bean Entity Table name CITIES JacksonXmlRootElement localName City pu
  • 生成的序列以 1 开头,而不是注释中设置的 1000

    我想请求一些有关 Hibernate 创建的数据库序列的帮助 我有这个注释 下面的代码 在我的实体类中 以便为合作伙伴表提供单独的序列 我希望序列以 1000 开头 因为我在部署期间使用 import sql 将测试数据插入数据库 并且我希
  • 在另一个模块中使用自定义 gradle 插件模块

    我正在开发一个自定义插件 我希望能够在稍后阶段将其部署到存储库 因此我为其创建了一个独立的模块 在对其进行任何正式的 TDD 之前 我想手动进行某些探索性测试 因此 我创建了一个使用给定插件的演示模块 到目前为止 我发现执行此操作的唯一方法
  • 如何在 Spring 属性中进行算术运算?

  • 使用架构注册表对 avro 消息进行 Spring 云合约测试

    我正在查看 spring 文档和 spring github 我可以看到一些非常基本的内容examples https github com spring cloud samples spring cloud contract sample
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • JMenu 中的文本居中

    好吧 我一直在网上寻找有关此问题的帮助 但我尝试的任何方法似乎都不起作用 我想让所有菜单文本都集中在菜单按钮上 当我使用setHorizontalTextPosition JMenu CENTER 没有变化 事实上 无论我使用什么常量 菜单
  • OpenCSV:将嵌套 Bean 映射到 CSV 文件

    我正在尝试将 bean 映射到 CSV 文件 但问题是我的 bean 具有其他嵌套 bean 作为属性 所发生的情况是 OpenCSV 遍历属性找到一个 bean 然后进入其中并映射该 bean 内的所有数据 如果找到另一个 bean 它就
  • Java中HashMap和ArrayList的区别?

    在爪哇 ArrayList and HashMap被用作集合 但我不明白我们应该在哪些情况下使用ArrayList以及使用时间HashMap 他们两者之间的主要区别是什么 您具体询问的是 ArrayList 和 HashMap 但我认为要完
  • 在java中使用多个bufferedImage

    我正在 java 小程序中制作游戏 并且正在尝试优化我的代码以减少闪烁 我已经实现了双缓冲 因此我尝试使用另一个 BufferedImage 来存储不改变的游戏背景元素的图片 这是我的代码的相关部分 public class QuizApp

随机推荐

  • SQL笔记(1)——MySQL创建数据库(收藏吃灰版)

    本文详细记录MySQL创建一个数据库的过程 不只是构建步骤 更多的是每一步涉及到的知识点 一般创建数据库有两种方式 一种是命令 另外一种就是通过数据库管理工具 本文主要记录通过命令的方式创建 后面的学习也都是基于这个数据库进行的 场景 创建
  • React中的条件渲染

    React中的条件渲染 Vue js中使用v if v else实现模板中的条件渲染 小程序中使用wx if wx else实现模板中的条件渲染 React中没有模板 即不需要v if 也没有指令系统 即没有v if 条件渲染需要手工实现
  • Springboot整合Mybatis之数据源配置

    spring datasource driver class name com mysql cj jdbc Driver spring datasource url jdbc mysql localhost 3306 springboot
  • androidstudio3.0解决gradle plugin 和android_apt不兼容问题

    将项目下的 classpath com neenbedankt gradle plugins android apt 1 8 删掉 和modul下的apply plugin com neenbedankt android apt 删掉 ap
  • opengl嵌入pyqt5编译的分割窗口中

    opengl嵌入pyqt5编译的分割窗口中 向大部分商业仿真软件一样 使用opengl显示三维模型 首先需要将opengl的窗口嵌入到pyqt5编译的界面中 下面是一个小例子 python view plain copy from PyQt
  • AI-视频换脸

    本文涉及到的代码均已放置在我的github中 gt 链接 环境 Anaconda 集成 python 3 6 5 主要使用了 dlib numpy opencv 调用为cv2 os这四个库 录制 截屏 FSCapture 8 0 目的 将视
  • pycharm配置PyQt5,以及创建第一个项目

    认你已经安装好了pycharm 也正确安装了PyQt5 否则 请移步https www cnblogs com longbigbeard p 9628102 html来安装PyQt5 下一步 Tools gt External Tools
  • CTFHub---xss 反射型

    反射型 反射型xss攻击 Reflected XSS 又称为非持久性跨站点脚本攻击 它是最常见的类型的XSS 攻击代码的工作方式可以分为三个类型 1 持久型跨站 最直接的危害类型 跨站代码存储在服务器 数据库 2 非持久型跨站 反射型跨站脚
  • 特征工程的建立过程

    1 特征工程 1 1 了解特征工程 数据挖掘 二八原则 80 的精力 gt 选取特征 20 的精力 gt 模型融合等 基于数据分析与探索提取潜在有价值的特征 特征工程重要性 特征越好 模型的性能越出色 特征越好 构建的模型越简单 特征越好
  • 清除浮动的五种方法

    为什么要清除浮动 因为往往浮动后的子元素因为脱离了标准流 不能自动撑起父元素的高度 所以会对后续布局产生影响 对此清除浮动不如理解为清除浮动产生的影响更为合理 例如 我们设置了两个盒子如图所示 粉色为父盒子 只有宽度没有高度 蓝色盒子有宽有
  • v-for和v-if不能同时使用(原因和解决方法)

    原因 当v for和v if同时使用时 VSCode会提示报错 这是因为v for的优先级比v if的优先级高 每一次遍历 再一个一个决定是否需要显示出来 渲染了多余的DOM节点 这会影响性能 解决 1 加一个
  • 【网络结构设计】1、ResNeXt

    文章目录 一 背景 二 方法 三 效果 论文 Aggregated Residual Transformations for Deep Neural Networks 代码 https github com miraclewkf ResNe
  • 前端浏览器报错:Invalid prop: type check failed for prop "border". Expected Boolean, got String.

    用elementUI写vue 项目 在浏览器调试的时候报了这个错误 原因是给表格加border true 让表格得到竖直的框线 插件希望得到的是一个布尔值 但是得到的是true的字符串 解决办法 在border true 前加上一个冒号
  • vue---深度修改样式

    scss parent v deep children1 样式 children2 样式
  • Sharding-Jdbc实现读写分离、分库分表

    1 概览 ShardingSphere Jdbc定位为轻量级Java框架 在Java的Jdbc层提供的额外服务 它使用客户端直连数据库 以jar包形式提供服务 可理解为增强版的Jdbc驱动 完全兼容Jdbc和各种ORM框架 2 MySQL主
  • LINUX下MYSQL密码正确但无法本地登录

    如果可以远程登录 但无法本地登录 报错为1045 可能出错原因和我一样 配置过远程连接 修改过user表中的host字段 而mysql默认user为localhost 不匹配于是报错 解决办法 1 启动mysql时跳过密码问题 打开my c
  • git:远程仓库

    远程仓库是指托管在网络服务器上的项目仓库 可能会有好多个项目仓库 其中有些你只能读 另外有些可以写 同他人协作开发某个项目时 需要管理这些远程仓库 以便推送或拉取数据 分享各自的工作进展 假设远程仓库有一个默认远程分支 dev 如果将其克隆
  • Ubuntu下SSH设置,实现远程登录

    网上有很多介绍在Ubuntu下开启SSH服务的文章 但大多数介绍的方法测试后都不太理想 均不能实现远程登录到Ubuntu上 最后分析原因是都没有真正开启ssh server服务 最终成功的方法如下 Ubuntu 下安装 OpenSSH Se
  • nginx的配置转发

    有这样一个需求 项目中跳转到某个地址 但这个地址不想暴露给用户 因此我们想到要做一层代理 通过项目某个路径直接用ngnix代理到这个地址 查询相关文档后 发现方案如下 用return 302 1 2 3 location myBaidu r
  • 【SpringBoot】过滤器,监听器,拦截器介绍

    文章目录 一 简介 1 过滤器 2 拦截器 3 监听器 二 如何创建 1 过滤器 2 监听器 3 拦截器 三 总结 一 简介 通过两幅图我们可以理解拦截器和过滤器的特点 1 过滤器 过滤器是在请求进入tomcat容器后 但请求进入servl