监听web组件的操作。
监听人:Web应用服务器
Web监听器:ServletContext[监听应用程序环境],HttpSession[监听用户会话对象],ServletRequest[监听用户请求对象]


场景
统计在线人数
页面访问量统计
应用启动时信息初始化工作
与Spring结合
启动顺序
多个监听器按照在web.xml中编写的顺序启动,三大组件中监听器 — 过滤器 — Servlet
实现步骤
1、定义一个类,实现相应接口;
2、复写方法;
3、配置
注解使用@WebListener即可
编写类实现接口
web.xml对监听器进行注册
多监听器执行顺序与xml中的配置顺序一致,销毁时逆序。
监听器的分类


按监听器对象:
ServletContext对象监听器;
HttpSession对象监听器
ServletRequest对象监听器
按事件分类
域对象自身的创建和销毁事件监听器
ServletContextListener
ServletContextListener是ServletContext的对象监听器,有contextInitialized和contextDestroyed方法
分别在服务器启动和销毁时触发这两个方法
package com.imooc.listener;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;public class MyServletContextListener implements ServletContextListener {@Overridepublic void contextDestroyed(ServletContextEvent sce) {String app_name = (String)sce.getServletContext().getAttribute("app_name");String version = (String)sce.getServletContext().getAttribute("version");System.out.println(app_name+version+"销毁中");}@Overridepublic void contextInitialized(ServletContextEvent sce) {// 读取<context-param>中的参数String app_name = sce.getServletContext().getInitParameter("app_name");String version = sce.getServletContext().getInitParameter("version");//给sce的getServletContext属性赋值sce.getServletContext().setAttribute("app_name", app_name);sce.getServletContext().setAttribute("version", version);System.out.println("初始化"+app_name+version);}}
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"><display-name>WebListenerDemo</display-name><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 配置相关参数 --><context-param><param-name>version</param-name><param-value>1.0</param-value></context-param><context-param><param-name>app_name</param-name><param-value>MyServletContextListener</param-value></context-param><listener><!-- 将类注册到xml --><listener-class>com.imooc.listener.MyServletContextListener</listener-class></listener></web-app>
HttpSessionListener
sessionCreated和sessionDestroyed方法
MyHttpSessionListener.java
package com.imooc.listener;import java.util.Date;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent se) {String sessionId = se.getSession().getId();Date createTime = new Date(se.getSession().getCreationTime());System.out.println("session创建啦,ID为"+sessionId+";创建时间为"+createTime);}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {String sessionId = se.getSession().getId();System.out.println("销毁啦,id为"+sessionId);}}
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"><display-name>WebListenerDemo</display-name><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 配置相关参数 --><context-param><param-name>version</param-name><param-value>1.0</param-value></context-param><context-param><param-name>app_name</param-name><param-value>MyServletContextListener</param-value></context-param><listener><!-- 将类注册到xml --><listener-class>com.imooc.listener.MyServletContextListener</listener-class></listener><listener><!-- 将类注册到xml --><listener-class>com.imooc.listener.MyHttpSessionListener</listener-class></listener><session-config><!-- 设置session的有效期为1分钟,即1分钟之后自动销毁,这里的timeout值好像不能设置小于1 --><session-timeout>1</session-timeout></session-config></web-app>
创建session得有访问,可以在index.jso设置一个hello world文本,然后设置为欢迎页面,127.0.0.1:8080/项目名称 即可访问,到了1分钟之后之后,会自动销毁session对象
session创建啦,ID为39A692A9E7637EA98A56079432F89283;创建时间为Thu Jul 02 23:17:51 CST 2020销毁啦,id为6A74C3D4DC2A259A346CD44514356E9E
ServletReuestListener
有两个方法,requestInitialized和requestDestroyed。
MyServletRequestListener.java
package com.imooc.listener;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.http.HttpServletRequest;public class MyServletRequestListener implements ServletRequestListener {@Overridepublic void requestDestroyed(ServletRequestEvent sre) {}@Overridepublic void requestInitialized(ServletRequestEvent sre) {HttpServletRequest request =(HttpServletRequest)sre.getServletRequest();System.out.println("请求地址的类型为"+request.getRequestURL().getClass());StringBuffer path = request.getRequestURL();String par = request.getParameter("par");System.out.println("请求地址为"+path);System.out.println("请求参数par为"+par);}}
web.xml
<listener><!-- 将类注册到xml --><listener-class>com.imooc.listener.MyServletRequestListener</listener-class></listener>
域对象中属性的创建、替换和消除事件监听器
共同的方法:attributeAdded,attributeReplaced,attributeRemoved
ServletContextAtributeListener
MyServletContextAttributeListener.java
/****/package com.imooc.listener;import javax.servlet.ServletContextAttributeEvent;import javax.servlet.ServletContextAttributeListener;/*** @author Juha Wu**/public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent scae) {System.out.println("添加属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());}@Overridepublic void attributeRemoved(ServletContextAttributeEvent scae) {System.out.println("移除属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());}@Overridepublic void attributeReplaced(ServletContextAttributeEvent scae) {System.out.println("替换属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());}}
web.xml
<listener><!-- 将类注册到xml --><listener-class>com.imooc.listener.MyServletContextAttributeListener</listener-class></listener>
test.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><!DOCTYPE html><html><head><%application.setAttribute("ServletContextPar", "我是测试属性啦");%><meta charset="utf-8"><title></title></head><body></body></html>
访问这个test.jsp,打印结果如下
添加属性,属性名为org.apache.jasper.runtime.JspApplicationContextImpl属性值为org.apache.jasper.runtime.JspApplicationContextImpl@78436fdd添加属性,属性名为org.apache.jasper.compiler.ELInterpreter属性值为org.apache.jasper.compiler.ELInterpreterFactory$DefaultELInterpreter@a68bb45添加属性,属性名为ServletContextPar属性值为我是测试属性啦
HttpSessionAttributeListener
ServletRequestAttributeListener
绑定到session中的某个对象的状态事件监听器
HttpSessionBindingListener
当监听器对象绑定之HTTP会话调用
当监听器对象从HTTP会话内修改、移除或会话销毁时调用
不需要在web.xml中注册
**
model.User.java
/****/package model;import javax.servlet.http.HttpSessionBindingEvent;import javax.servlet.http.HttpSessionBindingListener;/*** @author Juha Wu**/public class User implements HttpSessionBindingListener {private String username;private String password;@Overridepublic void valueBound(HttpSessionBindingEvent hsbe) {String name = hsbe.getName();System.out.println("绑定属性session对象,名称为"+name);}@Overridepublic void valueUnbound(HttpSessionBindingEvent hsbe) {String name = hsbe.getName();System.out.println("解绑属性session对象,名称为"+name);}}
test.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><!DOCTYPE html><html><head><%session.setAttribute("ServletContextPar", new model.User());%><meta charset="utf-8"><title></title></head><body><%session.removeAttribute("ServletContextPar");%></body></html>
访问test.jsp
结果如下
绑定属性session对象,名称为ServletContextPar解绑属性session对象,名称为ServletContextPar
总结
注册xml文件只需要注册class,不需要注册mapping;
HttpSessionBindingListener不需要注册。
