当前位置: 首页 > news >正文

JavaWeb中的Filter(过滤器)和 Listener(监听器)

提示:这两个东西听起来似乎很难,实际上是非常简单的,按照要求写就行了,一定不要被新名词给吓到了。

JavaWeb中的Filter(过滤器)

  • 一、Filter(过滤器)
    • 1.如何编写 Filter
    • 2.Filter 中的细节
    • 3.Filter 总结
  • 二、Listener(监听器)
    • 1.Servlet规范中提供的监听器
    • 2..如何实现 Listener
    • 3.Listener 应用场景


一、Filter(过滤器)

  • Filter 可以在 Servlet 这个目标程序执行之前添加代码。也可以在目标 Servlet 执行之后添加代码。之前之后都可以添加过滤规则。
  • 一般情况都是在过滤器中编写公共代码。
    在这里插入图片描述

1.如何编写 Filter

  • 第一步:编写一个 Java 类实现一个接口:jarkata.servlet.Filter。并且实现这个接口当中的方法。

    • init方法:在Filter对象第一次被创建之后调用,并且只调用一次。(默认方法,可以不实现)
    • doFilter方法:只要用户发送一次请求,则执行一次。发送N次请求,则执行N次。在这个方法中编写过滤规则。(必须实现这个方法
      • 注意: chain.doFilter(request, response);这个代码是必须要写的,这行代码的作用是执行下一个过滤器或者执行目标Servlet的。如果不写那么就无法执行目标Servlet。
      • 在chain.doFilter(request, response); 前写的代码是在目标Servlet执行前执行的,在chain.doFilter(request, response); 后写的代码是在目标Servlet执行后执行的。
    • destroy方法:在Filter对象被释放/销毁之前调用,并且只调用一次。 (默认方法,可以不实现)
    public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//获取请求路径String servletPath = request.getServletPath();if(true){//在目标Servlet执行前执行的代码System.out.println("Servlet执行前......")filterChain.doFilter(request,response);//一定不能少的代码//在目标Servlet执行后执行的代码System.out.println("Servlet执行后......")} else {response.sendRedirect(request.getContextPath()); //返回网站的首页}}
    }
    
  • 第二步:在web.xml文件中对Filter进行配置。这个配置和Servlet很像。或者使用注解:@WebFilter({“*.do”})

    <filter><filter-name>filter2</filter-name><filter-class>com.gdb.javaweb.servlet.Filter2</filter-class>
    </filter>
    <filter-mapping><filter-name>filter2</filter-name><url-pattern>*.do</url-pattern>
    </filter-mapping>
    

2.Filter 中的细节

  • Filter的生命周期
    • 和Servlet对象生命周期一致。唯一的区别:Filter默认情况下,在服务器启动阶段就实例化。Servlet不会。
    • Servlet是单例的。Filter也是单例的。(单实例。)
  • 关于Filter的优先级
    • ① 注意:Filter的优先级,天生的就比Servlet优先级高。
      • 例如:/a.do 对应一个Filter,也对应一个Servlet。那么一定是先执行Filter,然后再执行Servlet。
    • ② 在web.xml文件中进行配置的时候,Filter的执行顺序:
      • 依靠filter-mapping标签的配置位置,越靠上优先级越高。过滤器的调用顺序,遵循栈数据结构。
    • ③ 使用@WebFilter的时候,Filter的执行顺序
      • 按照类名的字典序的顺序执行。
    • ④ 总结:在程序编译阶段不会确定Filter调用顺序。因为Filter的调用顺序是配置到web.xml文件中的,只要修改web.xml配置文件中filter-mapping的顺序就可以调整Filter的执行顺序。显然Filter的执行顺序是在程序运行阶段动态组合的。 这种设计模式被称为责任链设计模式。
  • 关于Filter的配置路径:
    • /a.do、/b.do、/dept/save。这些配置方式都是精确匹配。
    • /* 匹配所有路径。
    • *.do 后缀匹配。不要以 / 开始
    • /dept/* 前缀匹配。
  • 目标Servlet是否执行,取决于两个条件:
    • 第一:在过滤器当中是否编写了:chain.doFilter(request, response); 代码。
      • 执行下一个过滤器,如果下面没有过滤器了,执行最终的Servlet。
    • 第二:用户发送的请求路径是否和Servlet的请求路径一致。

3.Filter 总结

  • 过滤器是使用责任链设计模式实现的。
    • 责任链设计模式最大的核心思想:在程序运行阶段,动态的组合程序的调用顺序。
  • 可以使用过滤器来实现验证用户是否登录,防止未登录访问我们服务器中的数据

二、Listener(监听器)

  • 监听器是 Servlet 规范中的一员。就像 Filter 一样。Filter 也是 Servlet 规范中的一员。
  • 在 Servlet 中,所有的监听器接口都是以 “Listener” 结尾。
  • 注意:所有监听器中的方法都是不需要javaweb程序员调用的,当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了。)之后,被web服务器自动调用。

1.Servlet规范中提供的监听器

  • jakarta.servlet包下:
    • ServletContextListener
    • ServletContextAttributeListener
    • ServletRequestListener
    • ServletRequestAttributeListener
  • jakarta.servlet.http包下:
    • HttpSessionListener
    • HttpSessionAttributeListener
      • 该监听器需要使用@WebListener注解进行标注。
      • 该监听器监听的是什么?是session域中数据的变化。只要数据变化,则执行相应的方法。主要监测点在session域对象上。
    • HttpSessionBindingListener
      • 该监听器不需要使用@WebListener进行标注。
      • 假设User类实现了该监听器,那么User对象在被放入session的时候触发bind事件,User对象从session中删除的时候,触发unbind事件。
      • 假设Customer类没有实现该监听器,那么Customer对象放入session或者从session删除的时候,不会触发bind和unbind事件。
    • HttpSessionIdListener
      • session的id发生改变的时候,监听器中的唯一一个方法就会被调用。
    • HttpSessionActivationListener
      • 监听session对象的钝化和活化的。
      • 钝化:session对象从内存存储到硬盘文件。
      • 活化:从硬盘文件把session恢复到内存。
  • ServletContextListener、ServletRequestListener、HttpSessionListener 这三个监听器都提供了两个时间点,一个是域对象创建的时候,另一个是域对象销毁的时候。
  • ServletContextAttributeListener、ServletRequestAttributeListener、HttpSessionAttributeListener 这三个监听器都提供了三个时间点,一个是往域中添加数据的时候,一个是删除域中数据的时候,另一个是修改域中的数据的时候。

2…如何实现 Listener

  • 第一步:编写一个类实现 ServletContextListener 接口(以这个接口为例而已)。并且实现里面的方法。
    void contextInitialized(ServletContextEvent event)
    void contextDestroyed(ServletContextEvent event)
    
  • 第二步:在 web.xml 文件中对 ServletContextListener 进行配置。或者用注解 @WebListener。
    <listener><listener-class>com.bjpowernode.javaweb.listener.MyServletContextListener</listener-class>
    </listener>
    

3.Listener 应用场景

  • 请编写一个功能,记录该网站实时的在线用户的个数。
    • 我们可以通过服务器端有没有分配 session 对象,因为一个 session 代表了一个用户。有一个 session 就代表有一个用户。如果你采用这种逻辑去实现的话,session 有多少个,在线用户就有多少个。这种方式的话:HttpSessionListener 够用了。session 对象只要新建,则 count++,然后将 count 存储到 ServletContext 域当中,在页面展示在线人数即可。
  • 业务发生改变了,只统计登录的用户的在线数量,这个该怎么办?
    • session.setAttribute(“user”, userObj);
    • 用户登录的标志是 session 中曾经存储过 User 类型的对象。那么这个时候可以让 User 类型的对象实现 HttpSessionBindingListener 监听器,只要 User 类型对象存储到 session 域中,则 count++,然后将 count++ 存储到 ServletContext 对象中。页面展示在线人数即可。
    public class User implements HttpSessionBindingListener {private String username;private String password;//有参构造、无参构造、toString方法、set和get方法@Overridepublic void valueBound(HttpSessionBindingEvent event) {//用户登陆//User类型的对象向session中存储//获取ServletContextServletContext application = event.getSession().getServletContext();//获取在线人数Object onlineCount = application.getAttribute("onlineCount");if (onlineCount == null){application.setAttribute("onlineCount",1);}else {int count = (Integer)onlineCount;count++;application.setAttribute("onlineCount",count);}}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {//退出登陆//User类型的对象从session域中删除//获取ServletContextServletContext application = event.getSession().getServletContext();//获取在线人数Integer onlineCount = (Integer) application.getAttribute("onlineCount");onlineCount--;application.setAttribute("onlineCount",onlineCount);}
    

相关文章:

JavaWeb中的Filter(过滤器)和 Listener(监听器)

提示&#xff1a;这两个东西听起来似乎很难&#xff0c;实际上是非常简单的&#xff0c;按照要求写就行了&#xff0c;一定不要被新名词给吓到了。 JavaWeb中的Filter&#xff08;过滤器&#xff09; 一、Filter&#xff08;过滤器&#xff09;1.如何编写 Filter2.Filter 中的细…...

mybatis查询修改mysql的json字段

前言&#xff1a; mysql5.7版本之后支持json字段类型&#xff0c;推荐mysql8版本&#xff0c;适用于属性不确定的个性化字段&#xff0c;比如: 身份信息{“职业”,“学生”,“兴趣”:“打乒乓球”,“特长”:“跳高&#xff0c;书法”}; 图片信息{“日期”:“2023-12-12 22:12”…...

实时聊天系统

这个系统可以用于网站的即时通讯&#xff0c;比如客服系统、在线社区等。这个功能不仅对用户友好&#xff0c;而且也是检验技术实现能力的一个很好的案例。 ### 功能概述 该系统允许用户在网站上实时发送和接收消息。为了保持实时性&#xff0c;我们将使用PHP进行服务器端的逻…...

Spring-mvc、Spring-boot中如何在调用同类方法时触发AOP

1. 问题描述 Spring-mvc和Spring-boot中aop可以实现代理的功能&#xff0c;我们可以借此实现事务和日志记录或者限流等多种操作。但是&#xff0c;如果你在一个方法中调用其同类下的其他方法的时候不会触发AOP。本文主要说明其原因及解决办法和实现原理。 2. 原因 AIOP的本质是…...

幻兽帕鲁服务器自动重启备份-python

幻兽帕鲁服务器自动重启备份-python 1. 前置知识点2. 目录结构3. 代码内容4. 原理解释5. 额外备注 基于python编写的服务器全自动管理工具&#xff0c;能够实现自动定时备份存档&#xff0c;以及在检测到服务器崩溃之后自动重新启动&#xff0c;并且整合了对于frp端口转发工具的…...

C# Onnx yolov8 水表读数检测

目录 效果 模型信息 项目 代码 训练数据 下载 C# Onnx yolov8 水表读数检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-01-31T10:18:10.141465 author&#xff1a;Ultralytics task&#xff1a;detect license&#xff1a;AGPL-…...

负载均衡下webshell连接

目录 一、什么是负载均衡 分类 负载均衡算法 分类介绍 分类 均衡技术 主要应用 安装docker-compose 2.1上传的文件丢失 2.2 命令执行时的漂移 2.3 大工具投放失败 2.4 内网穿透工具失效 3.一些解决方案 总结 一、什么是负载均衡 负载均衡&#xff08;Load Balanc…...

Spring面试大全-基础知识01

1.什么是Spring Spring框架是用于构建企业级Java的开源框架&#xff0c;他通过依赖注入和IOC容器帮我我们管理对象&#xff1b;支持AOP&#xff0c;将非业务功能&#xff08;日志&#xff0c;事务等&#xff09;从我们业务代码中分离出来&#xff0c;提高了代码的可维护性&…...

Transformer实战-系列教程4:Vision Transformer 源码解读2

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 4、Embbeding类 self.embeddings Embeddings(config, img_sizeimg_size) class Embeddings(nn.…...

cesium-水平测距

cesium测量两点间的距离 <template><div id"cesiumContainer" style"height: 100vh;"></div><div id"toolbar" style"position: fixed;top:20px;left:220px;"><el-breadcrumb><el-breadcrumb-item&…...

【Android-Compose】手势检测实现按下、单击、双击、长按事件,以及避免频繁单击事件的简单方法

目录&#xff1a; 1 不需要双击事件 规避频繁单击事件2 需要双击事件&#xff08;常规写法&#xff09;3 后记&#xff1a;不建议使用上面的代码自定义按钮 1 不需要双击事件 规避频繁单击事件 var firstClickTime by remember { mutableStateOf(System.currentTimeMillis()…...

AUTOSAR汽车电子嵌入式编程精讲300篇-基于神经网络的CAN总线负载率优化(续)

目录 3.3 SA 算法 3.3.1 SA 算法原理 3.3.2 基于 SA 算法 CAN 总线负载率优化分析...

python爬虫6—高性能异步爬虫

如果有多个URL等待我们爬取&#xff0c;我们通常是一次只能爬取一个&#xff0c;爬取效率低&#xff0c;异步爬虫可以提高爬取效率&#xff0c;可以一次多多个URL同时同时发起请求 异步爬虫方式&#xff1a; 一、多线程、多进程&#xff08;不建议&#xff09;&#xff1a;可以…...

日历功能——C语言

实现日历功能&#xff0c;输入年份月份&#xff0c;输出日历 #include<stdio.h>int leap_year(int year) {if(year % 4 0 && year % 100 ! 0 || year % 400 0){return 1;}else{return 0;} }int determine_year_month_day(int *day,int month,int year) {if(mo…...

GPIO中断

1.EXTI简介 EXTI是External Interrupt的缩写&#xff0c;指外部中断。在嵌入式系统中&#xff0c;外部中断是一种用于处理外部事件的机制。当外部事件发生时&#xff08;比如按下按钮、传感器信号变化等&#xff09;&#xff0c;外部中断可以立即打断正在执行的程序&#xff0…...

springboot完成一个线上图片存放地址+实现前后端上传图片+回显

1.路径 注意路径 2.代码&#xff1a;&#xff08;那个imagePath没什么用&#xff0c;懒的删了&#xff09;&#xff0c;注意你的本地文件夹要有图片&#xff0c;才可以在线上地址中打开查看 package com.xxx.common.config;import org.springframework.beans.factory.annotat…...

编程思维与生活琐事的内在关联及其应用价值

随着科技的日益普及和信息化时代的到来&#xff0c;编程作为一种现代技能&#xff0c;其影响已不再局限于专业领域&#xff0c;而是逐步渗透到人们的日常生活之中。探讨编程与生活琐事之间的关系&#xff0c;有助于我们更好地理解如何将技术智慧应用于日常管理&#xff0c;提升…...

OSPF排错

目录 实验拓扑图 实验要求 实验排错 故障一 故障现象 故障分析 故障解决 故障二 故障现象 故障分析 故障解决 故障三 故障现象 故障分析 故障解决 故障四 故障现象 故障分析 故障解决 故障五 故障现象 故障分析 故障解决 故障六 故障现象 故障分析 …...

day07-CSS高级

01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置 显示模…...

05 MP之ActiveRecord模式+SimpleQuery

1. ActiveRecord ActiveRecord(活动记录&#xff0c;简称AR)&#xff0c;是一种领域模型模式&#xff0c;特点是一个模型类对应关系型数据库中的一个表&#xff0c;而模型类的一个实例对应表中的一行记录。 其目标是通过围绕一个数据对象, 进行全部的CRUD操作。 1.1 让实体类…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞&#xff0c;需构建多层防御体系&#xff0c;结合技术验证、存储隔离与权限控制&#xff1a; &#x1f512; 一、基础防护层 前端校验&#xff08;仅辅助&#xff09; 通过JavaScript限制文件后缀名&#xff08;白名单&#xff09;和大小&#xff0c;提…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

P10909 [蓝桥杯 2024 国 B] 立定跳远

# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上&#xff0c;小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时&#xff0…...

Excel 怎么让透视表以正常Excel表格形式显示

目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...