• 监听器 web listener


    监听器:简单点说就是对web环境的监听

    监听器分为三大类
    1、数据域对象创建和销毁 监听器
    2、数据域对象 属性变更监听器 
    3、绑定到Session中数据对象 本身状态监听器


        主要有三类:
            1.ServletContext:对servlet上下文(application对象)进行监听
            2.Session:对session监听
            3.Request:对request的监听
    主要是:ServeltContext.Session的监听
    在WEB端实现监听实质:

    实现一系列的监听接口(实现相应的接口,覆写各接口中相应的方法,在相应的事件触发的时候会执行自己的监听器中的覆写的方法,在各个方法中完成自己想要的操作,从而实现了监听)

    监听--就是在进行某种各个范围(application,session,request)中有相关值的设置、修改、替换的时候,这些操作都会触发事件,而java中事件的代理机制,事件处理是利用listener机制,所以为了在事件触发的时候能够使自己能够采取相应的措施,就需要---->继承这样的listener,在listener中覆写相应的方法,覆写相应的事件处理方法,在对应的方法中处理对应的事件,也就是进行了监听

    对ServletContext的监听
            ServletContext---javax.servlet.ServletContext
        1.ServletContextListener---对整个Servlet上下文进行监听(启动、销毁)
            public void contextInitialized(ServletConfigEvent sce)---上下文初始化
            public    void    contextDestroyed(ServletConfigEvent  sce)--上下文的销毁
        ServletConfigEvent
            public ServletContext getServletContext()--就是取得application对象

        2.ServletContextAttributeListener---对Servlet上下文的属性的监听
            public void attributeAdded(ServletContextAttributeEvent scab):增加属性
            public void attributeRemoved(ServletContextAttributeEvent scab) :移除属性
            public void attributeReplaced(ServletContextAttributeEvent scab) :替换属性(第二次设置统一属性的值)
            
            ServletContextAttributeEvent
                public java.lang.String getName()---得到属性的名称
                public java.lang.Object getValue()--得到属性的值
                与setAttribute(String name,Object value)是对应的

      web.xml中的配置 ---跟过滤器一样是组件式的工作方式
    1.  
      <listener>
    2.  
      <listener-class>****</listener-class>
    3.  
      </listener>

    上下文监听(ServletContext监听)主要是针对容器的初始化、容器销毁、属性操作
    session监听是对session的创建、销毁和属性操作
        session是HTTP写一下的类容,所以是javax.servlet.http包中
        
        javax.servlet.http  Interface HttpSessionListener
            public void sessionCreated(HttpSessionEvent se)---session创建
            public void sessionDestroyed(HttpSessionEvent se)---session销毁
            
            HttpSessionEvent
                public HttpSessionEvent(HttpSession source)--取得当前的session
        javax.servlet.http Interface HttpSessionAttributeListener
            --public void attributeAdded(HttpSessionBindingEvent se)
            --public void attributeRemoved(HttpSessionBindingEvent se)
            --public void attributeReplaced(HttpSessionBindingEvent se)
            javax.servlet.http Class HttpSessionBindingEvent
                --public HttpSession getSession()
                --public java.lang.String getName()
                --public java.lang.Object getValue()
    页面中:session.setAttribute()触发了两个事件----session创建和属性增加

    session销毁有两种方式:
    1.session超时(web.xml)
        ·<session-config>
            <time-out>时间</time-out>  #单位为分钟,在达到这个时间之后session失效,并触发sessionDestroyed事件
        </session-config>
    2.手动使session失效
        invalidate()---session.invalidate()手动调用invalidate方法使session失效
    二者都会使session失效,并触发sessionDestroyed事件----这就是我们使用的“注销”

    监听器的使用案例:
        统计当前在线人员

    Servlet 规范中定义了很多监听器,用于监听Servlet三个数据域对象创建销毁和 内部数据状态改变
    Servlet三种存储范围:ServletContext、HttpSession、ServletRequest

    第一部分 数据域对象创建销毁监听器 --- 监听三个与对象 (三个监听器)

    1、ServletContextListener : 用来监听ServletContext对象的创建和销毁
    *contextInitialized(ServletContextEvent sce)  监听创建
    *contextDestroyed(ServletContextEvent sce)  监听销毁
    * ServletContext对象代表全局唯一对象,每个web工程会产生一个ServletContext,服务器启动创建,服务器关闭销毁
    编写监听器
    步骤一:编写类实现特定监听器接口
    步骤二:注册监听器,不是通过事件源,而是在web.xml 进行配置
    ServletContextListener主流应用:
    第一个:在服务器启动时,对一些对象进行初始化,并且将对象保存ServletContext数据范围内 --- 全局数据
    第二个:对框架进行初始化 例如:Spring框架初始化通过ServletContextListener (因为监听器代码在服务器启动时执行)
    第三个:实现任务调度,启动定时程序 (Timer、TimerTask) 使一个程序,定时执行
    java.util.Timer 一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
    Timer提供了启动定时任务方法 schedule
    * schedule(TimerTask task, Date firstTime, long period)  用来在指定一个时间启动定时器,定期循环执行
    * schedule(TimerTask task, long delay, long period)  用来在当前时间delay多少毫秒后 启动定时器
    停止定时器,timer.cancel 取消任务

    2、HttpSession 数据对象创建和销毁监听器 ----- HttpSessionListener
    * sessionCreated(HttpSessionEvent se)  监听Session对象创建
    * sessionDestroyed(HttpSessionEvent se) 监听Session对象销毁
    Session 何时创建 : request.getSession()
    Session 何时销毁 : 关闭服务器、Session过期、session.invalidate
    * Session 过期时间通过web.xml 配置,默认时间 30分钟

    3、HttpServletRequest对象的创建和销毁监听器 ---- ServletRequestListener
    * requestInitialized(ServletRequestEvent sre)  监听request对象创建
    * requestDestroyed(ServletRequestEvent sre) 监听request对象销毁
    请求发起时创建,响应结束时销毁
    问题:使用forward ---- request创建销毁几次 ----- 一次

    使用sendRedirect ---- request创建销毁两次 (两次请求)

    附上样例核心代码:

    ServletContextListener.java

    1.  
      package com.listener;
    2.  
       
    3.  
      import java.util.Timer;
    4.  
      import java.util.TimerTask;
    5.  
       
    6.  
      import javax.servlet.ServletContextEvent;
    7.  
      import javax.servlet.ServletContextListener;
    8.  
       
    9.  
      public class MyListener implements ServletContextListener{
    10.  
       
    11.  
      @Override
    12.  
      public void contextDestroyed(ServletContextEvent arg0) {
    13.  
       
    14.  
      }
    15.  
       
    16.  
      @Override
    17.  
      public void contextInitialized(ServletContextEvent arg0) {
    18.  
       
    19.  
      final Timer time=new Timer();
    20.  
      // long firstTime=1000*10;
    21.  
      // long period=1000*3;
    22.  
      //
    23.  
      // time.schedule(new TimerTask(){
    24.  
      // int i=0;
    25.  
      // @Override
    26.  
      // public void run() {
    27.  
      // i++;
    28.  
      // System.out.println("计时器");
    29.  
      // if(i==3)
    30.  
      // time.cancel();
    31.  
      // }
    32.  
      // }, firstTime, period);
    33.  
       
    34.  
      time.schedule(new TimerTask(){
    35.  
       
    36.  
      @Override
    37.  
      public void run() {
    38.  
      System.out.println("计时器");
    39.  
      }
    40.  
      }, 1000*3);
    41.  
       
    42.  
      }
    43.  
       
    44.  
      }

    第二部分 ServletContext/HttpSession/ServletRequest中保存数据 创建、修改、移除监听器
    ServletContextAttributeListener  监听ServletContext中属性变化
    HttpSessionAttributeListener  监听HttpSession中属性变化
    ServletRequestAttributeListener 监听ServletRequest中属性变化
    attributeAdded 监听属性添加 ---- 当数据范围对象没有该属性,第一次添加时调用执行 setAttribute(name,value);
    attributeRemoved  监听属性移除 ---- 从一个数据范围对象删除一个已经存在属性执行 removeAttribute(name);
    attributeReplaced  监听属性替换 ----- 当一个数据范围已经存在一个属性,向数据范围添加相同名称属性,触发替换方法 --- setAttribute(name,value);

    --------------------------------------------------------------------------------------------------------------------------------------
    第三部分 被绑定Session对象,自我状态感知监听器
    被存放Session的Java对象,感知自我四种状态变化
    1、被绑定
    2、被解除绑定
    3、被钝化 ----- 数据从内存序列化硬盘
    4、被活化 ---- 数据从硬盘重新加载回内存
    HttpSessionBindingListener 实现接口的java对象,感知自己被绑定到Session或者从Session中解除绑定
    HttpSessionActivationListener 实现接口的java对象,感知从内存被钝化硬盘上,从硬盘被活化到内存中
    * 不需要配置web.xml 监听方法调用,都是由Session自主完成的

    HttpSessionBindingListener
    * valueBound(HttpSessionBindingEvent event) 绑定对象方法 ---- session.setAttribute(name,Object);
    * valueUnbound(HttpSessionBindingEvent event)  解除绑定方法 ----- session.removeAttribute() 、当Session对象销毁时,当中所有绑定对象解除绑定

    HttpSessionActivationListener
    * sessionDidActivate(HttpSessionEvent se) 感知对象被活化
    * sessionWillPassivate(HttpSessionEvent se)  感知对象被钝化
    使用场景:Session保存数据,很长一段时间没用,但是不能销毁Session对象,不想占用服务器内存资源 ----- 钝化(将服务器内存中数据序列化硬盘上)

    钝化和活化应该由tomcat服务器 自动进行 ---- 配置tomcat
    <Context>
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
    <Store className="org.apache.catalina.session.FileStore" directory="it315"/>
    </Manager>
    </Context>

    配置context有几个位置?
    1、tomcat/conf/context.xml 对所有虚拟主机 所有web工程生效
    2、tomcat/conf/Catalina/localhost/context.xml 对当前虚拟主机所有web工程生效
    3、当前工程/META-INF/context.xml 对当前工程有效

    钝化后it315目录在哪里? tomcat/work/Catalina/localhost/day18 目录中
    序列化? java对象如果向被序列化 实现Serializable ---- Bean2 实现该接口

    绑定与解除绑定的样例:

    Bean.java

    1.  
      package com.bound;
    2.  
       
    3.  
      import javax.servlet.http.HttpSessionBindingEvent;
    4.  
      import javax.servlet.http.HttpSessionBindingListener;
    5.  
       
    6.  
      public class Bean implements HttpSessionBindingListener{
    7.  
      private int id;
    8.  
      public int getId() {
    9.  
      return id;
    10.  
      }
    11.  
      public void setId(int id) {
    12.  
      this.id = id;
    13.  
      }
    14.  
      @Override
    15.  
      public void valueBound(HttpSessionBindingEvent arg0) {
    16.  
      System.out.print(id+"被绑定了");
    17.  
      }
    18.  
      @Override
    19.  
      public void valueUnbound(HttpSessionBindingEvent arg0) {
    20.  
      System.out.print(id+"被解除绑定了");
    21.  
      }
    22.  
      }
    bound.jsp
    1.  
      <%@ page language="java" import="java.util.*,com.bound.*" pageEncoding="UTF-8"%>
    2.  
       
    3.  
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    4.  
      <html>
    5.  
      <body>
    6.  
      <%
    7.  
      Bean b=new Bean();
    8.  
      b.setId(1);
    9.  
      session.setAttribute("bean",b);
    10.  
       
    11.  
      %>
    12.  
      </body>
    13.  
      </html>

    钝化与活化的例子:

    Bean2.java

    1.  
      package com.bound;
    2.  
       
    3.  
      import java.io.Serializable;
    4.  
       
    5.  
      import javax.servlet.http.HttpSessionActivationListener;
    6.  
      import javax.servlet.http.HttpSessionEvent;
    7.  
       
    8.  
      public class Bean2 implements Serializable,HttpSessionActivationListener {
    9.  
       
    10.  
      private String name;
    11.  
       
    12.  
      public String getName() {
    13.  
      return name;
    14.  
      }
    15.  
       
    16.  
      public void setName(String name) {
    17.  
      this.name = name;
    18.  
      }
    19.  
       
    20.  
      @Override
    21.  
      public void sessionDidActivate(HttpSessionEvent arg0) {
    22.  
      System.out.println(name+"被活化");
    23.  
      }
    24.  
       
    25.  
      @Override
    26.  
      public void sessionWillPassivate(HttpSessionEvent arg0) {
    27.  
      System.out.println(name+"被钝化");
    28.  
      }
    29.  
       
    30.  
      }
    write.jsp
    1.  
      <%@ page language="java" import="java.util.*,com.bound.*" pageEncoding="UTF-8"%>
    2.  
       
    3.  
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    4.  
      <html>
    5.  
       
    6.  
      <body>
    7.  
      <%
    8.  
      Bean2 b2=new Bean2();
    9.  
      b2.setName("b2");
    10.  
      session.setAttribute("bean2", b2);
    11.  
      %>
    12.  
      This is my JSP page. <br>
    13.  
      </body>
    14.  
      </html>
    read.jsp
    1.  
      <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    2.  
       
    3.  
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    4.  
      <html>
    5.  
       
    6.  
      <body>
    7.  
      读取数据:${sessionScope.bean2.name}
    8.  
      </body>
    9.  
      </html>
    还要在META_INF下建一个context.xml然后进行配置
    1.  
      <?xml version="1.0" encoding="UTF-8"?>
    2.  
      <Context>
    3.  
      <!-- 1分钟不用 进行钝化 表示1分钟 -->
    4.  
      <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
    5.  
      <!-- 钝化后文件存储位置 directory="it315" 存放到it315目录-->
    6.  
      <Store className="org.apache.catalina.session.FileStore" directory="it315"/>
    7.  
      </Manager>
    8.  
      </Context>
  • 相关阅读:
    相关博客
    读写锁
    vccode配置c++ 编译环境
    windows下内存检测工具
    定时器堆的实现的方法
    关于tcp send的再次思考
    关于一个socket在阻塞模式下是否还可以使用的实验
    windows下对socket的send和recv的超时设置,并附一个简洁明了的socket简单demo
    对于vector中高效删除中间元素的技巧
    ubuntu下后台服务的管理
  • 原文地址:https://www.cnblogs.com/flyfishing1991/p/9611095.html
Copyright © 2020-2023  润新知