java web域对象的监听器

作用:

监听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):

    分两种情况:

  1. java中第一次调用request.getSession的时候
  2. jsp访问的时候创建,因为jsp内置了session对象,即已经创建了session对象了.

注意:上面所说的是在同一个会话中,即同一个浏览器首次访问才会创建,同个会话中刷新多次请求不会再创建;而关闭浏览器后再次访问属于另一个会话,因此关闭浏览器后首次打开还是会创建.

  • 销毁(sessionDestroyed):

    分三种情况:

  1. session超时
  2. 手动销毁session
  3. 服务器非正常关闭

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中设置序列化文件的保存目录,如下所示:可以看到序列号的文件 已经保存到这个目录了.

猜你喜欢

转载自blog.csdn.net/mchenys/article/details/81193008