前面说过javaweb中的三大组件分别:Servlet(程序),Filter(过滤器),Listener(监听器),而本篇就是简单聊监听器。
监听器顾名思义就是监听某周事件的发生,即当某个事件发生的时候就会触发某个设置条件的监控器,比如水坝的水位检测器,检测到水位到达警报位置就会通过监听器发出警报,从而选择是否放水还是需要严加观察后续水位的变化。
而JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext,HttpSession和ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。然后监听某个事件可以触发回调函数,反馈给程序去做一些响应的处理。
现在一下监听器:
request域上的监听器
ServletRequestListener 监听的request对象的接口
ServletRequestAttributeListener 监听request对象属性接口
session域上的监听器
HttpSessionListener 监听Session对象的接口
HttpSessionAttributeListener 监听Session对象属性接口
application域上的监控
ServletContextListener 监听application对象的接口
ServletContextAttributeListener 监听application对象属性接口
当然这些监听器的使用也是需要配置的,配置也是两种方式。
<listener>
<listener-class>listener-class>
listener>
通过注释进行配置
@WebListener
但是展开的时候不会以不同的域展开,因为器方法太相似了,对于所在的域的范围简单的说一下:
| 域对象 | 类 | 描述 |
|---|---|---|
| request | HttpServletRequest类 | 数据一次请求中有效 |
| session | HttpSession类 | 一个会话范围有效,通俗的说就是其生命周期是打开浏览器访问,直到浏览器关闭结束 |
| application | ServletContext类 | 整个web范围内都有效,简单的说就是web工程不关闭服务器,那其数据一致都存在. |
其方法很相似,而区别只是域的范围。所以如此解释:
| 监控器 | 描述 |
|---|---|
| ServletRequestListener | 监听request域对象 |
| HttpSessionListener | 监听Session对象 |
| ServletContextListener | 监听application对象的接口 |
然后看一下三个域对象监控器的都有什么什么方法:



可以看出这类监控器都有有两个方法监控:
但是也有不同:
域对象不同
监听的时候省的的监听事件不同;
| 域监听事件对象 | 描述 |
|---|---|
| ServletRequestEvent | ServletRequestListener的监听事件对象 |
| HttpSessionEvent | HttpSessionListener的监听事件对象 |
| ServletContextEvent | ServletContextListener的监听事件对象 |
ServletContextEvent 对象常用的方法:
getServletContext() : 返回一个ServletContext对象,所以可以使用ServletContext的方法。
HttpSessionEvent对象常用的方法:
getSession() : 返回一个HttpSession 对象,所以可以使用HttpSession 的方法。
ServletRequestEvent对象常用的方法:
getServletContext() : 返回一个ServletContext对象,所以可以使用ServletContext的方法。
getServletRequest() : 返回一个ServletRequest对象,所以可以使用ServletRequest的方法。
所以来一个例子一个域监控即可,其它可以套用,所以不多重复的事情:
package com.xzd.test;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class mylistener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("----销毁了");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("----创建了");
System.out.println(servletRequestEvent.getServletRequest().getLocalName());
System.out.println(servletRequestEvent.getServletContext().getContextPath());
}
}
这个是一个request域的监控器,所以随便请求一个servlet,然后控制台:

| 监控器 | 描述 |
|---|---|
| ServletRequestAttributeListener | 监听request对象属性接口 |
| HttpSessionAttributeListener | 监听Session对象属性接口 |
| ServletContextAttributeListener | 监听application对象属性接口 |
其实三个属性监控器的常用方法,其实很相似的,看截图

HttpSessionAttributeListener方法:

ServletContextAttributeListener 方法

可以看属性监控器的共同点:
属性监控器的不同点:
其属性监控的域不同。
其属性监控器的参数事件不同
| 域监听事件对象 | 描述 |
|---|---|
| ServletRequestAttributeEvent | ServletRequestAttributeListener的监听事件对象 |
| HttpSessionBindingEvent | HttpSessionAttributeListener的监听事件对象 |
| ServletContextAttributeEvent | ServletContextAttributeListener的监听事件对象 |
ServletRequestAttributeEvent对象常用的方法:
getName () : 返回 ServletRequest 中更改的属性的名称(String类型)。
getValue() : 返回已添加、移除或替换的属性的值。如果添加了属性,则这是属性的值。如果移除了 属性,则这是被移除属性的值。如果替换了属性,则这是属性原来的值。(Object类型)
HttpSessionBindingEvent对象常用的方法:
getName () : 返回 ServletRequest 中更改的属性的名称(String类型)。
getValue() : 返回已添加、移除或替换的属性的值。如果添加了属性,则这是属性的值。如果移除了 属性,则这是被移除属性的值。如果替换了属性,则这是属性原来的值。(Object类型)。
getSession(): 返回一个HttpSession 对象,所以可以使用HttpSession 的方法。
ServletContextAttributeEvent 对象常用的方法:
getName () : 返回 ServletRequest 中更改的属性的名称(String类型)。
getValue() : 返回已添加、移除或替换的属性的值。如果添加了属性,则这是属性的值。如果移除了 属性,则这是被移除属性的值。如果替换了属性,则这是属性原来的值。(Object类型)。
其实可以看出也是很多相似的地方,所以还是老规矩举出一个例子即可,毕竟可以套用:
首先来一个创建jsp文件:
<%@ page contentType="text/html;charset=UTF-8" isErrorPage="true" language="java" %>
test
<%
//添加了一个属性
request.setAttribute("name", "宫崎老贼");
//因为添加一个已有的属性就是修改属性
request.setAttribute("name", "骨灰啊,怜悯");
//删除属性
request.removeAttribute("name");
%>
然后再创建一个属性监控器:
package com.xzd.test;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class mylistener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("添加属性getName()---"+servletRequestAttributeEvent.getName());
System.out.println("添加属性getValue()---"+servletRequestAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("删除属性getName()---"+servletRequestAttributeEvent.getName());
System.out.println("删除属性getValue()---"+servletRequestAttributeEvent.getValue());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("修改属性getName()---"+servletRequestAttributeEvent.getName());
System.out.println("修改属性getValue()---"+servletRequestAttributeEvent.getValue());
}
}

其实可以看出再添加属性之前还输出了一个修改属性监控器,因为再添加属性的时候对于程序来说也是一种改变,只不过这个改变不是属性的改名,而是新增属性相对于没有属性来说也是一种修改。
其实聊监控器可以发现一件事情,其很多方法都相似。但是其难点就是在不同的域中使用不同的域监控。