JSP/Servlet 中的事件处理写过AWT或Swing程序的人一定对桌面程序的事件处理机制印象深刻:通过实现Listener接口的类可以在特定事件(Event)发生时,呼叫特定的方法来对事件进行响应。
其实我们在编写JSP/Servle程序时,也有类似的事件处理机制,所不同的是在JSP/Servlet中是在web.xml中注册Listener,由Container在特定事件发生时呼叫特定的实现Listener的类。
1. Servlet中的Listener和Event:
在JSP 2.0/Servlet 2.4中,共有八个Listener接口,六个Event类别。
l ServletContextListener
[接口方法] contextInitialized()与 contextDestroyed()
[接收事件] ServletContextEvent
[触发场景] 在Container加载Web应用程序时(例如启动 Container之后),会呼叫contextInitialized(),而当容器移除Web应用程序时,会呼叫contextDestroyed ()方法。
l ServletContextAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] ServletContextAttributeEvent
[触发场景] 若有对象加入为application(ServletContext)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、attributeRemoved()。
l HttpSessionListener
[接口方法] sessionCreated()与sessionDestroyed ()
[接收事件] HttpSessionEvent
[触发场景] 在session(HttpSession)对象建立或被消灭时,会分别呼叫这两个方法。
l HttpSessionAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为session(HttpSession)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。
l ServletRequestListener
[接口方法] requestInitialized()与 requestDestroyed()
[接收事件] RequestEvent
[触发场景] 在request(HttpServletRequest)对象建立或被消灭时,会分别呼叫这两个方法。
l ServletRequestAttributeListener
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为request(HttpServletRequest)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。
l HttpSessionBindingListener
[接口方法] valueBound()与valueUnbound()
[接收事件] HttpSessionBindingEvent
[触发场景] 实现HttpSessionBindingListener接口的类别,其实例如果被加入至session(HttpSession)对象的属性中,则会呼叫 valueBound(),如果被从session(HttpSession)对象的属性中移除,则会呼叫valueUnbound(),实现HttpSessionBindingListener接口的类别不需在web.xml中设定。
l HttpSessionActivationListener
[接口方法] sessionDidActivate()与 sessionWillPassivate()
[接收事件] HttpSessionEvent
[触发场景] Activate与Passivate是用于置换对象的动作,当session对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透过对象序列化),所作的动作称之为Passivate,而硬盘或储存器上的session对象重新加载JVM时所采的动作称之为Activate,所以容易理解的,sessionDidActivate()与sessionWillPassivate()分别于Activeate后与将Passivate前呼叫。
2. 注册监听器
除了HttpSessionBindingListener和HttpSessionActivationListener外,必须在web.xml中向容器注册,容器才会在对应的事件发生时呼叫对应的类别,如:
<listener>
<listener-class>
demo.servlet.listener.CustomServletContextListener
</listener-class>
</listener>
Listener是Servlet的监听器,它能够监听客户端的哀求、服务端的垄断等。穿越监听器,能够积极激励一些垄断,例如监听在线的用户的数量。当添置一个HttpSession时,就激励sessionCreated(HttpSessionEvent se)措施,这么就能够给在线人数加1。常用的监听接口有以下几个:
ServletContextAttributeL
ServletContextListener监听ServletContext。当创立ServletContext时,激励contextInitialized(ServletContextEvent sce)措施;当烧毁ServletContext时,激励contextDestroyed(ServletContextEvent sce)措施。
HttpSessionListener监听HttpSession的垄断。当创立一个Session时,激励session Created(HttpSessionEvent se)措施;当烧毁一个Session时,激励sessionDestroyed (HttpSessionEvent se)措施。
HttpSessionAttributeList
下?**颐强⒁桓鱿枋档睦樱飧黾嗵髂芄黄詹樵谙叩娜耸T赟ervletContext初始化和烧毁时,在服务器扼制台打印对应的消息。当ServletContext里的属性添置、改换、剔除时,在服务器扼制台打印对应的消息。
要获得以上的功能,监听器定然告终以下3个接口:
HttpSessionListener
ServletContextListener
ServletContextAttributeL
我们看翔实的代码,见示例14-9。
【过程源代码】
1 // ==================== Program Discription =====================
2 // 过程名目:示例14-9 : EncodingFilter .Java
3 // 过程目标:学习利用监听器
4 // ==============================================================
5 import javax.servlet.http.*;
6 import javax.servlet.*;
7
8 public class OnLineCountListener implements HttpSessionListener,
ServletContextListener,ServletContextAttributeL
9 {
10 private int count;
11 private ServletContext context = null;
12
13 public OnLineCountListener()
14 {
15 count=0;
16 //setContext();
17 }
18 //创立一个session时激励
19 public void sessionCreated(HttpSessionEvent se)
20 {
21 count++;
22 setContext(se);
23
24 }
25 //当一个session失效时激励
26 public void sessionDestroyed(HttpSessionEvent se)
27 {
28 count--;
29 setContext(se);
30 }
31 //设置context的属性,它将激励attributeReplaced或attributeAdded措施
32 public void setContext(HttpSessionEvent se)
33 {
34 se.getSession().getServletContext().
setAttribute("onLine",new Integer(count));
35 }
36 //添置一个新的属性时激励
37 public void attributeAdded(ServletContextAttributeE
38
39 log("attributeAdded('" + event.getName() + "', '" +
40 event.getValue() + "')");
41
42 }
43
44 //剔除一个新的属性时激励
45 public void attributeRemoved(ServletContextAttributeE
46
47 log("attributeRemoved('" + event.getName() + "', '" +
48 event.getValue() + "')");
49
50 }
51
52 //属性被轮换时激励
53 public void attributeReplaced(ServletContextAttributeE
54
55 log("attributeReplaced('" + event.getName() + "', '" +
56 event.getValue() + "')");
57 }
58 //context剔除时激励
59 public void contextDestroyed(ServletContextEvent event) {
60
61 log("contextDestroyed()");
62 this.context = null;
63
64 }
65
66 //context初始化时激励
67 public void contextInitialized(ServletContextEvent event) {
68
69 this.context = event.getServletContext();
70 log("contextInitialized()");
71
72 }
73 private void log(String message) {
74
75 System.out.println("ContextListener: " + message);
76 }
77 }