JavaWeb——Listener监听器

JavaWeb——Listener监听器

 1、前言

  在看Listener监听器之前,首先先来看一下一个Web程序的基础架构。

在这里插入图片描述

  Listener监听器正是根据此架构,分为了三类。

  ● ServletContext的各类监听器
  ● HttpSession的各类监听器
  ● ServletRequest的各类监听器

  编写监听器的方法比较简单,大体分为两个步骤

  ● 实现监听接口
    public class ListenerClass implements ListenerInterface {}
  ● 在部署文件描述文件中指定监听接口的实现类
    <listener>
      <listener-class>fully-qualified listener class</listener-class>
    </listener>

 2、应用级监听器(监听ServletContext)

  2.1.应用级监听器的分类
   ● ServletContextListener能对ServletContext的创建和销毁做出响应。

在这里插入图片描述

   ● ServletContextAttributeListener会响应ServletContext范围的属性被添加,删除或者替换。

在这里插入图片描述

  2.2.实例
	public class AppServletContextListener implements ServletContextListener, ServletContextAttributeListener {
	
	    @Override
	    public void contextInitialized(ServletContextEvent sce) {
	        System.out.println("应用程序的ServletContext初始化啦");
	    }
	
	    @Override
	    public void contextDestroyed(ServletContextEvent sce) {
	        System.out.println("应用程序的ServletContext销毁啦");
	    }
	
	    @Override
	    public void attributeAdded(ServletContextAttributeEvent event) {
	        System.out.println("应用程序的ServletContext的属性新增:"+event.getName()+"="+event.getValue());
	    }
	
	    @Override
	    public void attributeRemoved(ServletContextAttributeEvent event) {
	        System.out.println("应用程序的ServletContext的属性移除:"+event.getName()+"="+event.getValue());
	    }
	
	    @Override
	    public void attributeReplaced(ServletContextAttributeEvent event) {
	        System.out.println("应用程序的ServletContext的属性替换:"+event.getName()+"="+event.getValue());
	    }
	}
   简单的打印相关信息,当ServletContext创建时会调用contextInitialized(),销毁时会调用contextDestroyed(),ServletContext中的属性(ServletContext中通过setAttribute()/getAttribute()存放整个Web应用程序的共享数据),这些共享属性的创建、更新、销毁就与ServletContextAttributeListener 接口中的方法相关。
  2.3.应用级监听器的使用场景
   ● 应用全局共享数据加载
   ● 监听容器初始化和销毁时机,进行准备工作和清理工作
   ● 监听ServletContext的属性操作

 3、会话级监听器(监听Session)

  3.1.会话级监听器的分类
   ● HttpSessionListenern能够监听HttpSession的创建和销毁。

在这里插入图片描述

   ● HttpSessionAttributeListener和ServletContextAttributeListener类似,它会响应HttpSession范围的属性的添加,删除,替换。

在这里插入图片描述

  3.2.实例(实现Session的计数)
	public class SessionCountListener implements HttpSessionListener, ServletContextListener, HttpSessionAttributeListener {
	
	    @Override
	    public void contextInitialized(ServletContextEvent sce) {
	        // 先实现ServletContextListener
	        // 应用程序启动时,默认的session数量是0——设置全局变量
	        ServletContext context = sce.getServletContext();
	        context.setAttribute("session_count",0);
	    }
	
	    @Override
	    public void contextDestroyed(ServletContextEvent sce) {
	        // 应用程序停止时,移除session_count属性
	        ServletContext context = sce.getServletContext();
	        context.removeAttribute("session_count");
	    }
	
	    @Override
	    public void sessionCreated(HttpSessionEvent se) {
	        ServletContext context = se.getSession().getServletContext();
	        // 当应用程序建立一个会话(session),session_out+1
	        Integer sessionCount = Integer.parseInt(String.valueOf(
	                context.getAttribute("session_count")));
	        sessionCount++;
	        context.setAttribute("session_count",sessionCount);
	        System.out.println("HttpSession 创建啦");
	    }
	
	    @Override
	    public void sessionDestroyed(HttpSessionEvent se) {
	        ServletContext context = se.getSession().getServletContext();
	        // 当应用程序关闭一个会话(session),session_out+1
	        Integer sessionCount = Integer.parseInt(String.valueOf(
	                context.getAttribute("session_count")));
	        sessionCount--;
	        context.setAttribute("session_count",sessionCount);
	        System.out.println("HttpSession 销毁啦");
	    }
	
	
	    @Override
	    public void attributeAdded(HttpSessionBindingEvent event) {
	        System.out.println("应用程序会话的属性新增:"+event.getName()
	            +"="+event.getValue());
	    }
	
	    @Override
	    public void attributeRemoved(HttpSessionBindingEvent event) {
	        System.out.println("应用程序会话的属性移除:"+event.getName()
	                +"="+event.getValue());
	    }
	
	    @Override
	    public void attributeReplaced(HttpSessionBindingEvent event) {
	        System.out.println("应用程序会话的属性替换:"+event.getName()
	                +"="+event.getValue());
	    }
	}

   会话级监听器就是与用户相关联,其他操作与ServletContext一样,只不过对象此时换为了Session。

 4、请求级监听器

  4.1.请求级监听器的分类
   ● ServletRequestListener监听器会对ServletRequest的创建和销毁事件进行响应。由于容器不可能对每一个请求都开辟一块新的内存空间(太占内存了),因此,容器会通过一个池子来存放并复用多个ServletRequest,ServletRequest的创建时从容器池里被分配出来的时刻开始,而它的销毁时刻是放回容器池里的时间。
   ●ServletRequestAttributeListener会响应ServletRequest范围的属性被添加,删除,或者替换
  4.2.举例(计算一个Request的时间)
	public class RequestCastTimeListener implements ServletRequestListener, ServletRequestAttributeListener {
	
	    @Override
	    public void requestInitialized(ServletRequestEvent sre) {
	        System.out.println("应用程序请求初始化啦");
	
	        long startTime = System.currentTimeMillis();
	        sre.getServletRequest().setAttribute("startTime",startTime);
	    }
	
	    @Override
	    public void requestDestroyed(ServletRequestEvent sre) {
	        System.out.println("应用程序请求销毁啦");
	
	        long endTime = System.currentTimeMillis();
	        long startTime = (long) sre.getServletRequest().getAttribute("startTime");
	
	        String url = ((HttpServletRequest)sre.getServletRequest()).getRequestURI();
	        System.out.println("请求:"+url+"花费了"+(endTime-startTime)+"ms");
	    }
	
	    @Override
	    public void attributeAdded(ServletRequestAttributeEvent srae) {
	        System.out.println("应用程序请求的属性新增:"+srae.getName()
	                +"="+srae.getValue());
	    }
	
	    @Override
	    public void attributeRemoved(ServletRequestAttributeEvent srae) {
	        System.out.println("应用程序请求的属性移除:"+srae.getName()
	                +"="+srae.getValue());
	    }
	
	    @Override
	    public void attributeReplaced(ServletRequestAttributeEvent srae) {
	        System.out.println("应用程序请求的属性更新:"+srae.getName()
	                +"="+srae.getValue());
	    }
	}

 5、总结

  由于容器会通过一个池子来存放并复用多个ServletRequest用来解决多次调用的内存问题(见4.1),因此Web程序的基本架构就变为了下图:

在这里插入图片描述

  监听器本身并不难理解,只需要记住三种监听器的使用即可,最后用一张图总结一下三种监听器的区别与应用场景。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值