【监听器入门】javaweb常用技术,你不得不知道

简介: 我们学习了过滤器,这次学习的监听器与过滤器作用十分相似。

前言


上一篇博客我们学习了过滤器,这次学习的监听器与过滤器作用十分相似,对于过滤器不了解可以先去看看上一篇博客。


传送门:【过滤器入门】学会使用过滤器,为你的web项目添砖加瓦


接下来我们正式开始学习监听器。


什么是监听器?

监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象。


当被监视的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。


对于监听器:


(1)监听器(Listener)是J2EE Servlet模板下的组件。

(2)Listener的作用是对Web应用对象的行为进行监控。

(3)通过Listener监听自动触发指定的功能代码。


上面提到了Listener的作用是对Web应用对象进行监控,他经常监听的三种对象有:


(1)ServletContext:对全局对象ServletContext及属性进行监听。

(2)HttpSession:对用户会话及其属性操作进行监听。

(3)ServletRequest:对请求及属性操作进行监听。


之前也学过过滤器,那么它们的区别是什么呢?


(1)过滤器(Filter)的职责是对URL进行过滤拦截,是主动的执行。

(2)监听器(Listener)的职责是对Web对象进行监听,是被动的触发。


开发一个监听器

开发一个监听器都要经过以下三个步骤:


(1)实现XXXListener接口,不同接口对应不同监听对象。

(2)实现每个接口中独有的方法,实现触发监听的后续操作。

(3)在web.xml中配置使监听器生效。


接下来我们就来开发一个简单的监听器。


我们对全局变量ServletContext进行监听。在实现接口之后我们需要重写里面的两个方法分别是对象初始化时侯和销毁时候调用的。我们给其中先写上简单的打印即可。

public class FirstListener implements ServletContextListener{
  @Override
  public void contextDestroyed(ServletContextEvent arg0) {
  // TODO Auto-generated method stub
  System.out.println("ServletContext已销毁!");
  }
  @Override
  public void contextInitialized(ServletContextEvent arg0) {
  // TODO Auto-generated method stub
  System.out.println("ServletContext已初始化!");  
  }
}


在写完监听器的代码之后我们对监听器在web.xml中对其进行配置。

com.imooc.listener.FirstListener

 

或者我们也可以使用注解形式进行配置,只需要在实现接口函数的上方写上@WebListener即可。如下:

image.png


之后我们启动这个监听器。可以看到在启动Servlet的时候它执行了初始化的那个函数中的代码,进行了初始化。

image.png

在我们关闭服务器之后会发现它,执行了销毁代码块中的代码。

image.png


内置对象监听器

之前说了监听器经常监听的三种对象有:


(1)ServletContext:对全局对象ServletContext及属性进行监听。

(2)HttpSession:对用户会话及其属性操作进行监听。

(3)ServletRequest:对请求及属性操作进行监听。


在监听器中有专属的内置对象监听接口来对它们进行监听。


其中有三个接口是对它们的对象进行监听的,如下:


(1)ServletContextListener:监听ServletContext对象的创建、销毁等操作。

(2)HttpSessionListener:监听HttpSession对象的创建、销毁等操作。

(3)ServletRequestListener:监听HttpServletRequest对象创建、销毁等


还有三个接口是对他们的属性进行监听的,如下:


(1)ServletContextAttributeListener:监听全局属性操作。

(2)HttpSessionAttributeListener:监听用户会话属性操作。

(3)ServletRequestAttributeListener:监听请求属性操作。


我们在书写监听器的时候如果有需求实现多个监听器接口即可。


案例演示

我们最后来做一个案例,对于请求进行监听。统计出每分钟请求的次数。


写一个监听器,实现对应接口。对请求的url进行分析是不是我们要拦截的url,然后获取当前请求的时间进行记录。如果这个时间存在那么直接给这个时间的次数加1即可。

public class RequestTotalListener implements ServletContextListener, ServletRequestListener{
  @Override
  public void requestDestroyed(ServletRequestEvent sre) {
  }
  @Override
  public void requestInitialized(ServletRequestEvent sre) {
  HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();
  String url = request.getRequestURI().toString();
  if(url.endsWith("rt") == true) {
    return;
  }
  // TODO Auto-generated method stub
  List timeList = (List)sre.getServletContext().getAttribute("timeList");
  List valueList = (List)sre.getServletContext().getAttribute("valueList");
  Date date = new Date();
  SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
  String time = sdf.format(date);
  if(timeList.indexOf(time) == -1) {
    timeList.add(time);
    valueList.add(1);
    sre.getServletContext().setAttribute("timeList", timeList);
    sre.getServletContext().setAttribute("valueList", valueList);
  }else {
    int index = timeList.indexOf(time);
    int value = valueList.get(index);
    valueList.set(index, value + 1);
    sre.getServletContext().setAttribute("valueList", valueList);
  }
  }
  @Override
  public void contextDestroyed(ServletContextEvent sce) {
  // TODO Auto-generated method stub
  }
  @Override
  public void contextInitialized(ServletContextEvent sce) {
  // TODO Auto-generated method stub
  List timeList = new ArrayList();
  List valueList = new ArrayList();
  sce.getServletContext().setAttribute("timeList", timeList);
  sce.getServletContext().setAttribute("valueList", valueList);
  }
}


在写一个Servlet,监听器监听出来的数据进行统计处理。

@WebServlet("/rt")
public class RequestTotalServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  ServletContext context = request.getServletContext();
  List timeList = (List)context.getAttribute("timeList");
  List valueList = (List)context.getAttribute("valueList");
  response.setContentType("text/html;charset=utf-8");
  response.getWriter().println(timeList.toString());
  response.getWriter().println("
");
  response.getWriter().println(valueList.toString());
  }
}



输出如下:

image.png

监听成功!


结语

与过滤器一样内容比较少,但是用处比较大,也是重点内容。


相关文章
|
6天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
32 7
|
11天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
27 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
7天前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
6天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
23天前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
25天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
1月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
1月前
|
JSON 前端开发 JavaScript
java-ajax技术详解!!!
本文介绍了Ajax技术及其工作原理,包括其核心XMLHttpRequest对象的属性和方法。Ajax通过异步通信技术,实现在不重新加载整个页面的情况下更新部分网页内容。文章还详细描述了使用原生JavaScript实现Ajax的基本步骤,以及利用jQuery简化Ajax操作的方法。最后,介绍了JSON作为轻量级数据交换格式在Ajax应用中的使用,包括Java中JSON与对象的相互转换。
43 1
|
1月前
|
存储 安全 Java
🌟Java零基础-反序列化:从入门到精通
【10月更文挑战第21天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
72 5
|
1月前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
34 1