A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Servlet 规范中定义了很多监听器,用于监听Servlet三个数据域对象创建销毁和 内部数据状态改变
Servlet三种存储范围:ServletContext、HttpSession、ServletRequest


Servlet监听器分为三大类
1、数据域对象创建和销毁 监听器
2、数据域对象 属性变更监听器
3、绑定到Session中数据对象 本身状态监听器


第一部分 数据域对象创建销毁监听器 --- 监听三个与对象 (三个监听器)
1、ServletContextListener : 用来监听ServletContext对象的创建和销毁
*contextInitialized(ServletContextEvent sce)  监听创建
*contextDestroyed(ServletContextEvent sce)  监听销毁
* ServletContext对象代表全局唯一对象,每个web工程会产生一个ServletContext,服务器启动创建,服务器关闭销毁


编写监听器
步骤一:编写类实现特定监听器接口
步骤二:注册监听器,不是通过事件源,而是在web.xml 进行配置


ServletContextListener主流应用:
第一个:在服务器启动时,对一些对象进行初始化,并且将对象保存ServletContext数据范围内 --- 全局数据
第二个:对框架进行初始化 例如:Spring框架初始化通过ServletContextListener (因为监听器代码在服务器启动时执行)
第三个:实现任务调度,启动定时程序 Timer、TimerTask) 使一个程序,定时执行
java.util.Timer 一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
Timer提供了启动定时任务方法 schedule
* schedule(TimerTask task, Date firstTime, long period)  用来在指定一个时间启动定时器,定期循环执行
* schedule(TimerTask task, long delay, long period)  用来在当前时间delay多少毫秒后 启动定时器
停止定时器,timer.cancel 取消任务


2、HttpSession 数据对象创建和销毁监听器 ----- HttpSessionListener
* sessionCreated(HttpSessionEvent se)  监听Session对象创建
* sessionDestroyed(HttpSessionEvent se) 监听Session对象销毁


Session 何时创建 : request.getSession()
Session 何时销毁 : 关闭服务器、Session过期、session.invalidate
* Session 过期时间通过web.xml 配置,默认时间 30分钟


3、HttpServletRequest对象的创建和销毁监听器 ---- ServletRequestListener
* requestInitialized(ServletRequestEvent sre)  监听request对象创建
* requestDestroyed(ServletRequestEvent sre) 监听request对象销毁
请求发起时创建,响应结束时销毁


问题:使用forward ---- request创建销毁几次 ----- 一次
使用sendRedirect ---- request创建销毁两次 (两次请求)
ServletContextListener.java
1. package com.listener;  
2.   
3. import java.util.Timer;  
4. import java.util.TimerTask;  
5.   
6. import javax.servlet.ServletContextEvent;  
7. import javax.servlet.ServletContextListener;  
8.   
9. public class MyListener implements ServletContextListener{  
10.   
11.     @Override  
12.     public void contextDestroyed(ServletContextEvent arg0) {  
13.           
14.     }  
15.   
16.     @Override  
17.     public void contextInitialized(ServletContextEvent arg0) {  
18.      
19.         final Timer time=new Timer();   
20.           
21.         time.schedule(new TimerTask(){  
22.   
23.                 @Override  
24.                 public void run() {  
25.                     System.out.println("计时器");  
26.                 }                 
27.         }, 1000*3);  
28.   
29.     }  
30.   
31. }  
第二部分 ServletContext/HttpSession/ServletRequest中保存数据 创建、修改、移除监听器
ServletContextAttributeListener  监听ServletContext中属性变化
HttpSessionAttributeListener  监听HttpSession中属性变化
ServletRequestAttributeListener 监听ServletRequest中属性变化


attributeAdded 监听属性添加 ---- 当数据范围对象没有该属性,第一次添加时调用执行 setAttribute(name,value);
attributeRemoved  监听属性移除 ---- 从一个数据范围对象删除一个已经存在属性执行 removeAttribute(name);
attributeReplaced  监听属性替换 ----- 当一个数据范围已经存在一个属性,向数据范围添加相同名称属性,触发替换方法 --- setAttribute(name,value);


--------------------------------------------------------------------------------------------------------------------------------------
第三部分 被绑定Session对象,自我状态感知监听器
被存放Session的Java对象,感知自我四种状态变化
1、被绑定
2、被解除绑定
3、被钝化 ----- 数据从内存序列化硬盘
4、被活化 ---- 数据从硬盘重新加载回内存


HttpSessionBindingListener 实现接口的java对象,感知自己被绑定到Session或者从Session中解除绑定
HttpSessionActivationListener 实现接口的java对象,感知从内存被钝化硬盘上,从硬盘被活化到内存中


* 不需要配置web.xml 监听方法调用,都是由Session自主完成的


HttpSessionBindingListener
* valueBound(HttpSessionBindingEvent event) 绑定对象方法 ---- session.setAttribute(name,Object);
* valueUnbound(HttpSessionBindingEvent event)  解除绑定方法 ----- session.removeAttribute() 、当Session对象销毁时,当中所有绑定对象解除绑定


HttpSessionActivationListener
* sessionDidActivate(HttpSessionEvent se) 感知对象被活化
* sessionWillPassivate(HttpSessionEvent se)  感知对象被钝化
使用场景:Session保存数据,很长一段时间没用,但是不能销毁Session对象,不想占用服务器内存资源 ----- 钝化(将服务器内存中数据序列化硬盘上)


钝化和活化应该由tomcat服务器 自动进行 ---- 配置tomcat
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>


配置context有几个位置?
1、tomcat/conf/context.xml 对所有虚拟主机 所有web工程生效
2、tomcat/conf/Catalina/localhost/context.xml 对当前虚拟主机所有web工程生效
3、当前工程/META-INF/context.xml 对当前工程有效


钝化后it315目录在哪里? tomcat/work/Catalina/localhost/day18 目录中
序列化? java对象如果向被序列化 实现Serializable ---- Bean2 实现该接口
绑定与解除绑定的样例:
Bean.java
1. package com.bound;  
2.   
3. import javax.servlet.http.HttpSessionBindingEvent;  
4. import javax.servlet.http.HttpSessionBindingListener;  
5.   
6. public class Bean implements HttpSessionBindingListener{  
7.     private int id;  
8.     public int getId() {  
9.         return id;  
10.     }  
11.     public void setId(int id) {  
12.         this.id = id;  
13.     }  
14.     @Override  
15.     public void valueBound(HttpSessionBindingEvent arg0) {  
16.         System.out.print(id+"被绑定了");  
17.     }  
18.     @Override  
19.     public void valueUnbound(HttpSessionBindingEvent arg0) {  
20.         System.out.print(id+"被解除绑定了");  
21.     }  
22. }  
bound.jsp
1. <%@ page language="java" import="java.util.*,com.bound.*" pageEncoding="UTF-8"%>  
2.   
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
4. <html>  
5.   <body>  
6.     <%  
7.       Bean b=new Bean();  
8.       b.setId(1);  
9.       session.setAttribute("bean",b);  
10.         
11.      %>  
12.   </body>  
13. </html>  

钝化与活化的例子:
Bean2.java
1. package com.bound;  
2.   
3. import java.io.Serializable;  
4.   
5. import javax.servlet.http.HttpSessionActivationListener;  
6. import javax.servlet.http.HttpSessionEvent;  
7.   
8. public class Bean2 implements Serializable,HttpSessionActivationListener {  
9.   
10.     private String name;  
11.      
12.     public String getName() {  
13.         return name;  
14.     }  
15.   
16.     public void setName(String name) {  
17.         this.name = name;  
18.     }  
19.   
20.     @Override  
21.     public void sessionDidActivate(HttpSessionEvent arg0) {  
22.         System.out.println(name+"被活化");  
23.     }  
24.   
25.     @Override  
26.     public void sessionWillPassivate(HttpSessionEvent arg0) {  
27.         System.out.println(name+"被钝化");  
28.     }  
29.   
30. }  
write.jsp
1. <%@ page language="java" import="java.util.*,com.bound.*" pageEncoding="UTF-8"%>  
2.   
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
4. <html>  
5.     
6.   <body>  
7.     <%  
8.       Bean2  b2=new Bean2();  
9.       b2.setName("b2");  
10.       session.setAttribute("bean2", b2);  
11.      %>  
12.      This is my JSP page. <br>  
13.   </body>  
14. </html>  
read.jsp
1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
2.   
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
4. <html>  
5.     
6.   <body>  
7.    读取数据:${sessionScope.bean2.name}  
8.   </body>  
9. </html>  
还要在META_INF下建一个context.xml然后进行配置
1. <?xml version="1.0" encoding="UTF-8"?>  
2. <Context>  
3. <!-- 1分钟不用 进行钝化  表示1分钟 -->  
4. <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">  
5. <!-- 钝化后文件存储位置  directory="it315" 存放到it315目录-->  
6. <Store className="org.apache.catalina.session.FileStore" directory="it315"/>  
7. </Manager>  
8. </Context>  

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马