作用:
监听web中的域对象 ServletContext ServletRequest HttpSession
监听内容:
- 监听三个对象的创建和销毁
- 监听三个对象属性的变化
- 监听session中javabean的状态
一共有8个监听器接口,分为3组:
1)监听三个对象的创建和销毁
- ServletContextListener
- ServletRequestListener
- HttpSessionListener
2).监听三个对象属性的变化
- ServletContextAttributeListener
- ServletRequestAttributeListener
- HttpSessionAttributeListener
3)监听session中javabean的状态
- HttpSessionActivationListener(钝化和活化)
- HttpSessionBindingListener(绑定和解绑)
使用步骤:
1)编写一个类 实现接口
2)重写方法
3)编写配置文件
接口方法说明:
1)ServletContextListener
- 创建(contextInitialized):服务器启动的时候,会为每一个项目都创建一个servletContext,可以用来加载配置文件.
- 销毁(contextDestroyed):服务器关闭的时候,或者项目被移除的时候
2)ServletRequestListener
- 创建(requestInitialized):请求来的时候
- 销毁(requestDestroyed):响应生成的时候
3)HttpSessionListener
- 创建(sessionCreated):
分两种情况:
- java中第一次调用request.getSession的时候
- jsp访问的时候创建,因为jsp内置了session对象,即已经创建了session对象了.
注意:上面所说的是在同一个会话中,即同一个浏览器首次访问才会创建,同个会话中刷新多次请求不会再创建;而关闭浏览器后再次访问属于另一个会话,因此关闭浏览器后首次打开还是会创建.
- 销毁(sessionDestroyed):
分三种情况:
- session超时
- 手动销毁session
- 服务器非正常关闭
4)ServletContextAttributeListener/ServletRequestAttributeListener/HttpSessionAttributeListener
- attributeAdded:添加属性
- attributeReplaced:替换属性
- attributeRemoved:移除属性
注意:上面3个方法的参数是不一样的,分别介绍:
ServletContextAttributeListener接口方法的参数是ServletContextAttributeEvent
- String getName():获取当前操作的属性名;
- Object getValue():获取当前操作的属性值;
- ServletContext getServletContext():获取ServletContext对象。
HttpSessionAttributeListener接口方法的参数是HttpSessionBindingEvent
- String getName():获取当前操作的属性名;
- Object getValue():获取当前操作的属性值;
- HttpSession getSession():获取当前操作的session对象。
ServletRequestAttributeListener接口的参数是ServletRequestAttributeEvent
- String getName():获取当前操作的属性名;
- Object getValue():获取当前操作的属性值;
- ServletContext getServletContext():获取ServletContext对象;
- ServletRequest getServletRequest():获取当前操作的ServletRequest对象。
5)HttpSessionBindingListener(绑定和解绑,不用在web.xml文件中注册)
- valueBound:添加javabean到session域中
- valueUnbound:从session域中移除javabean
注意:需要javabean实现该HttpSessionBindingListener接口
6)HttpSessionActivationListener(钝化和活化,不用在web.xml文件中注册)
- 钝化(sessionWillPassivate):javabean从session域中序列化到服务器磁盘上
- 活化(sessionDidActivate):javabean从服务器磁盘上加载到了session域中
注意:session中的javabean必须要实现Serializable接口,否则无效,另外需要javabean实现该HttpSessionActivationListener接口
另外;需要看到钝化和活化的效果,可以通过配置文件修改javabean什么时候钝化.只需要在项目下/meta-info创建一个context.xml
内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
maxIdleSwap :单位是分钟 多少分钟后如果session不使用就会序列化到硬盘.
directory :chenys序列化到硬盘的文件存放的位置.
-->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="chenys"/>
</Manager>
</Context>
按照上面的配置后,在同一个回话中,如果浏览器一直不关闭,那么就会每隔1分钟就会将实现了HttpSessionActivationListener接口且实现了Serializable接口的javabean序列化到服务器硬盘中.当重新打开浏览器的时候首次访问session中的javabean对象时,又会去服务器硬盘将该对象活化到内存中使用,且此次会话中不关闭浏览器重复刷新的时候只会从内存中加载.
Demo演示:
1)依次创建以上监听器:
package blog.csdn.net.context;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 监听ServletContext创建和销毁
* @author mChenys
*
*/
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("servletContext创建了...");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("servletContext销毁...");
}
}
package blog.csdn.net.request;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
/**
* 监听ServletRequestListener创建和销毁
* @author mChenys
*
*/
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("请求创建了...");
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("请求结束了...");
}
}
package blog.csdn.net.session;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 监听HttpSessionListener的创建和销毁
* @author mChenys
*
*/
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session创建了...");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session销毁了...");
}
}
package blog.csdn.net.attr;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
/**
*
* 监听ServletContext域的属性添加,修改,替换
* @author mChenys
*
*/
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scab) {
System.out.println("ServletContext添加属性..."+scab.getName());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scab) {
System.out.println("ServletContext移除属性..."+scab.getName());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scab) {
System.out.println("ServletContext替换属性..."+scab.getName());
}
}
package blog.csdn.net.attr;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
/**
* 监听ServletRequest域的属性添加,修改,替换
* @author mChenys
*
*/
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest添加属性..."+srae.getName());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest移除属性..."+srae.getName());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println("ServletRequest替换属性..."+srae.getName());
}
}
package blog.csdn.net.attr;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
* 监听HttpSession域对象的属性添加,修改,替换
* @author mChenys
*
*/
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("HttpSession添加属性..."+se.getName());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("HttpSession移除属性..."+se.getName());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("HttpSession替换属性..."+se.getName());
}
}
2)javabean对象,演示session的/绑定/解绑
package blog.csdn.net.bean;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
/**
* 监听javabean对象从session域对象中添加或移除,不用在web.xml配置文件中进行注册...直接使用即可
*
* @author mChenys
*
*/
public class User implements HttpSessionBindingListener {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public User() {
super();
}
// 监听javabean对象从session域对象中添加或移除
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println(event.getName() + "从域中添加了...");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println(event.getName() + "从域中移除了...");
}
}
3)javabean对象,演示session的钝化/活化
package blog.csdn.net.bean;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
/**
* 监听javabean对象从session中序列化到硬盘,和从硬盘反序列号到session,不用在web.xml配置文件中进行注册...直接使用即可
*
* @author mChenys
*
*/
public class User2 implements Serializable, HttpSessionActivationListener {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User2(String username, String password) {
super();
this.username = username;
this.password = password;
}
public User2() {
super();
}
// 监听javabean对象从session中序列化到硬盘,和从硬盘反序列号到session
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("session中的javabean序列化到硬盘了...");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("硬盘中的javabean反序列号到session中了...");
}
}
4)依次在WEB-INF/web.xml中注册以上监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 三个域对象创建销毁监听器注册 -->
<listener>
<listener-class>blog.csdn.net.context.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>blog.csdn.net.request.MyServletRequestListener</listener-class>
</listener>
<listener>
<listener-class>blog.csdn.net.session.MyHttpSessionListener</listener-class>
</listener>
<!-- 三个域对象属性添加修改删除监听器注册 -->
<listener>
<listener-class>blog.csdn.net.attr.MyServletContextAttributeListener</listener-class>
</listener>
<listener>
<listener-class>blog.csdn.net.attr.MyServletContextAttributeListener</listener-class>
</listener>
<listener>
<listener-class>blog.csdn.net.attr.MyServletContextAttributeListener</listener-class>
</listener>
</web-app>
4)测试页
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/destorySession.jsp">手动销毁session</a>
<a href="${pageContext.request.contextPath }/addAttr.jsp">添加域属性</a>
<a href="${pageContext.request.contextPath }/deleteAttr.jsp">删除域属性</a>
<a href="${pageContext.request.contextPath }/replaceAttr.jsp">修改域属性</a>
<a href="${pageContext.request.contextPath }/addBean.jsp">添加对象到域</a>
<a href="${pageContext.request.contextPath }/deleteBean.jsp">从域中删除对象</a>
<a href="${pageContext.request.contextPath }/setBean.jsp">钝化</a>
<a href="${pageContext.request.contextPath }/getBean.jsp">活化</a>
</body>
</html>
测试结果:
1)测试3个域对象的创建
流程:服务器启动->请求index.jsp->再次请求->关闭浏览器->重新打开浏览器请求index.jsp->再次请求->destorySession.jsp->关闭服务器
log:
2)测试3个域对象属性的操作
流程:添加->修改->移除
log:
3)测试绑定/解绑session对象
流程:addBean.jsp->deleteBean.jsp
4)测试活化/钝化
流程:setBean.jsp->关闭浏览器->关闭服务器(或者等1分钟后)->打开浏览器->运行服务器->getBean.jsp
log:
此时查看tomcat的work\Catalina\localhost\项目名,目录下会多了一个chenys文件夹,这个就是上面我们在META-INF下配置context.xml中设置序列化文件的保存目录,如下所示:可以看到序列号的文件 已经保存到这个目录了.