监听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 {
@Override
public 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+"销毁中");
}
@Override
public 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 {
@Override
public void sessionCreated(HttpSessionEvent se) {
String sessionId = se.getSession().getId();
Date createTime = new Date(se.getSession().getCreationTime());
System.out.println("session创建啦,ID为"+sessionId+";创建时间为"+createTime);
}
@Override
public 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 {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
}
@Override
public 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 {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("添加属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("移除属性,属性名为"+scae.getName()+"属性值为"+scae.getValue());
}
@Override
public 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;
@Override
public void valueBound(HttpSessionBindingEvent hsbe) {
String name = hsbe.getName();
System.out.println("绑定属性session对象,名称为"+name);
}
@Override
public 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不需要注册。