JavaWeb三大组件之监听器

监听器

什么是监听器:

  1. 它是一个接口,内容由我们来实现;

  2. 它需要注册,例如注册在按钮上!

  3. 监听器中的方法,会在特殊事件发生时被调用!

JavaWeb中的监听器

ServletContext

  1. 生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
  • void contextInitialized(ServletContextEvent sce):创建Servletcontext时

  • void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时

  1. 属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
  • void attributeAdded(ServletContextAttributeEvent event):添加属性时;

  • void attributeReplaced(ServletContextAttributeEvent event):替换属性时;

  • void attributeRemoved(ServletContextAttributeEvent event):移除属性时;

HttpSession

  1. 生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
  • void sessionCreated(HttpSessionEvent se):创建session时

  • void sessionDestroyed(HttpSessionEvent se):销毁session时

  1. 属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
  • void attributeAdded(HttpSessionBindingEvent event):添加属性时;

  • void attributeReplaced(HttpSessionBindingEvent event):替换属性时

  • void attributeRemoved(HttpSessionBindingEvent event):移除属性时

ServletRequest

  1. 生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
  • void requestInitialized(ServletRequestEvent sre):创建request时

  • void requestDestroyed(ServletRequestEvent sre):销毁request时

  1. 属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
  • void attributeAdded(ServletRequestAttributeEvent srae):添加属性时

  • void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时

  • void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

javaWeb中完成编写监听器:

编写一个生命周期监听器(以ServletContext为例)

  1. 写一个监听器类:要求必须去实现ServletContextListener监听器接口;

    package cn.andios.test;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class MyServletContextListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("创建ServletContext");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("销毁ServletContext");
        }
    }
    
    
  2. 注册,是在web.xml中配置来完成注册!

    <?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>cn.andios.test.MyServletContextListener</listener-class>
        </listener>
    
    </web-app>
    
  3. 测试

    启动服务器时控制台输出了“创建ServletContext”。

    关闭服务器时控制台输出了“销毁ServletContext”

编写一个属性监听器(以ServletContext为例)

  1. 要求必须去实现ServletContextAttributeListener监听器接口;

    package cn.andios.test;
    
    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    
        //当添加属性时
        @Override
        public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
            System.out.println("向application中添加了"+servletContextAttributeEvent.getName()+"="+servletContextAttributeEvent.getValue());
        }
    
        //当移除属性时
        @Override
        public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
            System.out.println("从application中移除了"+servletContextAttributeEvent.getName()+"="+servletContextAttributeEvent.getValue());
        }
    
    
        //当替换属性时,这里得到的值是旧值
        @Override
        public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
            System.out.println("从application中替换了"+servletContextAttributeEvent.getName()+"="+servletContextAttributeEvent.getValue());
        }
    }
    
    
  2. 注册,是在web.xml中配置来完成注册!

    <!--注册ServletContext的属性监听器-->
        <listener>
            <listener-class>cn.andios.test.MyServletContextAttributeListener</listener-class>
        </listener>
    
  3. 测试

    • 当在jsp页面执行了application.setAttribute(“aaa”,“aaa”);时,控制台输出“向application中添加了aaa=aaa”
    • 当在jsp页面执行了application.setAttribute(“aaa”,“bbb”);时,控制台输出“从application中替换了aaa=aaa”
    • 当在jsp页面执行了application.removeAttribute(“aaa”);时,控制台输出“从application中移除了aaa=aaa”

HttpSession的监听器

还有两个与HttpSession相关的特殊的监听器,这两个监听器的特点如下:

  1. 不用在web.xml文件中部署;

  2. 这两个监听器不是给session添加,而是给Bean添加。即让Bean类实现监听器接口,然后再把Bean对象添加到session域中。

HttpSessionBindingListener

  1. 当某个类实现了该接口后,可以感知本类对象添加到session中,以及感知从session中移除。例如让Person类实现HttpSessionBindingListener接口,那么当把Person对象添加到session中,或者把Person对象从session中移除时会调用下面两个方法:
  • public void valueBound(HttpSessionBindingEvent event):当把监听器对象添加到session中会调用监听器对象的本方法;

  • public void valueUnbound(HttpSessionBindingEvent event):当把监听器对象从session中移除时会调用监听器对象的本方法;

  1. 测试HttpSessionBindingListener

    • 编写java类

      package cn.andios.test;
      
      import javax.servlet.http.HttpSessionBindingEvent;
      import javax.servlet.http.HttpSessionBindingListener;
      
      public class User implements HttpSessionBindingListener {
      
          @Override
          public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
              System.out.println("我添加到session中了");
          }
      
          @Override
          public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
              System.out.println("我从session中移除了");
          }
      }
      
    • 在jsp中执行application.setAttribute(“aaa”,new User());,控制台输出了“我添加到session中了”

    • 在jsp中执行session.removeAttribute(“aaa”);控制台输出了“我从session中移除了”

session序列化

  1. 当服务器启动时,向session中存入数据,重启服务器后,session中的数据居然还能取出来。这是因为,当服务器关闭时,把session对象序列化到了磁盘上。当服务器再次启动时,又把session反序列化了,所以还可以得到session中的信息。

  2. 若不想让服务器关闭时,序列化session,则在服务器的context.xml配置文件中加上<Manager pathname="">即可

session钝化

若服务器中有太多的访问用户,则占用的内存会很大。为了使内存占用不会过大,则服务器会把长时间无响应的session序列化到磁盘中(session的钝化),当用户再次活动时,再把session反序列化(session的活化)。这样就使得用户不会感受到自己掉线了。

  1. 要开启session的钝化与活化功能,则要在context.xml文件中添加

    <Context>
    	<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
    		<Store className="org.apache.catalina.session.FileStore" directory="mysession"/>
    	</Manager>
    </Context>
    
    

HttpSessionActivationListener监听器

与HttpSessionBindingListener监听器相似,都是感知型的监听器,例如让Person类实现了HttpSessionActivationListener监听器接口,并把Person对象添加到了session中后,当Tomcat钝化session时,同时也会钝化session中的Person对象,这时Person对象就会感知到自己被钝化了,其实就是调用Person对象的sessionWillPassivate()方法。当用户再次使用session时,Tomcat会活化session,这时Person会感知到自己被活化,其实就是调用Person对象的sessionDidActivate()方法。

验证

  1. 编写一个User类,实现HttpSessionActivationListener监听器口和Serializable序列化接口

    package cn.andios.test;
    
    import javax.servlet.http.HttpSessionActivationListener;
    import javax.servlet.http.HttpSessionEvent;
    import java.io.Serializable;
    
    public class User implements HttpSessionActivationListener, Serializable {
    
        private String name;
    
        private String password;
    
        public User(String name, String password) {
            this.name = name;
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    
        @Override
        public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
            System.out.println(httpSessionEvent.getSession().getAttribute("user")+"一起和session序列化到磁盘了");
        }
    
        @Override
        public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
            System.out.println(httpSessionEvent.getSession().getAttribute("user")+"一起和session活化了");
        }
    }
    
    
  2. 然后在jsp中执行session.setAttribute("user",new User("张三","123456"));

    • 等待一分钟,控制台输出“User{name=‘张三’, password=‘123456’}一起和session序列化到磁盘了”

    • 然后在继续操作页面,控制台输出“User{name=‘张三’, password=‘123456’}一起和session活化了”

    • 最后在jsp中执行

      User user=session.getAttribute("user");
      System.out.println(user)
      

      控制台会输出User{name=‘张三’, password=‘123456’}对象

  3. 注意:要使对象一起被序列化到磁盘,则必须实现Serializable接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值