监听器Listener + 过滤器Filter

news2024/11/15 19:48:27

监听器Listener

介绍

Listener是JavaEE的规范,就是接口

监听器的作用是,监听某种变化(一般就是对象创建/销毁, 属性变化), 触发对应方法完成相应的任务

ServletContextListener监听器(最常用)

作用:
        监听ServletContext创建或销毁(当我们Web应用启动时,就会创建ServletContext), 即生命周期监听


应用场景:
        (1)加载初始化的配置文件;比如spring的配置文件
        (2)任务调度(配合定时器Timer/TimerTask)

相关方法:

void contextInitialized(ServletContextEvent sce)        创建Servletcontext时触发
void contextDestroyed(ServletContextEvent sce)       销毁Servletcontext时触发

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


//当一个类实现了ServletContextListener,该类就是一个监听器
//该类可以监听的事件由该类实现的监听接口决定,比如实现ServletContextListener,则该类就可以监听ServletContext对象的创建和销毁
//HspServletContext就是一个监听者
//当web应用启动时,就会产生ServletContextEvent事件,会调用监听器的对应事件处理方法contextInitialized,同时会传递事件对象
//程序员可以通过servletContextEvent事件对象,来获取需要的信息,然后再进行业务处理
public class HspServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //获取到servletContext对象
        ServletContext servletContext = servletContextEvent.getServletContext();
        System.out.println("HspServletContextListener监听到" + servletContext + "被创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        System.out.println("HspServletContextListener监听到" + servletContext + "被销毁");
    }
}

配置xml 

    <listener>
        <listener-class>HspServletContextListener</listener-class>
    </listener>

ServletContextAttributeListener监听器(最常用)

作用:
        监听ServletContext属性变化

相关方法:

void attributeAdded(ServletContextAttributeEventevent)          添加属性时调用
void attributeReplaced(ServletContextAttributeEventevent)     替换属性时调用
void attributeRemoved(ServletContextAttributeEventevent)     移除属性时调用

public class HspServletContextAttributeListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("监听到添加属性" + servletContextAttributeEvent.getName() + "=" + servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("监听到修改属性" + servletContextAttributeEvent.getName() + "=" + servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("监听到删除属性" + servletContextAttributeEvent.getName() + "=" + servletContextAttributeEvent.getValue());
    }
}


/*
监听到添加属性name=abc
监听到修改属性name=abc    => 还是显示原来的value
监听到删除属性name=ddd
Hi处理完毕
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        servletContext.setAttribute("name","abc");
        servletContext.setAttribute("name","ddd");
        servletContext.removeAttribute("name");
        System.out.println("Hi处理完毕");
    }

HttpSessionListener监听器(常用)

作用:
        监听Session创建或销毁,即生命周期监听,可以用于监控用户上线,离线

相关方法:

void sessionCreated(HttpSessionEvent se)        创建session时调用
void sessionDestroyed(HttpSessionEvent se)    销毁session时调用

public class HspHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        //当session创建时,设置生命周期
        session.setMaxInactiveInterval(10);
        System.out.println("监听到session创建= " + session.getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("监听到session销毁= " + session.getId());
    }
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
    }

HttpSessionAttributeListener监听器

作用:
        监听Session属性的变化

相关方法:

void attributeAdded(ServletRequestAttributeEvent srae)             添加属性时
void attributeReplaced(ServletRequestAttributeEvent srae)        替换属性时
void attributeRemoved(ServletRequestAttributeEvent srae)        移除属性时

public class HspHttpSessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        //HttpSession session = httpSessionBindingEvent.getSession();
        System.out.println("监听到session添加属性" + httpSessionBindingEvent.getName() + "=" +httpSessionBindingEvent.getValue());
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("监听到session删除属性" + httpSessionBindingEvent.getName());
    }
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("监听到session修改属性" + httpSessionBindingEvent.getName() + "=" +httpSessionBindingEvent.getValue());
    }
}

/*
监听到session添加属性age=10
监听到session修改属性age=10
监听到session删除属性age
处理完毕
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.setAttribute("age",10);
        session.setAttribute("age",20);
        session.removeAttribute("age");
        System.out.println("处理完毕");
    }

ServletRequestListener监听器(常用)

作用:
        监听Request创建或销毁,即Request生命周期监听
        可以用来监控,某个IP访问我们网站的频率,日志记录,访问资源的情况

相关方法:

void requestInitialized(ServletRequestEvent sre)        创建request时
void requestDestroyed(ServletRequestEvent sre)       销毁request时

public class HspRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("监听到request对象被销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("监听到request对象创建");
        ServletRequest servletRequest = servletRequestEvent.getServletRequest();
        System.out.println("记录访问日志...");
        System.out.println("访问IP=" + servletRequest.getRemoteAddr());
        System.out.println("访问的资源=" + ((HttpServletRequest)servletRequest).getRequestURL());
    }
}

ServletRequestAttributeListener监听器

作用:
        监听Request属性变化

相关方法:

void attributeAdded(ServletRequestAttributeEvent srae)             添加属性时
void attributeReplaced(ServletRequestAttributeEvent srae)        替换属性时
void attributeRemoved(ServletRequestAttributeEvent srae)        移除属性时

过滤器Filter

介绍

Filter 过滤器是 JavaEE 的规范,是接口

Filter 过滤器作用是:拦截请求,过滤响应

应用场景:权限检查、日记操作、事务管理

为什么需要过滤器

基本原理

在web.xml中,filter一般写在其他servlet的前面

应用

web.xml

    <filter>
        <filter-name>ManageFilter</filter-name>
        <filter-class>ManageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ManageFilter</filter-name>
        <!--
        /manage/*   第一个/解析成http://ip:port/工程路径
        当请求的资源url满足该条件时,就会调用该filter
        -->
        <url-pattern>/manage/*</url-pattern>
    </filter-mapping>

登录

public class logincheck extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        if("123456".equals(pwd)) {
            request.getSession().setAttribute("username",username);
            //请求转发不会经过 过滤器
            request.getRequestDispatcher("/manage/admin.jsp").forward(request,response);
        } else {
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
    }
}

admin.jsp

浏览器第一次请求结束,发送第二次请求<img>,会调用dofilter()

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hi</title>
    <base href="<%=request.getContextPath()%>/manage/">
</head>
<body>
<h1>admin目录下的 hi.jsp</h1>
<h1>后台管理</h1>
<a href="#">用户列表</a>||<a href="#">添加用户</a>||<a href="#">删除用户</a>
<hr/>
<img src="abc.png" height="400px"/>
</body>
</html>

过滤器

public class ManageFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //当Tomcat创建Filter后,就会调用该方法,进行初始化
        System.out.println("init被调用");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //到每次调用该filter时,doFilter就会被调用

        //如果这里,没有调用继续请求的方法,则就停止
        //如果继续访问目标资源-> 等价于放行

        //老师说明:在调用过滤器前,servletRequest对象=request已经被创建并封装
        //所以:我们这里就可以通过servletRequest获取很多信息, 比如访问url , session
        //比如访问的参数 ... 就可以做事务管理,数据获取,日志管理等
        //获取到session
        //可以继续使用 httpServletRequest 方法.
        System.out.println("doFiter被调用");
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object username = session.getAttribute("username");
        if(username != null) {
            //filterChain.doFilter(servletRequest, servletResponse)
            //1. 继续访问目标资源url
            //2. servletRequest 和 servletResponse 对象会传递给目标资源/文件
            //3. 一定要理解filter传递的两个对象,再后面的servlet/jsp 是同一个对象(指的是在一次http请求)
            System.out.println("servletRequest=" + servletRequest);
            System.out.println("日志信息==");
            System.out.println("访问的用户名=" + username.toString());
            System.out.println("访问的url=" + httpServletRequest.getRequestURL());
            System.out.println("访问的IP=" + httpServletRequest.getRemoteAddr());
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            //说明没有登录过,回到登录页面
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
        }


    }

    @Override
    public void destroy() {
        //当filter被销毁时,会调用该方法
        System.out.println("destroy被调用");
    }
}

过滤器url-pattern

Filter生命周期 

  • 1. filter在web项目启动时, 由tomcat 来创建filter实例, 只会创建一个,换个浏览器也是同一个
  • 2. 会调用filter默认的无参构造器, 同时会调用 init方法, 只会调用一次
  • 3. 在创建filter实例时,同时会创建一个FilterConfig对象,并通过init方法传入
  • 4. 通过FilterConfig对象,程序员可以获取该filter的相关配置信息
  • 5. 当一个http请求和该filter的的url-patter匹配时,就会调用doFilter方法
  • 6. 在调用doFilter方法时,tomcat会同时创建ServletRequest 和 ServletResponse 和 FilterChain对象, 并通过doFilter传入.
  • 7. 如果后面的请求目标资源(jsp,servlet..) 会使用到request,和 response,那么会继续传递

FilterConfig

<filter>
        <filter-name>HspFilterConfig</filter-name>
        <filter-class>com.hspedu.filter.HspFilterConfig</filter-class>
        <!--这里就是给该filter配置的参数-有程序员根据业务逻辑来设置-->
        <init-param>
            <param-name>ip</param-name>
            <param-value>127.0</param-value>
        </init-param>
        <init-param>
            <param-name>port</param-name>
            <param-value>8888</param-value>
        </init-param>
        <init-param>
            <param-name>email</param-name>
            <param-value>hsp@sohu.com</param-value>
        </init-param>
</filter>
<filter-mapping>
        <filter-name>HspFilterConfig</filter-name>
        <url-pattern>/abc/*</url-pattern>
</filter-mapping>
public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("HspFilterConfig init() 被调用..");
        //通过filterConfig 获取相关的参数
        String filterName = filterConfig.getFilterName();
        ip = filterConfig.getInitParameter("ip");
        ServletContext servletContext = filterConfig.getServletContext();
        //可以获取到该filter所有的配置参数名
        Enumeration<String> initParameterNames =
                filterConfig.getInitParameterNames();

        //遍历枚举
        while (initParameterNames.hasMoreElements()) {
            System.out.println("名字=" + initParameterNames.nextElement());
        }

        System.out.println("filterName= " + filterName);
        System.out.println("ip= " + ip);
        System.out.println("servletContext= " + servletContext);
    }

FilterChain过滤器链

 

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("AFilter---> 线程id=" +
                Thread.currentThread().getId());
        System.out.println("AFilter doFilter 的前置代码...");
        System.out.println("执行 AFilter doFilter()");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("AFilter doFilter 的后置代码...");
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("BFilter---> 线程id=" +
                Thread.currentThread().getId());
        System.out.println("BFilter doFilter 的前置代码...");
        System.out.println("执行 BFilter doFilter()");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("BFilter doFilter 的后置代码...");
    }

执行顺序取决于web.xml的配置顺序

注意事项和细节

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

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

相关文章

javase综合案例4 -- 考试系统

文章目录 一&#xff0c;项目要求二&#xff0c;创建实体类ExamItem三&#xff0c;创建考试服务类ExamService3.1 全局变量 考题列表itemList(List< ExamItem >类型)&#xff0c;答案数组answerArr (String[]类型)&#xff0c;得分score3.2 初始化方法init()3.3 打印菜单…

从0开始的算法(数据结构和算法)基础(六)

二叉树 什么是二叉树 二叉树是一种非线性数据结构(层次关系结构)&#xff0c;代表“祖先”与“后代”之间的派生关系&#xff0c;体现了“一分为二”的分治逻辑。与链表类似&#xff0c;二叉树的基本单元是节点&#xff0c;每个节点包含值、左子节点引用和右子节点引用。 首先…

人生苦短,我用 Python,AI 模型助力高效数据提取

一、前言 在网络爬虫和数据挖掘领域&#xff0c;提取网页内容是一项常见且重要的任务。无论是从新闻网站、电商平台还是社交媒体&#xff0c;获取有用的信息都是开展后续分析和应用的前提。然而&#xff0c;传统的网页内容提取需要编写大量的代码来处理和解析 HTML 文档&#…

comfyui flux

下载文本编码器&#xff0c;模型放到ComfyUI/models/clip/ 下&#xff0c;t5模型可以任选其一&#xff1b;https://huggingface.co/comfyanonymous/flux_text_encoders/tree/main 下载vae模型&#xff0c;https://huggingface.co/black-forest-labs/FLUX.1-schnell/tree/main&a…

31、Python之面向对象:开闭原则与多态?学我者生、似我者死

引言 前面我们花了不少的篇幅把Python中面向对象的封装与继承简单介绍了一遍。今天来聊一下Python面向对象的第三个特性&#xff1a;多态。 其实&#xff0c;在《Python之面向对象&#xff1a;一切皆对象&#xff0c;可你真的需要面向对象吗》这篇文章中&#xff0c;对比面向…

Python大数据分析——朴素贝叶斯模型

Python大数据分析——朴素贝叶斯模型 数学方面思路理论基础高斯贝叶斯分类器多项式贝叶斯分类器伯努利贝叶斯分类器 代码部分高斯贝叶斯——皮肤识别多项式贝叶斯——毒蘑菇识别伯努利贝叶斯——情感分析 数学方面 思路 该分类器的实现思想非常简单&#xff0c;即通过已知类别…

vs code 代码同步到服务器,无需下载插件,使用自带ftp

可使用 vscode 自带ftp,无需下载插件 快捷键 ctrl shift p {"name": "My Server", //上传名"host": "192.168.56.102",//服务器"protocol": "ftp",//协议"port": 21,//端口"username": &q…

《机电信息》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《机电信息》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《机电信息》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;江苏省设备成套股份有限公司 主办单位&#x…

nvm安装高版本的node18.17.0,报https://nodejs.org/dist/latest/SHASUMS256.txt

1、执行npm install v18.17.0这条命令时&#xff0c;报如下错误&#xff1a; 2、或者报Node.js v18.17.0 is not yet released or is not available. 解决方案&#xff1a; 1、打开nvm 的安装路径中的setting.json node_mirror:npm.taobao.org/mirrors/node/ npm_mirror:npm.…

基于目标检测的目标跟踪(python)

文章目录 概要环境准备目标检测实现目标跟踪实现整合后的代码可能遇到的问题Could not load library libcudnn_ops_infer.so.8. Error: libcudnn_ops_infer.so.8: cannot open shared object file: No such file or directory参考概要 基于目标检测的目标跟踪过程通常包括以下…

硬控年轻人的长沙,城市底色竟是研发

近年来&#xff0c;找到“流量密码”的长沙&#xff0c;吸引了来自全国各地的年轻人&#xff0c;形成百川赴海之势。而消费生力军的到来&#xff0c;也让长沙成为新消费发展的“沃土”&#xff0c;三顿半、茶颜悦色、文和友、墨茉点心局、柠季、零食很忙等一众“顶流”新消费品…

ADC的一些细节

一&#xff0c;输入通道 总共 2 个 ADC&#xff08;ADC1&#xff0c;ADC2&#xff09;&#xff0c;每个 ADC 有 18 个转换通道: 16 个外部通道、 2 个内部通道&#xff08;温度传感器、内部参考电压&#xff09; ADC1和ADC2的通道都相同&#xff0c;是采用分时复用来…

汇凯金业:黄金交易技术分析方法

黄金交易&#xff0c;作为一种高风险、高收益的投资方式&#xff0c;需要投资者具备一定的专业知识和技能&#xff0c;才能在市场中获得收益。技术分析&#xff0c;作为一种重要的分析方法&#xff0c;可以帮助投资者判断市场趋势&#xff0c;寻找交易机会。 一、趋势分析&…

TOB拓客销售新方向全网大数据捕捉

销售开拓市场什么最重要 &#xff1f; 思考这个问题几秒钟&#xff0c;相信大家就知道了 当然是客户数据&#xff0c;只有源源不断的客户数据才有成交机会&#xff0c;所以每个企业都会遇到获客难的问题 那么今天哦我们俩围绕这个问题&#xff0c;给大家汇报一下&#xff…

5 倍网络性能提升!DigitalOcean上线全新高级内存优化型和高级存储优化型 Droplet 云主机

支持用户从想法到实现&#xff0c;再到业务不断发展过程中提供持续可靠的支持&#xff0c;这是 DigitalOcean 的核心使命。所以 DigitalOcean 也在不断推出更多专业的解决方案。 DigitalOcean Droplet 是基于虚拟化硬件上运行的虚拟机&#xff08;VM&#xff09;。用户创建的每…

使用无服务器功能的云计算成新趋势?无服务器功能的隐藏挑战

无服务器函数非常适合小任务 使用无服务器功能的云计算已广受欢迎。它们对实现新功能的吸引力源于无服务器计算的简单性。您可以使用无服务器功能来分析传入的照片或处理来自 IoT 设备的事件。它快速、简单且可扩展。您不必分配和维护计算资源 - 只需部署应用程序代码。主要的…

简单的docker学习 第11章 镜像中心

第11章 镜像中心 Docker Hub 与阿里云都是 Docker 的公网镜像中心&#xff0c;用户可以将自己的镜像 push 到公网镜像中心中自己的镜像仓库&#xff0c;并可将仓库设置为私有库&#xff0c;使他人无法看到&#xff0c;更无法 pull&#xff0c;以保证镜像的安全性。不过&#x…

云服务IaaS、PaaS、SaaS的区别

云计算有三种主要服务模式&#xff1a;基础设施级服务&#xff08;IaaS&#xff09;&#xff0c;平台级服务&#xff08;PaaS&#xff09;和软件级服务&#xff08;SaaS&#xff09;&#xff0c;它们具体是啥&#xff1f;三者之间的区别是什么&#xff1f; IaaS、PaaS、SaaS是…

WAF是什么,有什么用?

在互联网技术的飞速发展下&#xff0c;企业对网络安全的重视程度与日俱增。面对日益复杂的网络攻击和数据安全威胁&#xff0c;云WAF&#xff08;Web Application Firewall&#xff09;作为一种先进的网络安全解决方案&#xff0c;正逐渐成为企业网络安全架构中的关键组件。本文…

WEB渗透Web突破篇-WAF绕过

SQL注入分块传输 https://github.com/c0ny1/chunked-coding-converter跑注入点被拦截使用分块传输&#xff0c;右键选择使用SQLMAP跑注入>python sqlmap.py -r 1.txt --batch --proxyhttp://127.0.0.1:8080 --dbs自动提供可用的tamper Atlas https://github.com/m4ll0k/At…