IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 深度好文之Servlet技术详解(十二)完结篇之Listener监听器 -> 正文阅读

[Java知识库]深度好文之Servlet技术详解(十二)完结篇之Listener监听器

目录

一.介绍

二.ServletContext对象的生命周期监听器

三.ServletContext对象的属性操作监听器

四.HttpSession对象的生命周期监听器

五.HttpSession对象的属性操作监听器

六.HttpServletRequest对象的生命周期监听器

七.HttpServletRequest对象的属性操作监听器

八.基于注解式开发监听器

九.Filter与Listener设计模式


一.介绍

监听器用于监听 web 应用中某些对象的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态 发生变化的时候,服务器会自动调用监听器对象中的方法。
监听器分类
按监听的对象划分,可以分为:
  • ServletContext对象生命周期监听器与属性操作监听器;
  • HttpSession对象生命周期监听器与属性操作监听器;
  • ServletRequest对象生命周期监听器与属性操作监听器;

二.ServletContext对象的生命周期监听器

ServletContextListener 接口定义了 ServletContext 对象生命周期的 监听行为。
void contextInitialized(ServletContextEvent sce)
ServletContext 对象创建之后会触发该监听方法,并将ServletContext 对象传递到该方法中。
void contextDestroyed(ServletContextEvent sce)
ServletContext 对象在销毁之前会触发该监听方法,并将ServletContext 对象传递到该方法中。

?

在src下新建一个listener目录用于本篇文章的功能代码

ServletContextLifecyclelistener.java:

package com.first.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//ServletContext生命周期监听器
public class ServletContextLifecyclelistener implements ServletContextListener {
    //Code-->Implement Methods 实现接口函数

    //监听ServletContext对象创建的监听方法
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //初始化和销毁时都输出ServletContext对象地址,看看是否是同一个对象
        ServletContext sc=sce.getServletContext();
        System.out.println(sc);
        System.out.println("ServletContext Init...");
    }

    //监听ServletContext对象销毁的监听方法
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext sc=sce.getServletContext();
        System.out.println(sc);
        System.out.println("ServletContext Destroy...");
    }
}
配置web.xml:
    <listener>
        <listener-class>com.first.listener.ServletContextLifecyclelistener</listener-class>
    </listener>

输出:

启动时控制台输出 :

ServletContext Init...

注意销毁时不要直接在idea中点按钮关闭,而是去tomcat的安装目录下,点击bin目录下的shutdown.bat进行销毁。

销毁时控制台输出:

ServletContext Destroy...

且可看到控制台两次输出的对象地址都一样:

org.apache.catalina.core.ApplicationContextFacade@505077d9

三.ServletContext对象的属性操作监听器

ServletContextAttributeListener 接口定义了对于 ServletContext 对象属性操作的监听行为。
void attributeAdded(ServletContextAttributeEvent scae)
ServletContext 对象中添加属性时会触发该监听方法,并将 ServletContext 对象传递到该方法中。触发事件的方法
servletContext.setAttribute("key","value")
void attributeRemoved(ServletContextAttributeEvent scae)
当从 ServletContext 对象中删除属性时会触发该监听方法,并将ServletContext 对象传递到该方法中。
触发事件方法
servletContext.removeAttribute("key")
void attributeReplaced(ServletContextAttributeEvent scae)
当从 ServletContext 对象中属性的值发生替换时会触发该监听方法,并将 ServletContext 对象传递到该方法中。
触发事件的方法
servletContext.setAttribute("key","value")

ServletContextAttrListener.java:

package com.first.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

//ServletContext属性监听器
public class ServletContextAttrListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("-----------Start Added-------------");
        //输出键值
        System.out.println("Name:"+scae.getName()+" Value:"+scae.getValue());
        System.out.println(scae.getServletContext());
        System.out.println("------------End Added------------");
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("-----------Start Removed-------------");
        //输出键值
        System.out.println("Name:"+scae.getName()+" Value:"+scae.getValue());
        System.out.println(scae.getServletContext());
        System.out.println("------------End Removed------------");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("-----------Start Replaced-------------");
        //输出键值
        System.out.println("Name:"+scae.getName()+" Value:"+scae.getValue());
        System.out.println(scae.getServletContext());
        System.out.println("------------End Replaced------------");
    }
}

配置web.xml:

    <listener>
        <listener-class>com.first.listener.ServletContextAttrListener</listener-class>
    </listener>

?ServletContextAttrServlet.java:

package com.first.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//ServletContext属性监听器测试(Servlet
@WebServlet("/attr.do")
public class ServletContextAttrServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();
        //触发attributeAdded
        servletContext.setAttribute("key","sb");
        //触发attributeReplaced
        servletContext.setAttribute("key","brave");
        //触发attributeRemoved
        servletContext.removeAttribute("key");
    }
}

?输出:

浏览器地址访问http://localhost:8888/ajaxDemo/attr.do

控制台输出:

-----------Start Added-------------
Name:key Value:sb
org.apache.catalina.core.ApplicationContextFacade@6014fd5a
------------End Added------------
-----------Start Replaced-------------
Name:key Value:sb
org.apache.catalina.core.ApplicationContextFacade@6014fd5a
------------End Replaced------------
-----------Start Removed-------------
Name:key Value:brave
org.apache.catalina.core.ApplicationContextFacade@6014fd5a
------------End Removed------------

四.HttpSession对象的生命周期监听器

HttpSessionListener 接口定义了 HttpSession 对象生命周期的监听行为。
void sessionCreated(HttpSessionEvent se)
HttpSession 对象创建后会触发该监听方法,并将已创建HttpSession 对象传递到该方法中。
void sessionDestroyed(HttpSessionEvent se)
HttpSession 对象在销毁之前会触发该监听方法,并将要销毁的HttpSession 对象传递到该方法中。

?

?HttpSessionLifecyclelistener.java:

package com.first.listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class HttpSessionLifecyclelistener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("sessionCreated");
        System.out.println(se.getSession());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("sessionDestroyed");
        System.out.println(se.getSession());
    }
}

配置web.xml:

    <listener>
        <listener-class>com.first.listener.HttpSessionLifecyclelistener</listener-class>
    </listener>

输出:

自己启动试试吧,其中前面学的章节中(戳这里),销毁HttpSession对象时有两种方法,一是超时时间到了,二是调用了invalidate()方法。

五.HttpSession对象的属性操作监听器

HttpSessionAttributeListener 接口定义了对于 HttpSession 对象属性操作的监听行为。
void attributeAdded(HttpSessionBindingEvent se)
HttpSession 对象中添加属性时会触发该监听方法,并将HttpSession 对象传递到该方法中。
触发事件的方法
HttpSession.setAttribute("key","value")
void attributeRemoved(HttpSessionBindingEvent se)
当从 HttpSession 对象中删除属性时会触发该监听方法,并将HttpSession 对象传递到该方法中。
触发事件方法
HttpSession.removeAttribute("key")
void attributeReplaced(HttpSessionBindingEvent se)
当从 HttpSession 对象中属性的值发生替换时会触发该监听方法,并将 HttpSession 对象传递到该方法中。
触发事件的方法
HttpSession.setAttribute("key","value")

?

HttpSessionAttrListener.java:

package com.first.listener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class HttpSessionAttrListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        System.out.println("----------HttpSessionAttrListener----Start Added----------");
        System.out.println("Name: "+se.getName()+" Value: "+se.getValue());
        System.out.println(se.getSession());
        System.out.println("----------HttpSessionAttrListener----End Added----------");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.out.println("----------HttpSessionAttrListener----Start Removed----------");
        System.out.println("Name: "+se.getName()+" Value: "+se.getValue());
        System.out.println(se.getSession());
        System.out.println("----------HttpSessionAttrListener----End Removed----------");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        System.out.println("----------HttpSessionAttrListener----Start Replaced----------");
        System.out.println("Name: "+se.getName()+" Value: "+se.getValue());
        System.out.println(se.getSession());
        System.out.println("----------HttpSessionAttrListener----End Replaced----------");
    }
}

配置web.xml:

    <listener>
        <listener-class>com.first.listener.HttpSessionAttrListener</listener-class>
    </listener>

HttpSessionAttrServlet.java:

package com.first.listener;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/sessionAttr.do")
public class HttpSessionAttrServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取HttpSession对象
        HttpSession session=req.getSession();
        //触发attributeAdded
        session.setAttribute("key","brave");
        //触发attributeReplaced
        session.setAttribute("key","timid");
        //触发attributeRemoved
        session.removeAttribute("key");
    }
}

?输出:

访问http://localhost/ajaxDemo/sessionAttr.do

----------HttpSessionAttrListener----Start Added----------
Name: key Value: brave
org.apache.catalina.session.StandardSessionFacade@656b023d
----------HttpSessionAttrListener----End Added----------
----------HttpSessionAttrListener----Start Replaced----------
Name: key Value: brave
org.apache.catalina.session.StandardSessionFacade@656b023d
----------HttpSessionAttrListener----End Replaced----------
----------HttpSessionAttrListener----Start Removed----------
Name: key Value: timid
org.apache.catalina.session.StandardSessionFacade@656b023d
----------HttpSessionAttrListener----End Removed----------

六.HttpServletRequest对象的生命周期监听器

ServletRequestListener 接口定义了 ServletRequest( 是HttpServletRequest 接口的父接口类型 ) 对象生命周期的监听行为。

?

void requestInitialized(ServletRequestEvent sre)
HttpServletRequest 对象创建后会触发该监听方法,并将已创建HttpServletRequest 对象传递到该方法中。
void requestDestroyed(ServletRequestEvent sre)
HttpServletRequest 对象在销毁之前会触发该监听方法,并将要销毁 HttpServletRequest 对象传递到该方法中。
当有请求时,tomcat会创建一个servlet,故而下面的代码会执行。
HttpServletRequestLifecycleListener.java
package com.first.listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;

/**
 * 监听HttpServletRequest生命周期的监听器
 */
public class HttpServletRequestLifecycleListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("----------Start requestDestroyed------------");
        System.out.println((HttpServletRequest)sre.getServletRequest());
        System.out.println("----------End requestDestroyed------------");

    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("----------Start Initialized------------");
        System.out.println((HttpServletRequest)sre.getServletRequest());
        System.out.println("----------End Initialized------------");
    }
}

web.xml:

    <listener>
        <listener-class>com.first.listener.HttpServletRequestLifecycleListener</listener-class>
    </listener>
控制台输出:
----------Start requestDestroyed------------
org.apache.catalina.connector.RequestFacade@5f402c23
----------End requestDestroyed------------
----------Start Initialized------------
org.apache.catalina.connector.RequestFacade@5f402c23
----------End Initialized------------

七.HttpServletRequest对象的属性操作监听器

ServletRequestAttributeListener 接口定义了对于HttpServletRequest 对象属性操作的监听行为。
void attributeAdded(ServletRequestAttributeEvent srae)
HttpServletRequest 对象中添加属性时会触发该监听方法,并将HttpServletRequest 对象传递到该方法中。
触发事件的方法
HttpServletRequest.setAttribute("key","value")
void attributeRemoved(ServletRequestAttributeEvent srae)
当从 HttpServletRequest 对象中删除属性时会触发该监听方法,并将 HttpServletRequest 对象传递到该方法中。
触发事件方法
HttpServletRequest.removeAttribute("key")

?

void attributeReplaced(ServletRequestAttributeEvent srae)
当从 HttpServletRequest 对象中属性的值发生替换时会触发该监听方法,并将 HttpServletRequest 对象传递到该方法中。
触发事件的方法
HttpServletRequest.setAttribute("key","value")

HttpServletRequestAttrListener.java:

package com.first.listener;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

/**
 * HttpServletRequest对象属性监听器
 */
public class HttpServletRequestAttrListener implements ServletRequestAttributeListener {

    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.out.println("---HttpServletRequestAttrListener-----------Start Added-----------");
        System.out.println("Name: "+srae.getName()+" Value: "+srae.getValue());
        System.out.println(srae.getServletRequest());
        System.out.println("---HttpServletRequestAttrListener-----------End Added-----------");
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        System.out.println("---HttpServletRequestAttrListener-----------Start Removed-----------");
        System.out.println("Name: "+srae.getName()+" Value: "+srae.getValue());
        System.out.println(srae.getServletRequest());
        System.out.println("---HttpServletRequestAttrListener-----------End Removed-----------");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        System.out.println("---HttpServletRequestAttrListener-----------Start Replaced-----------");
        System.out.println("Name: "+srae.getName()+" Value: "+srae.getValue());
        System.out.println(srae.getServletRequest());
        System.out.println("---HttpServletRequestAttrListener-----------End Replaced-----------");
    }
}

?web.xml:

<listener>
    <listener-class>com.first.listener.HttpServletRequestAttrListener</listener-class>
</listener>

?HttpServletRequestAttrServlet.java:

package com.first.listener;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/requestAttr.do")
public class HttpServletRequestAttrServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("key","prospect");
        req.setAttribute("key","entertainment");
        req.removeAttribute("key");
    }
}

输出:

访问:http://localhost:8888/ajaxDemo/requestAttr.do

输出看控制台。

八.基于注解式开发监听器

Listener 支持注解式开发,通过 @WebListener 注解替代 web.xml 中Listener 的配置。
以本文章第一个例子为例:
把web.xml里的相应配置去了,然后顶部添加@WebListener即可,无需配置参数!

?

九.FilterListener设计模式

知其然,知其所以然
Filter 的设计模式
Servlet Filter 中使用的责任链设计模式。
责任链模式特点
责任链( Chain of Responsibility ):责任链模式也叫职责链模式,是一种对象行为模式。在责任链模式里,很多对象由每一个对象对 其下一个对象的引用而连接起来形成一条链。请求在这个链上传 递,直到链上的某一个对象决定处理此请求。发出这个请求的客户 端并不需要知道链上的哪一个对象最终处理这个请求,这使得系统 可以在不影响客户端的情况下动态地重新组织链和分配责任。

责任链的优缺点
优点:
  • 降低了对象之间的耦合度。
  • 增强了系统的可扩展性。
  • 增强了给对象指派职责的灵活性。
  • 责任链简化了对象之间的连接。
  • 责任分担。每个类只需要处理自己该处理的工作。
缺点:
  • 不能保证请求一定被接收。
  • 对比较长的责任链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 可能会由于责任链的错误设置而导致系统出错,如可能会造成循环调用。
Listener 的设计模式
Servlet Listener 中使用的观察者设计模式。
观察者模式的特点
观察者模式( Observer Pattern ):观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发 生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式的优缺点
优点:
  • 观察者和被观察者是抽象耦合的。
  • 建立一套触发机制。
缺点:
  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:26:14  更:2022-05-09 12:27:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:56:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码