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

  域对象中属性的变更的事件监听器就是用来监听 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. ASP.NET Core MVC和Visual Studio入门

    本教程将教你使用Visual Studio 2017创建 ASP.NET Core MVC web应用程序的基础知识. 安装Visual Studio 2017 和.Net Core 安装Visual ...

  2. Python爬虫入门 Urllib库的基本使用

    1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...

  3. .net md5

    今天试着写了一下MD5加密,网站注册登录估计都用到MD5,今天就把写的贴出来 public string GetMd5(string user) { using (MD5 md5 = MD5.Crea ...

  4. Java 中字两个字符串判断是否相等(转载)

    java中判断字符串是否相等有两种方法:1.用"=="运算符,该运算符表示指向字符串的引用是否相同,比如: String a="abc";String b=&q ...

  5. vue.js随笔记---初识Vue.js

    1.基础要求: 1.1 HTML CSS JAVASCRIPT 1.2 模块化基础 1.3 Es6初步了解 2.vue.js 轻量级的MVVM模式框架,他同时吸收了recat和angular的优点,他 ...

  6. Neural Networks and Deep Learning(神经网络与深度学习) - 学习笔记

    catalogue . 引言 . 感知器及激活函数 . 代价函数(loss function) . 用梯度下降法来学习-Learning with gradient descent . 用反向传播调整 ...

  7. 10个漂亮的jQuery日历插件下载【转载】

    10个漂亮的jQuery日历插件下载 2013-08-07 标签:jQuery日历插件jQuery日历jQuery插件   日期是非常重要的,随时随地.微薄或网站的日期选取器日历必须在那里.您可以使用 ...

  8. 【原创】bootstrap框架的学习 第七课 -[bootstrap表格]

    Bootstrap 表格 标签 描述 <table> 为表格添加基础样式. <thead> 表格标题行的容器元素(<tr>),用来标识表格列. <tbody& ...

  9. MATLAB下跑Faster-RCNN+ZF实验时如何编译自己需要的external文件

    本篇文章主讲这篇博客中的(http://blog.csdn.net/sinat_30071459/article/details/50546891)的这个部分,如图所示 注:截图来自 小咸鱼_ 的博客 ...

  10. 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

    https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...