Filter与Listener(过滤器与监听器)

news2024/12/25 15:52:52

1.Filter

1.过滤器概述

过滤器——Filter,它是JavaWeb三大组件之一。另外两个是Servlet和Listener

它可以对web应用中的所有资源进行拦截,并且在拦截之后进行一些特殊的操作

在程序中访问服务器资源时,当一个请求到来,服务器首先判断是否有过滤器与请求资源相关联,如果有,过滤器可以将请求拦截下来,完成一些特定的功能,再由过滤器决定是否交给请求资源。如果没有则像之前那样直接请求资源了。响应也是类似的

过滤器一般用于完成通用的操作,例如:登录验证、统一编码处理、敏感字符过滤等

2.Filter概述

Filter 是一个接口,如果想实现过滤器的功能,必须实现该接口

核心方法

返回值方法名作用
voidinit(FilterConfig config)初始化方法
voiddoFilter(ServletRequest req,ServletResponse resp,FilterChain chain)对请求资源和响应资源过滤
voiddestory()销毁方法

 配置方式

        注解方式

        配置文件 

3.FilterChain

 FilterChain 是一个接口,代表过滤器链对象。由 Servlet 容器提供实现类对象,直接使用即可。

 过滤器可以定义多个,就会组成过滤

核心方法

返回值方法名作用
voiddoFilter(ServletRequest req,ServletResponse resp)放行方法

如果有多个过滤器,在第一个过滤器中调用下个过滤器,依次类推。直到到达最终访问资源

如果只有一个过滤器,放行时,就会直接到达最终访问资源

  

4.过滤器的使用 

需求说明

通过Filter过滤器解决多个资源写出中文乱码的问题

实现步骤

1.创建一个web项目

2.创建两个Servlet功能类,都向客户端写出中文数据

3.创建一个Filter过滤器实现类,重写doFilter核心方法

4.在方法内部解决中文乱码,并放行

5.部署并启动项目

6.通过浏览器测试

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/*
    过滤器基本使用
*/
@WebFilter("/*")
public class FilterDemo01 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterDemo01执行了...");
        //处理乱码
        servletResponse.setContentType("text/html;charset=UTF-8");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

5.过滤器的使用细节

配置方式

         注解方式 @WebFilter(拦截路径)

         配置文件

<filter>
    <filter-name>filterDemo01</filter-name>
    <filter-class>filter.FilterDemo01</filter-class>
</filter>
<filter-mapping>
    <filter-name>filterDemo01</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

 多个过滤器使用顺序

如果有多个过滤器,取决于过滤器映射的顺序

也就是filter-mapping配置的先后顺序

6.过滤器的生命周期

 创建(出生)

当应用加载时实例化对象并执行 init 初始化方法

 服务(活着)

对象提供服务的过程,执行 doFilter 方法
​​​​​

只要应用一直提供服务,对象就一直存在

 销毁(死亡)

当应用卸载时或服务器停止时对象销毁。执行 destroy

Filter的实例对象在内存中也只有一份。所以也是单例的

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo03 implements Filter {
    //初始化方法
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("对象初始化成功了...");
    }

    //提供服务方法
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterDemo03执行了...");
        //处理乱码
        servletResponse.setContentType("text/html;charset=UTF-8");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    //对象销毁
    @Override
    public void destroy() {
        System.out.println("对象销毁了...");
    }
}

 web.xml

<filter>
        <filter-name>filterDemo03</filter-name>
        <filter-class>filter.FilterDemo03</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterDemo03</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

7.FilterConfig过滤器配置对象

FilterConfig 是一个接口。代表过滤器的配置对象,可以加载一些初始化参数。与ServletConfig类似

核心方法

返回值方法名作用
StringgetFilterName()获取过滤器对象名称
StringgetInitParameter(String key)根据key过去value
EnumerationgetInitParameterNames()获所有参数的key
ServletContextgetServletContext()获取应用上下文对象
package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo04 implements Filter {
    //初始化方法
    @Override
    public void init(FilterConfig filterConfig) {

        System.out.println("对象初始化成功了...");
        //获取过滤器名称
        String filterName = filterConfig.getFilterName();
        System.out.println(filterName);
        //根据name获取value
        String username = filterConfig.getInitParameter("username");
        System.out.println(username);
    }

    //提供服务方法
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filterDemo04执行了...");
        //处理乱码
        servletResponse.setContentType("text/html;charset=UTF-8");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    //对象销毁
    @Override
    public void destroy() {
        System.out.println("对象销毁了...");
    }
}

web.xml

 <filter>
        <filter-name>filterDemo04</filter-name>
        <filter-class>filter.FilterDemo04</filter-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>zhangsan</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filterDemo04</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

8.过滤器五种拦截行为 

Filter 过滤器默认拦截的是请求,但是在实际开发中,我们还有请求转发和请求包含,以及由服务器触发调用的全局错误页面。默认情况下过滤器是不参与过滤的,要想使用,就需要我们配置

<filter>
    <filter-name>filterDemo05</filter-name>
    <filter-class>Filter.FilterDemo5</filter-class>
    <!--配置开启异步支持,当dispatcher配置ASYNC时,需要配置此行-->
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>filterDemo05</filter-name>
    <url-pattern>/index.jsp</url-pattern>
    <!--过滤请求:默认值。-->
    <dispatcher>REQUEST</dispatcher>
    <!--过滤全局错误页面:当由服务器调用全局错误页面时,过滤器工作-->
    <dispatcher>ERROR</dispatcher>
    <!--过滤请求转发:当请求转发时,过滤器工作。-->
    <dispatcher>FORWARD</dispatcher>
    <!--过滤请求包含:当请求包含时,过滤器工作。它只能过滤动态包含,jsp的include指令是静态包含,过滤器不会起作用-->
    <dispatcher>INCLUDE</dispatcher>
    <!--过滤异步类型,它要求我们在filter标签中配置开启异步支持-->
    <dispatcher>ASYNC</dispatcher>
</filter-mapping>

2.Listener 

1.监听器概述

观察者设计模式,所有的监听器都是基于观察者设计模式的

三个组成部分

事件源:触发事件的对象。

事件:触发的动作,里面封装了事件源。

监听器:当事件源触发事件时,要做的事情。一般是一个接口,由使用者来实现。

监听器:

在程序当中,我们可以对:对象的创建销毁、域对象中属性的变化、会话相关内容进行监听

Servlet 规范中共计 8 个监听器,监听器都是以接口形式提供,具体功能需要我们自己来完成

2.监听对象的监听器

1.ServletContextListener:用于监听 ServletContext 对象的创建和销毁

核心方法

返回值方法名作用
voidcontextInitialized(ServletContextEvent sce)对象创建时执行该方法
voidcontextDestroyed(ServletContextEvent sce)对象销毁时执行该方法

参数:ServletContextEvent 代表事件对象

事件对象中封装了事件源,也就是 ServletContext

真正的事件指的是创建或销毁 ServletContext 对象的操作

2.HttpSessionListener:用于监听 HttpSession 对象的创建和销毁

核心方法

返回值方法名作用
voidsessionCreated(HttpSessionEvent se)对象创建时执行该方法
voidsessionDestroyed(HttpSessionEvent se)对象销毁时执行该方法

参数:HttpSessionEvent 代表事件对象

事件对象中封装了事件源,也就是 HttpSession

真正的事件指的是创建或销毁 HttpSession 对象的操作

3.ServletRequestListener:用于监听 ServletRequest 对象的创建和销毁

核心方法

返回值方法名作用
voidrequestInitialized(ServletRequestEvent sre)对象创建时执行该方法
voidrequestDestroyed(ServletRequestEvent sre)对象销毁时执行该方法

参数:ServletRequestEvent 代表事件对象

事件对象中封装了事件源,也就是 ServletRequest

真正的事件指的是创建或销毁 ServletRequest 对象的操作

3.监听域对象属性变化的监听器

1.ServletContextAttributeListener:用于监听 ServletContext 应用域中属性的变化

核心方法

返回值方法名作用
voidattributeAdded(ServletContextAttributeEvent scae)域中添加属性时执行该方法
voidattributeRemoved(ServletContextAttributeEvent scae)域中移除属性时执行该方法
voidattributeReplaced(ServletContextAttributeEvent scae)域中替换属性时执行该方法

参数:ServletContextAttributeEvent 代表事件对象

事件对象中封装了事件源,也就是 ServletContext

真正的事件指的是添加、移除、替换应用域中属性的操作

2.HttpSessionAttributeListener:用于监听 HttpSession 会话域中属性的变化

核心方法

返回值方法名作用
voidattributeAdded(ServletSessionBindingEvent se)域中添加属性时执行该方法
voidattributeRemoved(ServletSessionBindingEvent se)域中移除属性时执行该方法
voidattributeReplaced(ServletSessionBindingEvent se)域中替换属性时执行该方法

参数:HttpSessionBindingEvent 代表事件对象

事件对象中封装了事件源,也就是 HttpSession

真正的事件指的是添加、移除、替换会话域中属性的操作

3.ServletRequestAttributeListener:用于监听 ServletRequest 请求域中属性的变化

核心方法

返回值方法名作用
voidattributeAdded(ServletRequestAttributeEvent srae)域中添加属性时执行该方法
voidattributeRemoved(ServletRequestAttributeEvent srae)域中移除属性时执行该方法
voidattributeReplaced(ServletRequestAttributeEvent srae)域中替换属性时执行该方法

参数:ServletRequestAttributeEvent 代表事件对象

事件对象中封装了事件源,也就是 ServletRequest

真正的事件指的是添加、移除、替换请求域中属性的操作

4.监听会话相关的感知性监听器

1.HttpSessionBindingListener:用于感知对象和会话域绑定的监听器

核心方法

返回值方法名作用
voidvalueBound(HttpSessionBindingEvent event)数据添加到会话域中(绑定时)执行该方法
voidvalueUnbound(HttpSessionBindingEvent event)数据从会话域中移除(解绑时)执行该方法

参数:HttpSessionBindingEvent 代表事件对象

事件对象中封装了事件源,也就是 HttpSession

真正的事件指的是添加、移除会话域中数据的操作

2.HttpSessionActivationListener:用于感知会话域中对象钝化和活化的监听器

核心方法

返回值方法名作用
voidsessionWillPassivate(HttpSessionEvent se)会话域中数据钝化时执行该方法
voidsessionDidActivate(HttpSessionEvent se)会话域中数据活化时执行该方法

参数:HttpSessionEvent 代表事件对象

事件对象中封装了事件源,也就是 HttpSession

真正的事件指的是会话域中数据钝化、活化的操作

5.监听器的使用

在实际开发中,我们可以根据具体情况来从这8个监听器中选择使用

感知型监听器由于无需配置,只需要根据实际需求编写代码

ServletContextListener

package listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/*
    ServletContext对象的创建和销毁的监听器
    //配置监听器:@WebListener
 */
@WebListener
public class ServletContextListenerDemo implements ServletContextListener {
    /*
        ServletContext对象创建的时候执行此方法
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("监听到了对象的创建...");

        //获取对象
        ServletContext servletContext = sce.getServletContext();
        System.out.println(servletContext);

    }

    /*
        ServletContext对象销毁的时候执行此方法
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("监听到了对象的销毁...");
    }
}

ServletContextAttributeListener

package listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

/*
    应用域对象中的属性变化的监听器
 */
@WebListener
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener {
    /*
        向应用域对象中添加属性时执行此方法
     */
    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("监听到了属性的添加...");

        //获取应用域对象
        ServletContext servletContext = scae.getServletContext();
        //获取属性
        Object value = servletContext.getAttribute("username");
        System.out.println(value);
    }

    /*
        向应用域对象中替换属性时执行此方法
     */
    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("监听到了属性的替换...");

        //获取应用域对象
        ServletContext servletContext = scae.getServletContext();
        //获取属性
        Object value = servletContext.getAttribute("username");
        System.out.println(value);
    }

    /*
        向应用域对象中移除属性时执行此方法
     */
    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("监听到了属性的移除...");

        //获取应用域对象
        ServletContext servletContext = scae.getServletContext();
        //获取属性
        Object value = servletContext.getAttribute("username");
        System.out.println(value);
    }
}

修改ServletContextListenerDemo:在contextInitialized中增加

//添加属性
servletContext.setAttribute("username","zhangsan");

//替换属性
servletContext.setAttribute("username","lisi");

//移除属性
servletContext.removeAttribute("username");

 

用配置文件方式(第一种为注解方式)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置监听器-->
    <listener>
        <listener-class>listener.ServletContextListenerDemo</listener-class>
    </listener>
    <listener>
        <listener-class>listener.ServletContextAttributeListenerDemo</listener-class>
    </listener>
</web-app>

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

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

相关文章

Ganache本地测试网如何在远程环境中进行访问和操作

文章目录 前言1. 安装Ganache2. 安装cpolar3. 创建公网地址4. 公网访问连接5. 固定公网地址 前言 Ganache 是DApp的测试网络&#xff0c;提供图形化界面&#xff0c;log日志等&#xff1b;智能合约部署时需要连接测试网络。 Ganache 是一个运行在本地测试的网络,通过结合cpol…

ELK架构Logstash的相关插件:grok、multiline、mutate、date的详细介绍

文章目录 1. grok (正则捕获插件)1.1 作用1.2 正则表达式的类型1.2.1 内置正则表达式1.2.2 自定义正则表达式 2. mutate (数据修改插件&#xff09;2.1 作用2.2 常见配置选项2.3 应用实例 3. multiline &#xff08;多行合并插件&#xff09;3.1 作用3.2 常用配置项及示例3.2.1…

babel6使用ES2020最新js语法

babel6使用ES2020最新js语法 Babel 6 原本是不支持 ES2020 语法&#xff0c;因为它是在 Babel 7 中引入的。如果您想使用 ES2020 语法&#xff0c;您需要将 Babel 6 升级到 Babel 7 或更高版本(推荐),当然也可以在bebel6中安装支持某个语法的plugin,比如你想使用 ES2020 中的可…

react仿照antd progress实现可自定义颜色的直角矩形进度条

可传颜色、带滑块的直角进度条 很歹毒的UI设计&#xff08;真的很丑&#xff09; 实现&#xff1a; class RankProgress extends React.Component {render() {const { percent, progressColor } this.props;return (<div className{styles.progress}><div classNam…

SpringSecurity+ Oauth2.0+JWT 0-1

这里写目录标题 准备工作准备SQL添加用户添加依赖准备UserInfoUserMapperUserServiceUserServiceImpl配置SpringDataUserDetailsService 授权服务器&#xff1a;AuthorizationServer配置客户端详细信息管理令牌定义TokenConfig定义AuthorizationServerTokenServices 令牌访问端…

百分点科技再度亮相GITEX全球大会

10月16-20日&#xff0c;全球最大科技信息展会之一 GITEX Global 2023在迪拜世贸中心开展&#xff0c;本届展会是历年来最大的一届&#xff0c;吸引了来自180个国家的6,000家参展商和180,000名技术高管参会。 百分点科技作为华为生态合作伙伴&#xff0c;继去年之后再度参展&a…

六顶思考帽思维模型

六顶思考帽思维模型 由爱德华德博诺博士开发的一种思维训练模式&#xff0c;也是一个全面思考问题的模型。 模型介绍 六顶思考帽对人们思考以及讨论问题所起到的帮助在于&#xff1a; 角色扮演-思维的最大限制就是“自我防卫”&#xff0c;这些帽子使我们敢说&#xff0c;而不…

Mask R-CNN训练自己的数据集

数据集制作 通常使用labelme来制作实例分割数据集&#xff0c;也有教程和代码来转换成COCO数据集。labelme项目地址为&#xff1a;https://github.com/wkentaro/labelme/tree/main 安装labelme conda create --namelabelme python3 conda activate labelme pip install labe…

纳米软件干货分享|芯片测试技术知识科普

芯片测试是确保芯片在各种条件下能够正常工作的关键环节。测试人员对芯片进行各种性能和可靠性的检测&#xff0c;以确保产品达到预期的性能指标和可靠性标准。 一、芯片测试的目的 芯片测试的主要目的是在投入应用之前发现和纠正芯片的潜在问题&#xff0c;防止不良品流入客…

c++_learning-对象模型探索

c对象模型探索 深入理解面向对象&#xff1a;c类对象模型&#xff1a;类中的成员&#xff1a;对象的内存大小&#xff1a;类对象内存的组成&#xff1a;不在对象内存中存放的成员&#xff1a; 类与类对象的内存分配&#xff1a;数据部分和代码部分&#xff1a;类对象占用的内存…

Verilog基础:避免混合使用阻塞和非阻塞赋值

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 “避免在一个always块中混杂阻塞赋值和非阻塞赋值”&#xff0c;这条原则是著名的Verilog专家Cliff Cummings在论文SUNG2000中提出的&#xff0c;这个观点在公众讨…

【AWS】亚马逊云的使用

现已推出预览版 — Amazon SageMaker Studio Lab&#xff0c;一项具有机器学习 (ML) 功能的免费学习和实验服务

公网使用PLSQL远程连接Oracle数据库【内网穿透】

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址…

2.2.2 交换机间相同vlan的通信

实验2.2.2 交换机间相同vlan的通信 一、任务描述二、任务分析三、实验拓扑四、具体要求五、任务实施1.设置交换机的名称&#xff0c;创建VLAN&#xff0c;配置access并分配接口。对两台交换机进行相同的VLAN划分&#xff0c;下面是SWA配置过程&#xff0c;同理可实现SWB的配置。…

低代码源代码交付的平台有哪些?

一、前言 作为这两年IT界的风口&#xff0c;低代码在众人眼里已经不是什么陌生的概念。 对标于传统的纯代码开发&#xff0c;低代码是一种快速开发软件&#xff08;应用程序&#xff09;的方法&#xff0c;平台通过对大量功能与场景做提前封装&#xff0c;使得用户可以在可视化…

Flink学习笔记(三):Flink四种执行图

文章目录 1、Graph 的概念2、Graph 的演变过程2.1、StreamGraph (数据流图)2.2、JobGraph (作业图)2.3、ExecutionGraph (执行图)2.4、Physical Graph (物理图) 1、Graph 的概念 Flink 中的执行图可以分成四层&#xff1a;StreamGraph -> JobGraph -> ExecutionGraph -&g…

2023年下半年软考机考考试时间批次安排

中国计算机技术职业资格网发布了关于2023年下半年计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试批次安排的通告&#xff0c;2023年下半年软考机考考试时间批次安排详见正文。 原文如下&#xff1a; 按照《2023年下半年计算机技术与软件专业技术资格&#xff…

2023年中国酒类新零售行业发展概况分析:线上线下渠道趋向深度融合[图]

近年来&#xff0c;我国新零售业态不断发展&#xff0c;线上便捷性和个性化推荐的优势逐步在放大&#xff0c;线下渠道智慧化水平持续提升&#xff0c;线上线下渠道趋向深度融合。2022年&#xff0c;我国酒类新零售市场规模约为1516亿元&#xff0c;预计2025年酒类新零售市场规…

STM32的hex文件格式的分析

前言 最近研究Bootloader&#xff0c;通过串口实现STM32程序的更新。需要学习了解STM32的Hex文件格式。在这进行一下总结。 HEX文件格式 我们通过文本形式打开hex文件&#xff0c;可以看到&#xff1a; 这一行就是一条指令数据&#xff0c;这里对数据帧格式进行说明&#xff…

c++_learning-模板与泛型编程

模板与泛型编程 模板概念、函数模板定义、调用&#xff1a;各种函数&#xff1a;替换失败不是一个错误SFINAE&#xff08;substitution failure is not an error&#xff09;&#xff1a;由来&#xff1a;特性&#xff1a; *c11引入的类模板enable_if&#xff0c;体现了SFINAE的…