监听web组件的操作。

监听人:Web应用服务器

Web监听器:ServletContext[监听应用程序环境],HttpSession[监听用户会话对象],ServletRequest[监听用户请求对象]
image.png
image.png

image.png

场景

统计在线人数

页面访问量统计

应用启动时信息初始化工作

与Spring结合

启动顺序

多个监听器按照在web.xml中编写的顺序启动,三大组件中监听器 — 过滤器 — Servlet
image.png

实现步骤

1、定义一个类,实现相应接口;
2、复写方法;
3、配置
注解使用@WebListener即可

编写类实现接口

web.xml对监听器进行注册

多监听器执行顺序与xml中的配置顺序一致,销毁时逆序。
image.png

监听器的分类

image.png
image.png

按监听器对象:

ServletContext对象监听器;

HttpSession对象监听器

ServletRequest对象监听器

按事件分类

域对象自身的创建和销毁事件监听器

ServletContextListener

ServletContextListener是ServletContext的对象监听器,有contextInitialized和contextDestroyed方法
分别在服务器启动和销毁时触发这两个方法

  1. package com.imooc.listener;
  2. import javax.servlet.ServletContextEvent;
  3. import javax.servlet.ServletContextListener;
  4. public class MyServletContextListener implements ServletContextListener {
  5. @Override
  6. public void contextDestroyed(ServletContextEvent sce) {
  7. String app_name = (String)sce.getServletContext().getAttribute("app_name");
  8. String version = (String)sce.getServletContext().getAttribute("version");
  9. System.out.println(app_name+version+"销毁中");
  10. }
  11. @Override
  12. public void contextInitialized(ServletContextEvent sce) {
  13. // 读取<context-param>中的参数
  14. String app_name = sce.getServletContext().getInitParameter("app_name");
  15. String version = sce.getServletContext().getInitParameter("version");
  16. //给sce的getServletContext属性赋值
  17. sce.getServletContext().setAttribute("app_name", app_name);
  18. sce.getServletContext().setAttribute("version", version);
  19. System.out.println("初始化"+app_name+version);
  20. }
  21. }

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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">
  3. <display-name>WebListenerDemo</display-name>
  4. <welcome-file-list>
  5. <welcome-file>index.jsp</welcome-file>
  6. </welcome-file-list>
  7. <!-- 配置相关参数 -->
  8. <context-param>
  9. <param-name>version</param-name>
  10. <param-value>1.0</param-value>
  11. </context-param>
  12. <context-param>
  13. <param-name>app_name</param-name>
  14. <param-value>MyServletContextListener</param-value>
  15. </context-param>
  16. <listener>
  17. <!-- 将类注册到xml -->
  18. <listener-class>com.imooc.listener.MyServletContextListener</listener-class>
  19. </listener>
  20. </web-app>

HttpSessionListener

sessionCreated和sessionDestroyed方法
MyHttpSessionListener.java

  1. package com.imooc.listener;
  2. import java.util.Date;
  3. import javax.servlet.http.HttpSessionEvent;
  4. import javax.servlet.http.HttpSessionListener;
  5. public class MyHttpSessionListener implements HttpSessionListener {
  6. @Override
  7. public void sessionCreated(HttpSessionEvent se) {
  8. String sessionId = se.getSession().getId();
  9. Date createTime = new Date(se.getSession().getCreationTime());
  10. System.out.println("session创建啦,ID为"+sessionId+";创建时间为"+createTime);
  11. }
  12. @Override
  13. public void sessionDestroyed(HttpSessionEvent se) {
  14. String sessionId = se.getSession().getId();
  15. System.out.println("销毁啦,id为"+sessionId);
  16. }
  17. }

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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">
  3. <display-name>WebListenerDemo</display-name>
  4. <welcome-file-list>
  5. <welcome-file>index.jsp</welcome-file>
  6. </welcome-file-list>
  7. <!-- 配置相关参数 -->
  8. <context-param>
  9. <param-name>version</param-name>
  10. <param-value>1.0</param-value>
  11. </context-param>
  12. <context-param>
  13. <param-name>app_name</param-name>
  14. <param-value>MyServletContextListener</param-value>
  15. </context-param>
  16. <listener>
  17. <!-- 将类注册到xml -->
  18. <listener-class>com.imooc.listener.MyServletContextListener</listener-class>
  19. </listener>
  20. <listener>
  21. <!-- 将类注册到xml -->
  22. <listener-class>com.imooc.listener.MyHttpSessionListener</listener-class>
  23. </listener>
  24. <session-config>
  25. <!-- 设置session的有效期为1分钟,即1分钟之后自动销毁,这里的timeout值好像不能设置小于1 -->
  26. <session-timeout>1</session-timeout>
  27. </session-config>
  28. </web-app>

创建session得有访问,可以在index.jso设置一个hello world文本,然后设置为欢迎页面,127.0.0.1:8080/项目名称 即可访问,到了1分钟之后之后,会自动销毁session对象

  1. session创建啦,ID39A692A9E7637EA98A56079432F89283;创建时间为Thu Jul 02 23:17:51 CST 2020
  2. 销毁啦,id6A74C3D4DC2A259A346CD44514356E9E

ServletReuestListener

有两个方法,requestInitialized和requestDestroyed。
MyServletRequestListener.java

  1. package com.imooc.listener;
  2. import javax.servlet.ServletRequestEvent;
  3. import javax.servlet.ServletRequestListener;
  4. import javax.servlet.http.HttpServletRequest;
  5. public class MyServletRequestListener implements ServletRequestListener {
  6. @Override
  7. public void requestDestroyed(ServletRequestEvent sre) {
  8. }
  9. @Override
  10. public void requestInitialized(ServletRequestEvent sre) {
  11. HttpServletRequest request =(HttpServletRequest)sre.getServletRequest();
  12. System.out.println("请求地址的类型为"+request.getRequestURL().getClass());
  13. StringBuffer path = request.getRequestURL();
  14. String par = request.getParameter("par");
  15. System.out.println("请求地址为"+path);
  16. System.out.println("请求参数par为"+par);
  17. }
  18. }

web.xml

  1. <listener>
  2. <!-- 将类注册到xml -->
  3. <listener-class>com.imooc.listener.MyServletRequestListener</listener-class>
  4. </listener>

这里的监听器,只要注册到xml文件中,每次都会监听到

域对象中属性的创建、替换和消除事件监听器

共同的方法:attributeAdded,attributeReplaced,attributeRemoved

ServletContextAtributeListener

MyServletContextAttributeListener.java

  1. /**
  2. *
  3. */
  4. package com.imooc.listener;
  5. import javax.servlet.ServletContextAttributeEvent;
  6. import javax.servlet.ServletContextAttributeListener;
  7. /**
  8. * @author Juha Wu
  9. *
  10. */
  11. public class MyServletContextAttributeListener implements ServletContextAttributeListener {
  12. @Override
  13. public void attributeAdded(ServletContextAttributeEvent scae) {
  14. System.out.println("添加属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());
  15. }
  16. @Override
  17. public void attributeRemoved(ServletContextAttributeEvent scae) {
  18. System.out.println("移除属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());
  19. }
  20. @Override
  21. public void attributeReplaced(ServletContextAttributeEvent scae) {
  22. System.out.println("替换属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());
  23. }
  24. }

web.xml

  1. <listener>
  2. <!-- 将类注册到xml -->
  3. <listener-class>com.imooc.listener.MyServletContextAttributeListener</listener-class>
  4. </listener>

test.jsp

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <%
  7. application.setAttribute("ServletContextPar", "我是测试属性啦");
  8. %>
  9. <meta charset="utf-8">
  10. <title></title>
  11. </head>
  12. <body>
  13. </body>
  14. </html>

访问这个test.jsp,打印结果如下

  1. 添加属性,属性名为org.apache.jasper.runtime.JspApplicationContextImpl属性值为org.apache.jasper.runtime.JspApplicationContextImpl@78436fdd
  2. 添加属性,属性名为org.apache.jasper.compiler.ELInterpreter属性值为org.apache.jasper.compiler.ELInterpreterFactory$DefaultELInterpreter@a68bb45
  3. 添加属性,属性名为ServletContextPar属性值为我是测试属性啦

HttpSessionAttributeListener

ServletRequestAttributeListener

绑定到session中的某个对象的状态事件监听器

HttpSessionBindingListener

当监听器对象绑定之HTTP会话调用
当监听器对象从HTTP会话内修改、移除或会话销毁时调用
不需要在web.xml中注册
**
model.User.java

  1. /**
  2. *
  3. */
  4. package model;
  5. import javax.servlet.http.HttpSessionBindingEvent;
  6. import javax.servlet.http.HttpSessionBindingListener;
  7. /**
  8. * @author Juha Wu
  9. *
  10. */
  11. public class User implements HttpSessionBindingListener {
  12. private String username;
  13. private String password;
  14. @Override
  15. public void valueBound(HttpSessionBindingEvent hsbe) {
  16. String name = hsbe.getName();
  17. System.out.println("绑定属性session对象,名称为"+name);
  18. }
  19. @Override
  20. public void valueUnbound(HttpSessionBindingEvent hsbe) {
  21. String name = hsbe.getName();
  22. System.out.println("解绑属性session对象,名称为"+name);
  23. }
  24. }

test.jsp

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <%
  7. session.setAttribute("ServletContextPar", new model.User());
  8. %>
  9. <meta charset="utf-8">
  10. <title></title>
  11. </head>
  12. <body>
  13. <%
  14. session.removeAttribute("ServletContextPar");
  15. %>
  16. </body>
  17. </html>

访问test.jsp
结果如下

  1. 绑定属性session对象,名称为ServletContextPar
  2. 解绑属性session对象,名称为ServletContextPar

总结

注册xml文件只需要注册class,不需要注册mapping;
HttpSessionBindingListener不需要注册。