【监听器入门】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

监听成功!


结语

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


相关文章
|
7天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
7天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
18天前
|
Java API
Java技术体系
Java技术体系包括运行于Java虚拟机上的各种语言及其相关程序,传统上由Java程序设计语言、Java虚拟机、Class文件格式、Java API类库以及第三方类库组成,可进一步细分为Java Card、Java ME、Java SE和Java EE四个平台。
32 3
Java技术体系
|
8天前
|
存储 负载均衡 Java
Jetty技术深度解析及其在Java中的实战应用
【9月更文挑战第3天】Jetty,作为一款开源的、轻量级、高性能的Java Web服务器和Servlet容器,自1995年问世以来,凭借其卓越的性能、灵活的配置和丰富的扩展功能,在Java Web应用开发中占据了举足轻重的地位。本文将详细介绍Jetty的背景、核心功能点以及在Java中的实战应用,帮助开发者更好地理解和利用Jetty构建高效、可靠的Web服务。
22 2
|
13天前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
8天前
|
SQL JSON JavaScript
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
Vue 指令、生命周期、this和$、vue脚手架进行模块化开发/ElementUI框架、综合案例,element商品列表展示增删改查
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
|
12天前
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
|
17天前
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
|
2天前
|
Kubernetes Cloud Native Java
探索未来编程新纪元:Quarkus带你秒建高性能Kubernetes原生Java应用,云原生时代的技术狂欢!
Quarkus 是专为 Kubernetes 设计的全栈云原生 Java 框架,凭借其轻量级、快速启动及高效执行特性,在 Java 社区脱颖而出。通过编译时优化与原生镜像支持,Quarkus 提升了应用性能,同时保持了 Java 的熟悉度与灵活性。本文将指导你从创建项目、编写 REST 控制器到构建与部署 Kubernetes 原生镜像的全过程,让你快速上手 Quarkus,体验高效开发与部署的乐趣。
9 0
|
9天前
|
Java 程序员
Java中的异常处理:从入门到精通
在Java编程的世界中,异常处理是保持程序稳定性和可靠性的关键。本文将通过一个独特的视角—把异常处理比作一场“捉迷藏”游戏—来探讨如何在Java中有效管理异常。我们将一起学习如何识别、捕捉以及处理可能出现的异常,确保你的程序即使在面对不可预见的错误时也能优雅地运行。准备好了吗?让我们开始这场寻找并解决Java异常的冒险吧!