JavaWeb(37) : 监听器Listener(二)

一、监听域对象中属性的变更的监听器

域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。

这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener 和ServletRequestAttributeListener,这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。

1.1、ServletContextAttributeListener监听器案例

BListener.java :
package waf.yty.web.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class BListener implements ServletContextAttributeListener {

    public void attributeAdded(ServletContextAttributeEvent scab)  { 
        System.out.println("您向application中添加了一个名为" + scab.getName() + 
        		",值为" + scab.getValue() + "的属性");
    }

    public void attributeRemoved(ServletContextAttributeEvent scab)  { 
         System.out.println(scab.getName() + "=" + scab.getValue());
    }

    public void attributeReplaced(ServletContextAttributeEvent scab)  { 
        System.out.println(scab.getName() + "=" + scab.getValue() + ","
        			+ scab.getServletContext().getAttribute(scab.getName()));
    }
	
}

web.xml :

 <listener>
    <listener-class>waf.yty.web.listener.BListener</listener-class>
  </listener>

add.jsp :

  <body>
<%
application.setAttribute("waf", "WAF");
 %>
  </body>

replace.jsp :

  <body>
<%
application.setAttribute("waf", "ZZZ");

%>

  </body>

remove.jsp :

  <body>
<%
application.removeAttribute("waf");
 %>
  </body>

1.2、ServletRequestAttributeListener和HttpSessionAttributeListener监听器案例

CListener.java :

package waf.yty.web.listener;

import java.text.MessageFormat;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class CListener implements HttpSessionAttributeListener, ServletRequestAttributeListener {

	public void attributeAdded(ServletRequestAttributeEvent srae)  {
		String str = MessageFormat.format("ServletRequest域对象中添加了属性:{0},属性值是:{1}"
				,srae.getName()
				,srae.getValue());
		System.out.println(str);
	}

	public void attributeRemoved(ServletRequestAttributeEvent srae)  {
		String str = MessageFormat.format("ServletRequest域对象中删除了属性:{0},属性值是:{1}"
				,srae.getName()
				,srae.getValue());
		System.out.println(str);
	}

    public void attributeReplaced(ServletRequestAttributeEvent srae)  {
    	String str = MessageFormat.format("ServletRequest域对象中替换了属性:{0},属性值是:{1}"
				,srae.getName()
				,srae.getValue());
		System.out.println(str);
    }

    public void attributeAdded(HttpSessionBindingEvent se)  { 
    	String str = MessageFormat.format("HttpSession域对象中添加了属性:{0},属性值是:{1}"
				,se.getName()
				,se.getValue());
		System.out.println(str);
    }

    public void attributeRemoved(HttpSessionBindingEvent se)  { 
    	String str = MessageFormat.format("HttpSession域对象中删除了属性:{0},属性值是:{1}"
				,se.getName()
				,se.getValue());
		System.out.println(str);
    }

    public void attributeReplaced(HttpSessionBindingEvent se)  { 
    	String str = MessageFormat.format("HttpSession域对象中替换了属性:{0},属性值是:{1}"
				,se.getName()
				,se.getValue());
		System.out.println(str);
    }
	
}

web.xml :

  <listener>
    <listener-class>waf.yty.web.listener.CListener</listener-class>
  </listener>

rsTest.jsp :

  <body>
<%
session.setAttribute("aa", "bb");
session.setAttribute("aa", "cc");
session.removeAttribute("aa");

request.setAttribute("AA", "BB");
request.setAttribute("AA", "DD");
request.removeAttribute("AA");
 %>
  </body>

二、感知Session绑定的事件监听器

 保存在Session域中的对象可以有多种状态:绑定(session.setAttribute("bean",Object))到Session中;从 Session域中解除(session.removeAttribute("bean"))绑定;随Session对象持久化到一个存储设备中;随Session对象从一个存储设备中恢复。

 Servlet 规范中定义了两个特殊的监听器接口"HttpSessionBindingListener和HttpSessionActivationListener"来帮助JavaBean 对象了解自己在Session域中的这些状态: ,实现这两个接口的类不需要 web.xml 文件中进行注册

2.1、HttpSessionBindingListener接口

实现了HttpSessionBindingListener接口的JavaBean对象可以感知自己被绑定到Session中和从Session中删除的事件。

当对象被绑定到HttpSession对象中时,web服务器调用该对象的void valueBound(HttpSessionBindingEvent event)方法

当对象从HttpSession对象中解除绑定时,web服务器调用该对象的void valueUnbound(HttpSessionBindingEvent event)方法

案例 :

User.java :

package waf.yty.web.listener;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class User implements HttpSessionBindingListener{
	
	private String username;
	private String password;
	
	public User(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	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;
	}
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + "]";
	}
	public void valueBound(HttpSessionBindingEvent arg0) {
		System.out.println("或许这就是Session上流社会吧!");
		
	}
	public void valueUnbound(HttpSessionBindingEvent arg0) {
		System.out.println("Session我去也!");
		
	}
	

}

addAndRemove.jsp :

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="waf.yty.web.listener.User" %>

<html>
  <head>
    
    <title>My JSP 'addAndRemove.jsp' starting page</title>
    

  </head>
  
  <body>
<%
User user = new User();
// 添加到Session
session.setAttribute("user", user);
// 从Session中溢出
session.removeAttribute("user");
 %>
  </body>
</html>

2.2、HttpSessionActivationListener接口

实现了HttpSessionActivationListener接口的JavaBean对象可以感知自己被活化(反序列化)和钝化(序列化)的事件

 当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被钝化(序列化)之前,web服务器调用该javabean对象的void sessionWillPassivate(HttpSessionEvent event) 方法。这样javabean对象就可以知道自己将要和HttpSession对象一起被序列化(钝化)到硬盘中。

当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被活化(反序列化)之后,web服务器调用该javabean对象的void sessionDidActive(HttpSessionEvent event)方法。这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中。

JavaBean对象一定要实现序列化 (Serializable) 接口,否则会在Session钝化到硬盘之前被杀死,再查询就为NULL !

示例:

User.java :

package waf.yty.pojo;

import java.io.Serializable;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
/**
 *  	实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件
	活化:javabean对象和Session一起被反序列化(活化)到内存中。
    钝化:javabean对象存在Session中,当服务器把session序列化到硬盘上时,如果Session中的javabean对象实现了Serializable接口
    那么服务器会把session中的javabean对象一起序列化到硬盘上,javabean对象和Session一起被序列化到硬盘中的这个操作称之为钝化
    如果Session中的javabean对象没有实现Serializable接口,那么服务器会先把Session中没有实现Serializable接口的javabean对象移除
    然后再把Session序列化(钝化)到硬盘中
    当绑定到 HttpSession对象中的javabean对象将要随 HttpSession对象被钝化之前,
    web服务器调用该javabean对象对象的 void sessionWillPassivate(HttpSessionEvent event)方法
    这样javabean对象就可以知道自己将要和 HttpSession对象一起被序列化(钝化)到硬盘中
    当绑定到HttpSession对象中的javabean对象将要随 HttpSession对象被活化之后,
    web服务器调用该javabean对象的 void sessionDidActive(HttpSessionEvent event)方法
    这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中
 * @author yangtengyu
 *
 */
public class User implements HttpSessionActivationListener, Serializable {

	public void sessionWillPassivate(HttpSessionEvent arg0) {
		System.out.println("钝化到硬盘");
		
	}
	
	public void sessionDidActivate(HttpSessionEvent arg0) {
		System.out.println("活化回内存");
	}


}

在WebRoot\META-INF文件夹下创建一个context.xml文件 :

<Context>
<!-- 1分钟之后就将HttpSession对象钝化到本地硬盘的一个gacl文件夹中 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
 <Store className="org.apache.catalina.session.FileStore" directory="de_cache"/>
 </Manager>
</Context>

a.jsp :

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="waf.yty.pojo.User" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'a.jsp' starting page</title>
    
  </head>
  
  <body>
  <h1>向session中保存session数据</h1>
<%
User user = new User();

session.setAttribute("user", user);
 %>
  </body>
</html>

b.jsp :

  </head>
  
  <body>
  <h1>获取session中的数据</h1>
<%
out.print(session.getAttribute("user"));
 %>
  </body>
</html>

访问这个a.jsp页面,服务器就会马上创建一个HttpSession对象,然后将实现了HttpSessionActivationListener接口的JavaBean对象绑定到session对象中,这个jsp页面在等待1分钟之后没有人再次访问,那么服务器就会自动将这个HttpSession对象钝化(序列化)到硬盘上。

我们可以在tomcat服务器的work\Catalina\localhost\JavaWeb_Listener_20140908\gacl文件夹下找到序列化到本地存储的session,它会生成一个context.xml中directory的value值的文件夹,里面生成一个以.session结尾的文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值