介绍
监听器用于监听 Web 应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。
监听器的作用实际上就是在特定的时间触发监听器提供给我们重写的钩子函数。
分类及使用
监听器按监听的对象可分为如下几类:
监听 ServletContext
ServletContextListener
监听 ServletContext
对象的创建和销毁:
// com.zze.listener.MyServletContextListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
/*
* 初始化时调用
* */
System.out.println("初始化");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
/*
* 销毁时调用(服务器正常关闭或从服务器移除项目时)
* */
System.out.println("销毁");
}
}
<!-- web.xml -->
<listener>
<listener-class>com.zze.listener.MyServletContextListener</listener-class>
</listener>
ServletContextAttributeListener
监听对 ServletContext
属性操作:
// com.zze.listener.MyServletContextAttributeListener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("添加属性时触发");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("移除属性时触发");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("修改属性时触发");
}
}
<!-- web.xml -->
<listener>
<listener-class>com.zze.listener.MyServletContextAttributeListener</listener-class>
</listener>
监听 HttpSession
HttpSessionListener
监听 Session
对象的创建和销毁:
// com.zze.listener.MyHttpSessionListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session 创建时调用");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session 销毁时调用");
}
}
<!-- web.xml -->
<listener>
<listener-class>com.zze.listener.MyHttpSessionListener</listener-class>
</listener>
HttpSessionAttributeListener
监听 Session
中的属性操作:
// com.zze.listener.MyHttpSessionAttributeListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("添加属性时触发");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("移除属性时触发");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("修改属性时触发");
}
}
<!-- web.xml -->
<listener>
<listener-class>com.zze.listener.MyHttpSessionAttributeListener</listener-class>
</listen
HttpSessionBindingListener
监听对象在 Session
中的绑定和解绑操作:
// com.zze.bean.User;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("被绑定到 session");
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("从 session 中解绑");
}
}
// com.zze.servlet.TestServlet;
import com.zze.com.zze.bean.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/test")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("user", new User()); // 绑定 触发 valueBound
session.removeAttribute("user");// 解绑 触发 valueUnbound
}
}
HttpSessionActivationListener
监听对象在 Session
中的钝化与活化:
// com.zze.bean.User
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;
public class User implements HttpSessionActivationListener,Serializable {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
System.out.println("钝化");
}
@Override
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
System.out.println("活化");
}
}
// com.zze.servlet.TestServlet;
import com.zze.com.zze.bean.User;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/test")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession();
session.setAttribute("user", new User("zhangsan",19)); // 存储到 session
}
}
钝化:将内存中的数据序列化保存到硬盘。
活化:将硬盘中的数据反序列化加载到内存。
Session 的钝化和活化用意何在?
Session 中的值可能会很多,并且可能我们很长一段时间都不会使用这个值,那么可以考虑将 Session 中的值存储到硬盘,等要使用的时候再从硬盘中提取,减轻内存压力。
默认情况下,在服务器正常关闭时会钝化保存在 Session 中的数据,而在服务器再次启动时会活化之前钝化的数据。
配置钝化活化:
<!-- context.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--maxIdleSwap :设置间隔多久时间钝化,单位为分钟-->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<!--directory:session 钝化保存的目录-->
<Store className="org.apache.catalina.session.FileStore" directory="sessionDir"/>
</Manager>
</Context>
- 在 Tomcat 目录下
/conf/context.xml
中配置以上内容,对托管到当前服务器的所有程序生效。 - 在 Tomcat 目录下
/conf/Catalina/localhost/context.xml
中配置以上内容,对托管到当前服务器中使用localhost
访问的程序生效。 - 在项目目录下
/META-INF/context.xml
中配置以上内容,仅对当前项目生效。
注意:因为钝化和活化实际上是序列化和反序列化的过程,所以要钝化的对象类必须实现
Serializable
接口。
监听 HttpServletRequest
ServletRequestListener
监听 HttpServletRequest
对象的创建和销毁:
// com.zze.listener.MyServletRequestListener
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("初始化");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("销毁");
}
}
<!-- web.xml -->
<listener>
<listener-class>com.zze.listener.MyServletRequestListener</listener-class>
</listener>
ServletRequestAttributeListener
监听 Request
中的属性操作:
// com.zze.listener.MyServletRequestAttributeListener
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("添加属性时触发");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("移除属性时触发");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("修改属性时触发");
}
}
<!-- web.xml -->
<listener>
<listener-class>com.zze.listener.MyServletRequestAttributeListener</listener-class>
</listener>
评论区