Servlet监听器
监听器:专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。
servlet监听器:servlet规范中定义的一种特殊类,他用于监听web应用程序中的servletcontext,httpsession和servletrequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。
按监听的事件类型servlet监听器可分为如下三种类型:
--监听域对象自身的创建和销毁的事件监听器
--监听域对象中的属性的增加和删除的事件监听器
--监听绑定到httpsession域中的某个对象的状态的事件监听器
①:监听域对象自身的创建和销毁
监听域对象自身的创建和销毁的事件监听器就是用来监听servletcontext, httpsession,httpservletrequest这三个对象的创建和销毁事件的监听器。
域对象的创建和销毁时机:
1.1:servletContextListener接口用于监听servletContext对象的创建和销毁事件。
当servletContext对象被创建时,激发contextInitialized方法
当servletContext对象被销毁时,激发contextDestroyed方法
1.2:httpSessionListener接口用于监听httpSession对象的创建和销毁事件。
当session被创建时,激发sessionCreated方法
当session被销毁时,激发sessionDestroyed方法
1.3:servletRequestListener接口用于监听servletRequest对象的创建和销毁事件。
当servletRequest对象被创建时,激发requestInitialized方法
当servletRequest对象被销毁时,激发requestDestroyed方法
编写servlet监听器:
servlet规范为每种事件监听器都定义了相应的接口,开发人员编写的事件监听器程序只需要实现这些接口,web服务器根据用户编写的事件监听器所实现的接口把它
注册到相应的被监听对象上
一些servlet事件监听器需要在web应用程序的web.xml文件中进行注册,一个web.xml文件中可以注册多个servlet事件监听器,web服务器按照它们在web.xml中的注册
顺序来加载和注册这些servlet事件监听器。
servlet事件监听器的注册和调用过程都是由web容器自动完成的,当发生被监听的对象呗创建,修改或销毁事件时,web容器将调用与之相关的servlet事件监听器对象
的相关方法,开发人员在这些方法中编写的事件处理代码即被执行
由于一个web应用程序只会为每个事件监听器创建一个对象,有可能出现多个线程同时调用一个事件监听器对象的情况,所以,在编写事件监听器时,应考虑多线程安全的问题。
servletContextListener监听器实例:
package com.sa.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener()
public class ServletListener implements ServletContextListener {
// Public constructor is required by servlet spec
public ServletListener() {
}
// -------------------------------------------------------
// ServletContextListener implementation
// -------------------------------------------------------
public void contextInitialized(ServletContextEvent sce) {
/* This method is called when the servlet context is
initialized(when the Web application is deployed).
You can initialize servlet context related data here.
*/
System.out.println("contextInitialized");
}
public void contextDestroyed(ServletContextEvent sce) {
/* This method is invoked when the Servlet Context
(the Web application) is undeployed or
Application Server shuts down.
*/
System.out.println("contextDestroyed");
}
}
配置xml:
<listener>
<listener-class>com.sa.listener.ServletListener</listener-class>
<display-name>ServletListener</display-name>
</listener>
重新启动Tomcat:
关闭Tomcat:
servletContextListener是最常用的listener,可以在当前WEB应用被加载时对当前
WEB应用的相关资源进行初始化操作:创建数据库连接池,创建springIOC容器,
读取当前WEB应用的初始化参数。。。
servletRequestListener:
package com.sa.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener()
public class RequestListener implements ServletRequestListener {
// Public constructor is required by servlet spec
public RequestListener() {
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("requestDestroyed");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("requestInitialized");
}
}
<listener>
<listener-class>com.sa.listener.RequestListener</listener-class>
<display-name>RequestListener</display-name>
</listener>
测试:
进入http://localhost:8080/1012/pages/login.jsp
httpSessionListener:
package com.sa.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener()
public class SessionListener implements HttpSessionListener {
// Public constructor is required by servlet spec
public SessionListener() {
}
// -------------------------------------------------------
// HttpSessionListener implementation
// -------------------------------------------------------
public void sessionCreated(HttpSessionEvent se) {
/* Session is created. */
System.out.println("sessionCreated");
}
public void sessionDestroyed(HttpSessionEvent se) {
/* Session is destroyed. */
System.out.println("sessionDestroyed");
}
}
web.xml:
<listener>
<listener-class>com.sa.listener.SessionListener</listener-class>
<display-name>SessionListener</display-name>
</listener>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
i.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<% session.setAttribute("name","sasa");%>
</body>
</html>
测试:http://localhost:8080/1012/pages/i.jsp
session设置超时时间一分钟:
②:监听域对象中的属性的变更的事件监听器
域对象中属性的变更的事件监听器就是用来监听servletContext,httpSession,httpServeltRequest这三个对象中的属性变更信息事件的监听器。
这三个监听器接口分别是
servletContextAttributeListener,httpSessionAttributeListener,servletRequestAttributeListener
这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。
一个例子:
attributeListener:
package com.sa.listener;
import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener()
public class AttributeListener implements ServletContextAttributeListener,
ServletRequestAttributeListener, HttpSessionAttributeListener {
// Public constructor is required by servlet spec
public AttributeListener() {
}
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("context attributeAdded");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("context attributeRemoved");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("context attributeReplaced");
}
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request attributeAdded");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request attributeRemoved");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("request attributeReplaced");
}
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("session attributeAdded");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("session attributeRemoved");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("session attributeReplaced");
}
}
web.xml:
<listener>
<listener-class>com.sa.listener.AttributeListener</listener-class>
<display-name>AttributeListener</display-name>
</listener>
j.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%request.setAttribute("name","sasa");%>
<%System.out.println("----------------------------");%>
<%request.setAttribute("name","zhangsan");%>
<%System.out.println("----------------------------");%>
<%request.removeAttribute("name");%>
<%System.out.println("----------------------------");%>
</body>
</html>
测试:http://localhost:8080/1012/pages/j.jsp
③:监听绑定到httpSession域中的某个对象的状态的事件监听器
保存在session域中的对象可以有多种状态:绑定到session中;从session域中解除绑定;随session对象持久化到一个存储设备中;随session对象从一个存储设备中恢复
servlet规范中定义了两个特殊的监听器接口来帮助javabean对象了解自己在session域中的这些状态:httpSessionBindingListener和httpSessionActivationListener接口,
实现这两个接口的类不需要在web.xml文件中进行注册。
httpSessionBindingListener接口:
实现了httpSessionBindingListener接口的javaBean对象可以感知自己被绑定到session中和从session中删除的事件
当对象呗绑定到httpSession对象中时,web服务器调用该对象的bound()方法
当对象从httpSession对象中解决绑定时,web服务器调用该对象的unbound()方法
测试:
package com.sa.entity;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class Boy implements HttpSessionBindingListener{
@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("valueBound");
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("valueUnbound");
}
}
k.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Boy boy=new Boy();
session.setAttribute("boy",boy);
System.out.println("----------------");
session.removeAttribute("boy");
%>
</body>
</html>
httpSessionActivationListener接口:
实现了httpSessionBindingListener接口的javaBean对象可以感知自己被活化和钝化的事件
当绑定到httpSession对象中的对象将要随httpSession对象被钝化之前,web服务器调用该对象的void sessionWillPassivate()方法。
当绑定到httpSession对象中的对象将要随httpSession对象被活化之前,web服务器调用该对象的void sessionDidActive()方法。
推荐阅读
-
Struts2访问servlet分享
-
浅析JAVA中过滤器、监听器、拦截器的区别
-
SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)
-
Java:Servlet
-
Servlet | Request 对象获取请求参数的通用方式
-
jsp和servlet操作mysql中文乱码问题的解决办法
-
JSP 开发之Servlet解决网页缓存问题
-
解决cannot be cast to javax.servlet.Filter 报错的问题
-
jsp传参 servlet接收中文乱码问题的解决方法
-
Servlet实现文件上传的三种方法总结