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

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

1.1、attributeAdded 方法

  当向被监听对象中增加一个属性时,web容器就调用事件监听器的attributeAdded方法进行响应,这个方法接收一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
  各个域属性监听器中的完整语法定义为:

1 public void attributeAdded(ServletContextAttributeEvent scae)
2 public void attributeReplaced(HttpSessionBindingEvent hsbe)
3 public void attributeRmoved(ServletRequestAttributeEvent srae)

1.2、attributeRemoved 方法

  当删除被监听对象中的一个属性时,web容器调用事件监听器的attributeRemoved方法进行响应
  各个域属性监听器中的完整语法定义为:

1 public void attributeRemoved(ServletContextAttributeEvent scae)
2 public void attributeRemoved (HttpSessionBindingEvent hsbe)
3 public void attributeRemoved (ServletRequestAttributeEvent srae)

1.3、attributeReplaced 方法

  当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的attributeReplaced方法进行响应
  各个域属性监听器中的完整语法定义为:

1 public void attributeReplaced(ServletContextAttributeEvent scae)
2 public void attributeReplaced (HttpSessionBindingEvent hsbe)
3 public void attributeReplaced (ServletRequestAttributeEvent srae)

1.4、ServletContextAttributeListener监听器范例:

  编写ServletContextAttributeListener监听器监听ServletContext域对象的属性值变化情况,代码如下:

package me.gacl.web.listener;

import java.text.MessageFormat;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener; /**
* @ClassName: MyServletContextAttributeListener
* @Description: ServletContext域对象中属性的变更的事件监听器
* @author: 孤傲苍狼
* @date: 2014-9-11 下午10:53:04
*
*/
public class MyServletContextAttributeListener implements
ServletContextAttributeListener { @Override
public void attributeAdded(ServletContextAttributeEvent scab) {
String str =MessageFormat.format(
"ServletContext域对象中添加了属性:{0},属性值是:{1}"
,scab.getName()
,scab.getValue());
System.out.println(str);
} @Override
public void attributeRemoved(ServletContextAttributeEvent scab) {
String str =MessageFormat.format(
"ServletContext域对象中删除属性:{0},属性值是:{1}"
,scab.getName()
,scab.getValue());
System.out.println(str);
} @Override
public void attributeReplaced(ServletContextAttributeEvent scab) {
String str =MessageFormat.format(
"ServletContext域对象中替换了属性:{0}的值"
,scab.getName());
System.out.println(str);
}
}

在web.xml文件中注册监听器

1  <listener>
2 <description>MyServletContextAttributeListener监听器</description>
3 <listener-class>me.gacl.web.listener.MyServletContextAttributeListener</listener-class>
4 </listener>

  编写ServletContextAttributeListenerTest.jsp测试页面

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>ServletContextAttributeListener监听器测试</title>
</head> <body>
<%
//往application域对象中添加属性
application.setAttribute("name", "孤傲苍狼");
//替换application域对象中name属性的值
application.setAttribute("name", "gacl");
//移除application域对象中name属性
application.removeAttribute("name");
%>
</body>
</html>

运行结果如下:

  

  从运行结果中可以看到,ServletContextListener监听器成功监听到了ServletContext域对象(application)中的属性值的变化情况。

1.5、ServletRequestAttributeListener和HttpSessionAttributeListener监听器范例:

  编写监听器监听HttpSession和HttpServletRequest域对象的属性值变化情况,代码如下:

package me.gacl.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 MyRequestAndSessionAttributeListener implements
HttpSessionAttributeListener, ServletRequestAttributeListener { @Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
String str =MessageFormat.format(
"ServletRequest域对象中添加了属性:{0},属性值是:{1}"
,srae.getName()
,srae.getValue());
System.out.println(str);
} @Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
String str =MessageFormat.format(
"ServletRequest域对象中删除属性:{0},属性值是:{1}"
,srae.getName()
,srae.getValue());
System.out.println(str);
} @Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
String str =MessageFormat.format(
"ServletRequest域对象中替换了属性:{0}的值"
,srae.getName());
System.out.println(str);
} @Override
public void attributeAdded(HttpSessionBindingEvent se) {
String str =MessageFormat.format(
"HttpSession域对象中添加了属性:{0},属性值是:{1}"
,se.getName()
,se.getValue());
System.out.println(str);
} @Override
public void attributeRemoved(HttpSessionBindingEvent se) {
String str =MessageFormat.format(
"HttpSession域对象中删除属性:{0},属性值是:{1}"
,se.getName()
,se.getValue());
System.out.println(str);
} @Override
public void attributeReplaced(HttpSessionBindingEvent se) {
String str =MessageFormat.format(
"HttpSession域对象中替换了属性:{0}的值"
,se.getName());
System.out.println(str);
}
}

在web.xml文件中注册监听器

1  <listener>
2 <description>MyRequestAndSessionAttributeListener监听器</description>
3 <listener-class>me.gacl.web.listener.MyRequestAndSessionAttributeListener</listener-class>
4 </listener>

  编写RequestAndSessionAttributeListenerTest.jsp测试页面

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>RequestAndSessionAttributeListener监听器测试</title>
</head> <body>
<%
//往session域对象中添加属性
session.setAttribute("aa", "bb");
//替换session域对象中aa属性的值
session.setAttribute("aa", "xx");
//移除session域对象中aa属性
session.removeAttribute("aa"); //往request域对象中添加属性
request.setAttribute("aa", "bb");
//替换request域对象中aa属性的值
request.setAttribute("aa", "xx");
//移除request域对象中aa属性
request.removeAttribute("aa");
%>
</body>
</html>

运行结果如下:

  

  从运行结果中可以看到,HttpSessionAttributeListener监听器和ServletRequestAttributeListener成功监听到了HttpSession域对象和HttpServletRequest域对象的属性值变化情况。

二、感知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)方法

范例:

package me.gacl.domain;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener; /**
* @ClassName: JavaBeanDemo1
* @Description:
* 实现了HttpSessionBindingListener接口的 JavaBean对象可以感知自己被绑定到 Session中和从Session中删除的事件
当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的 void valueBound(HttpSessionBindingEvent event) 方法
当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法 * @author: 孤傲苍狼
* @date: 2014-9-11 下午11:14:54
*
*/
public class JavaBeanDemo1 implements HttpSessionBindingListener { private String name; @Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println(name+"被加到session中了");
} @Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println(name+"被session踢出来了");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public JavaBeanDemo1(String name) {
this.name = name;
}
}

上述的JavaBeanDemo1这个javabean实现了HttpSessionBindingListener接口,那么这个JavaBean对象可以感知自己被绑定到Session中和从Session中删除的这两个操作,测试代码如下:

<%@ page language="java" pageEncoding="UTF-8"%>
<%@page import=" me.gacl.domain.JavaBeanDemo1"%>
<!DOCTYPE HTML>
<html>
<head>
<title></title>
</head> <body>
<%
//将javabean对象绑定到Session中
session.setAttribute("bean",new JavaBeanDemo1("孤傲苍狼"));
//从Session中删除javabean对象
session.removeAttribute("bean");
%>
</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对象一起被反序列化(活化)回到内存中

范例:

package me.gacl.domain;

import java.io.Serializable;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent; /**
* @ClassName: JavaBeanDemo2
* @Description:
实现了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: 孤傲苍狼
* @date: 2014-9-11 下午11:22:35
*
*/
public class JavaBeanDemo2 implements HttpSessionActivationListener,
Serializable { private static final long serialVersionUID = 7589841135210272124L;
private String name; @Override
public void sessionWillPassivate(HttpSessionEvent se) { System.out.println(name+"和session一起被序列化(钝化)到硬盘了,session的id是:"+se.getSession().getId());
} @Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println(name+"和session一起从硬盘反序列化(活化)回到内存了,session的id是:"+se.getSession().getId());
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public JavaBeanDemo2(String name) {
this.name = name;
}
}

为了观察绑定到HttpSession对象中的javabean对象随HttpSession对象一起被钝化到硬盘上和从硬盘上重新活化回到内存中的的过程,我们需要借助tomcat服务器帮助我们完成HttpSession对象的钝化和活化过程,具体做法如下:

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

  

  context.xml文件的内容如下:

1 <Context>
2 <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
3 <Store className="org.apache.catalina.session.FileStore" directory="gacl"/>
4 </Manager>
5 </Context>

  在context.xml文件文件中配置了1分钟之后就将HttpSession对象钝化到本地硬盘的一个gacl文件夹中

  jsp测试代码如下:

<%@ page language="java" pageEncoding="UTF-8"%>
<%@page import="me.gacl.domain.JavaBeanDemo2"%>
<!DOCTYPE HTML>
<html>
<head>
<title></title>
</head> <body>
一访问JSP页面,HttpSession就创建了,创建好的Session的Id是:${pageContext.session.id}
<hr/>
<%
session.setAttribute("bean",new JavaBeanDemo2("孤傲苍狼"));
%>
</body>
</html>

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

  

  我们可以在tomcat服务器的work\Catalina\localhost\JavaWeb_Listener_20140908\gacl文件夹下找到序列化到本地存储的session,如下图所示:

  

  当再次访问这个Jsp页面时,服务器又会自动将已经钝化(序列化)到硬盘上HttpSession对象重新活化(反序列化)回到内存中。运行结果如下:

  

  JavaWeb开发技术中的监听器技术的内容就这么多了,在平时的工作中,监听器技术在JavaWeb项目开发中用得是比较多,因此必须掌握这门技术。

javaWeb学习总结(11)- 监听器(Listener)学习(2)的更多相关文章

  1. javaWeb学习总结(11)- 监听器(Listener)学习

    一.监听器介绍 1.1.监听器的概念 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其 实就是一个实现特定接口的普 ...

  2. JavaWeb学习 (二十七)————监听器(Listener)在开发中的应用

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听 ...

  3. 深入分析JavaWeb Item39 -- 监听器(Listener)学习进阶

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

  4. 监听器(Listener)学习(一)

    一.监听器介绍 1.1.监听器的概念 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通 ...

  5. 监听器(Listener)学习(二)在开发中的常见应用

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用: 统计当前在线人数 自定义Session扫描器 一.统计当前在线人数 在JavaWeb应用开发中,有时候 ...

  6. 监听器(Listener)学习(二)

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

  7. javaweb学习总结(四十五)——监听器(Listener)学习二

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

  8. javaweb学习总结(四十四)——监听器(Listener)学习

    一.监听器介绍 1.1.监听器的概念

  9. JavaWeb学习 (二十六)————监听器(Listener)学习(二)

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

随机推荐

  1. 通过js获取元素css3的transform rotate旋转角度方法

    我们再试用jquery获取样式的时候是通过$('domName').css('transform'):的方式来获取元素的css样式,但是通过它获取到的css3的transform属性是以矩阵的方式呈现 ...

  2. Ubuntu抛弃了Untiy转向Gnome,美化之路怎么办?不用怕咱一步一步大变身!

    跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 常用软件安装+系统软件卸载:http://www.cnblogs.com/du ...

  3. asp.net SignalR 一对一聊天

    <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/S ...

  4. 美团点评DBProxy读写分离使用说明

    目的 因为业务架构上需要实现读写分离,刚好前段时间美团点评开源了在360Atlas基础上开发的读写分离中间件DBProxy,关于其介绍在官方文档已经有很详细的说明了,其特性主要有:读写分离.负载均衡. ...

  5. php数组--2017-04-16

    一.定义数组 (1)索引数组 $arr=array(1,2,3,3); (2)关联数组  类似于集合 $arr1=array("one"=>"111",& ...

  6. (转)使用string.Format需要注意的一个性能问题

    今天,我在写C#代码时,突然发现一个最熟悉的陌生人 —— string.Format.在写C#代码的日子里,与它朝夕相伴,却没有真正去了解它.只知道在字符串比较多时,用它比用加号进行字符串连接效率更高 ...

  7. CentOS下安装JDK的三种方法

    方法一:手动解压JDK的压缩包,然后设置环境变量 1.在/usr/目录下创建java目录 [root@localhost ~]# mkdir/usr/java[root@localhost ~]# c ...

  8. git 分支的创建与提交

    我们在开发的过程中会遇到很多团队协作的问题,怎么来解决团队合作呢,就是靠分支来管理代码.一般来说一个功能就要创建一个分支,这样才能减少代码的冲突,给开发带来很大的方便. 首先需要克隆代码 git cl ...

  9. [ext4]05 磁盘布局 - 延迟块组初始化

    延迟块组初始化,Ext4的新特性.如果对应的特性标识uninit_bg置位,那么inode bitmap和inode tables就不会初始化. 延迟块组初始化特性特性可以减少格式化耗时. 延迟块组初 ...

  10. 使用ioctl向linux内核传递参数的方法实例

    该篇实例是摘自网络(无法追根溯源倒低是哪位"前"辈写的了) 一.应用层 uint16 data16; if ((fd = socket(AF_INET, SOCK_STREAM, ...