Listener监听器 -- 重点讲解HttpSessionActivationListener的钝化、活化

121 阅读3分钟

文章目录

1. 作用

用于监听另一个对象的方法调用或者属性的变化,当触发这些事件,监听器的方法立即被执行

  监听器分类

2. 8大监听器类、6个事件类

  监听器Listener类

  事件Event类

2. 监听器的使用

  创建监听器实现类的步骤

2.1 代码示例

2.1.1 作用域对象监听器

  监听Web项目的启动、关闭的监听器

class Webistener implements ServletContextListener {
    @Override
    public void contextInitialized( ServletContextEvent sce ) {
        System.out.println(" Web应用服务初始化 ");
    }
    
    @Override
    public void  contextDestoryed( ServletCotnextEvent sce ) {
        System.out.println(" Web应用服务关闭 " );
    }
}

2.1.2 作用域的对象监听器 - 所有属性

  监听application作用域的属性监听器 - 增加、修改、删除

@WebListener
public class ApplicationAttrListener implements ServletContextAttributeListener{

	@Override
	public void attributeAdded(ServletContextAttributeEvent scab) {
		System.out.println("Web应用作用域属性添加");
	}

	@Override
	public void attributeRemoved(ServletContextAttributeEvent scab) {
		System.out.println("Web应用作用于属性删除");
	}

	@Override
	public void attributeReplaced(ServletContextAttributeEvent scab) {
		System.out.println("Web应用作用于属性值被替换");
	}
	
}

2.1.3 指定某个类对象在会话域属性的监听

  对JavaBean进行会话域监听

@WebListener
public class TestBean implements HttpSessionBindingListener {
	
        String name;
        Integer id;
        public String getName() { return this.name; }
        public Integer getId() { return this.id; }
        public void setName( String name ) { this.name = name; }
        public void setId( Integer id ) { this.id = id; }       
    
        @Override
        public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("TestBean被放入到session域中");
        }
        @Override
        public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("TestBean被删除从session域中");
        }  
}

  testBean.JSP

	<%
		Thread.sleep(3000);
		System.out.println("3秒后:添加新的TestBean对象");
		session.setAttribute("testBean", new TestBean());
		System.out.println("\n");
	
		Thread.sleep(5000);
		System.out.println("8秒后:更换另一个TestBean对象");
		session.setAttribute("testBean", new TestBean());
		System.out.println("\n");
		
		
		Thread.sleep(5000);
		System.out.println("13秒后:删除绑定TestBean的属性");
		session.removeAttribute("testBean");
	%>


运行结果

  1. 浏览器输入关于这个JSP的URL
  2. 控制台输入如下图:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfeB49PU-1573065934898)(en-resource://database/8791:1)]

重点: 由运行结果推知:

  1. 实现该接口(HttpSessionBindingListener)的类 会话属性的值更换 会触发 valueBound() 跟 valueUnbound()
  2. 一开始就没该属性,就会触发 valueBound()
  3. 属性删除,则会触发 valueUnbound()
2.1.4 Session对象的钝化、活化的监听

  ActivationObject – 能够序列化并且被监听的对象

切记切记必须序列化、必须序列化、必须序列化,我没序列化,我还以为我代码出错了,调试了半天。

配置信息 – 进行下面代码示例的前提

两步操作:

  1. 关闭Tomcat自带 - 关闭服务器时会话序列化
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJtvqFWt-1573065934913)(en-resource://database/8899:0)]


2. 配置会话的存储位置以及用户不请求服务器时限会话序列化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8BLrmEMp-1573065934922)(en-resource://database/8903:0)]

  context.xml内容

<?xml version="1.0" encoding="UTF-8"?>
<Context>
	<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">   <!-- 用户无请求操作时会话序列化 - 1分钟 -->
		<Store className="org.apache.catalina.session.FileStore"
			directory="C:/Users/lrc/Desktop/sessionTest" />   <!-- 会话对象序列化的文件位置,一经硬盘存储直接就在硬盘上,并不是其他博客写的重启服务器会消失,该会话钝化、活化该文件都不会被删除 -->
	</Manager>
</Context>

代码示例

文件位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d96mijhq-1573065934925)(en-resource://database/8907:0)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qxCzFYs6-1573065934932)(en-resource://database/8909:0)]

  ActivationObject.java

@WebListener
public class ActivationObject implements HttpSessionActivationListener, Serializable {
	String name;
	Integer id;
	public String getName() { return this.name; }
	public Integer getId() { return this.id; }
	public void setName( String name ) { this.name = name; }
	public void setId( Integer id ) { this.id = id; }
	
	
	@Override
	public String toString() {
		return ("[ name:" + name + ", id:" + id + " ]" );
	}
	
	@Override
	public void sessionWillPassivate(HttpSessionEvent se) {
		System.out.println("session中的ActivationObject属性值被序列化");
	}

	@Override
	public void sessionDidActivate(HttpSessionEvent se) {
		System.out.println("session中的ActivationObject属性值被活化");
	}

}

  testPassivate.jsp

<body>
	<p>0</p>
	<br>
	<br>
	<%
		ActivationObject a = new ActivationObject();	
		a.setName("测试");
		a.setId(999);
		session.setAttribute("attr", a);
		session.setAttribute("attr2", "5");
		out.write( session.getAttribute("attr").toString() );
	%>
	<br/>
	<br/>
	<a href="./testActivate.jsp">testActivate.jsp页面</a>
</body>

<script>
	var i = 0;
	var p = document.getElementsByTagName("p")[0];
	setInterval(function() {
		i++;
		p.innerHTML = i;
	}, 1000)
</script>

  testActivate.jsp

<body>	
	<%= session.getAttribute("attr2") %>
	<%= session.getAttribute("attr") %>	
</body>

  运行流程 - 以及结果输出

  1. *输入URL: *http://localhost:8080/JavaWeb_servlet/testPassivate.jsp
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6mUVgYFc-1573065934939)(en-resource://database/8905:0)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OuPzdInQ-1573065934943)(en-resource://database/8911:0)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJd7CAff-1573065934949)(en-resource://database/8915:0)]


  1. 等待60秒后,即有上图控制台输出效果后,点击页面的会话活化页面跳转
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWcQpIKP-1573065934957)(en-resource://database/8917:0)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aSBZzi72-1573065934959)(en-resource://database/8919:0)]
    在这里插入图片描述


  1. 经过配置信息的配置,服务器不会自动的序列话所有会话,但是有ActivationObject的会话一定会被序列化。
    关闭并重启服务器

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uZsJIHAU-1573065934973)(en-resource://database/8925:0)]

*浏览器输入URL: *http://localhost:8080/JavaWeb_servlet/testActivate.jsp

重启服务器后会话的信息依然还在

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yEMNtSbT-1573065934977)(en-resource://database/8927:0)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zUCKEfPr-1573065934982)(en-resource://database/8929:0)]

2.2 声明配置

2.2.1 @WebListener
@WebListener
public class TestListener implements ServletContextListener {
}

2.2.2 web.xml文件配置
<listener>
    <listener-class> 包名.TestListener </listener-class>
</listener>