1.1 監(jiān)聽器的概述
- 簡述
- 是一個(gè)實(shí)現(xiàn)了特定接口的普通Java類,用于監(jiān)聽其他對象的創(chuàng)建和銷毀,監(jiān)聽其他對象的方法執(zhí)行和屬性改變,
- 被監(jiān)聽的對象如果發(fā)生了上述的事件,監(jiān)聽器的某個(gè)方法就會立刻的執(zhí)行。
- 作用
- 監(jiān)聽(監(jiān)視,觀察)其他對象所發(fā)生的變化,主要用于圖形化界面的程序員,比如Java的GUI,Android,IOS。
- 三個(gè)要素
- 事件源:被監(jiān)聽的對象
- 監(jiān)聽器:用來監(jiān)聽事件源,簡單理解為事件的處理程序 3個(gè)域?qū)ο笠獎(jiǎng)?chuàng)建或者銷毀的時(shí)候,都會執(zhí)行事件監(jiān)聽程序進(jìn)行相應(yīng)的處理ServletContext 創(chuàng)建的時(shí)候,我就可以初始化一些整個(gè)應(yīng)用都用到的參數(shù),一些配置. 等ServletContext被銷毀的時(shí)候我可以執(zhí)行整個(gè)應(yīng)用的保存工作,收尾的工作
- 事件:也就是發(fā)生的那件事,創(chuàng)建和銷毀這件事 當(dāng)這件事發(fā)生的時(shí)候 我們的監(jiān)聽程序應(yīng)該被執(zhí)行
- 使用的三個(gè)步驟
- 要有事件源
- 搞一個(gè)監(jiān)聽器(寫事件的處理程序)
- 把事件和監(jiān)聽器綁定到一起
- 常用監(jiān)聽器的分類
- 第一類 3個(gè) 監(jiān)聽域?qū)ο蟮膭?chuàng)建和銷毀
- 第二類 3個(gè) 監(jiān)聽3個(gè)域?qū)ο蟠鏀?shù)據(jù),取數(shù)據(jù),刪除數(shù)據(jù)這種狀態(tài)
- 第三類 2個(gè) 監(jiān)聽javaBean他自己的狀態(tài)
- 我自偷懶的一些想法
- 監(jiān)聽器在GUI中會使用的很多。。。
- 所以 我這里就大概講講在web中會使用的監(jiān)聽器吧
1.2 Servlet中的監(jiān)聽器
- Servlet規(guī)范為我們提供了8個(gè)監(jiān)聽器。
- 監(jiān)聽域?qū)ο蟮膭?chuàng)建和銷毀
- ServletContextListener
- HttpSessionListener
- ServletRequestListener
- 監(jiān)聽域?qū)ο笾袑傩缘淖兓?
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- 編寫步驟
- 創(chuàng)建一個(gè)普通的Java類
- 讓該類實(shí)現(xiàn)監(jiān)聽器的接口
- 在該類中實(shí)現(xiàn)監(jiān)聽器接口的所有方法
- 在web.xml文件中通過<listener>標(biāo)簽來配置(注冊)監(jiān)聽器
- 幫助JavaBean對象感知自己在session域?qū)ο笾械臓顟B(tài)
- HttpSessionBindingListener
- 幫助javaBean對象感知自己在session對象中的綁定和解綁 ,也就是感知javabean對象被添加到session對象中和被刪除2種狀態(tài)
- HttpSessionActivationListener
- 幫助javaBean對象感知自己在session對象中被鈍化或者恢復(fù)
- 注意:這兩個(gè)特殊的監(jiān)聽器不需要在web.xml文件中配置,讓JavaBean實(shí)現(xiàn)這兩個(gè)接口就可以了
- HttpSessionBindingListener
1.3 監(jiān)聽域?qū)ο蟮膭?chuàng)建和銷毀
- ServletContextListener
- HttpSessionListener
package com.itbear.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//監(jiān)聽ServletContext域?qū)ο蟮膭?chuàng)建
System.out.println("ServletContext域?qū)ο髣?chuàng)建了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//監(jiān)聽ServletContext域?qū)ο蟮匿N毀
System.out.println("ServletContext域?qū)ο箐N毀了");
}
}
1.4 監(jiān)聽域?qū)ο笾袑傩缘淖兓?/h2>
- ServletContextAttributeListener
- HttpSessionAttributeListener
package com.itbear.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
//監(jiān)聽session域?qū)ο笾袑傩缘淖兓?public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
public void attributeAdded(HttpSessionBindingEvent se) {
String name = se.getName();
Object value = se.getValue();
//se.getSession()
System.out.println(name + "=" + value);
System.out.println("session域?qū)ο筇砑恿诵碌膶傩裕?);
}
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("session域?qū)ο笾袑傩缘闹当惶鎿Q了!");
}
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println(se.getName());
System.out.println("session域?qū)ο笾袑傩员粍h除了!");
}
}
注意:
- 點(diǎn)擊紅色按鈕是關(guān)閉 不正常操作 session對象不會被鈍化到硬盤里面,
- 重啟Tomcat是一個(gè)正常的操作,session對象以及他里面的數(shù)據(jù)會被鈍化到硬盤上,重啟之后,,session對象以及他里面的數(shù)據(jù)會被恢復(fù)
不會創(chuàng)建新的session對象
1.5 JavaBean的感知監(jiān)聽器
- 綁定:添加到session域?qū)ο笾?/li>
- 解綁:從session域?qū)ο笾袆h除
package cn.itbear.domain;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
public class Person implements Serializable, HttpSessionBindingListener,HttpSessionActivationListener{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("當(dāng)當(dāng)前javaBean對象被綁定到session域中,javaBean感知自己被添加到了session域中,從而觸發(fā)此事件...");
}
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("當(dāng)當(dāng)前javaBean對象從sessio域中移除,javaBean感知自己從session域中移除了,從而觸發(fā)此事件...");
}
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("javaBean感知自己鈍化了...觸發(fā)此事件...");
}
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("javabean感知自己被活化了...觸發(fā)此事件...");
}
}
package com.itbear.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
//監(jiān)聽session域?qū)ο笾袑傩缘淖兓?public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
public void attributeAdded(HttpSessionBindingEvent se) {
String name = se.getName();
Object value = se.getValue();
//se.getSession()
System.out.println(name + "=" + value);
System.out.println("session域?qū)ο筇砑恿诵碌膶傩裕?);
}
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("session域?qū)ο笾袑傩缘闹当惶鎿Q了!");
}
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println(se.getName());
System.out.println("session域?qū)ο笾袑傩员粍h除了!");
}
}
不會創(chuàng)建新的session對象
package cn.itbear.domain;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
public class Person implements Serializable, HttpSessionBindingListener,HttpSessionActivationListener{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("當(dāng)當(dāng)前javaBean對象被綁定到session域中,javaBean感知自己被添加到了session域中,從而觸發(fā)此事件...");
}
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("當(dāng)當(dāng)前javaBean對象從sessio域中移除,javaBean感知自己從session域中移除了,從而觸發(fā)此事件...");
}
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("javaBean感知自己鈍化了...觸發(fā)此事件...");
}
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("javabean感知自己被活化了...觸發(fā)此事件...");
}
}
訪問
package cn.itbear.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import cn.itheima.domain.Person;
public class SessionDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//創(chuàng)建session對象
HttpSession session = request.getSession();
Person p=new Person();
session.setAttribute("p", p);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
1.6 統(tǒng)計(jì)在線用戶數(shù)
1.6.1 統(tǒng)計(jì)在線用戶數(shù)分析
- 計(jì)數(shù)器
- 可以把計(jì)數(shù)器保存在ServletContext域?qū)ο螽?dāng)中
計(jì)數(shù)器的默認(rèn)值是0 - 如果session域?qū)ο髣?chuàng)建了,那我們認(rèn)為用戶在線了,計(jì)數(shù)器就需要+1
- 如果session域?qū)ο箐N毀了,那我們認(rèn)為用戶離線了,計(jì)數(shù)器就需要-1
- 可以把計(jì)數(shù)器保存在ServletContext域?qū)ο螽?dāng)中
- 在線
- 一個(gè)用戶有了自己的session對象,我們就認(rèn)為這個(gè)用戶在線了
離線 - 一個(gè)用戶手動(dòng)銷毀自己的session對象,獲取超時(shí)了,那我們就認(rèn)為這個(gè)用戶離線了
- 一個(gè)用戶有了自己的session對象,我們就認(rèn)為這個(gè)用戶在線了
1.6.2 代碼
- 監(jiān)聽ServletContext
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class OnlineServletContextListener implements ServletContextListener {
//監(jiān)聽ServletContext域?qū)ο蟮膭?chuàng)建
public void contextInitialized(ServletContextEvent sce) {
//獲取ServletContext域?qū)ο? ServletContext context = sce.getServletContext();
//初始化計(jì)數(shù)器
context.setAttribute("count", 0);
}
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
- 監(jiān)聽 Session
mport javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineHttpSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
//獲取ServletContext對象
ServletContext context = se.getSession().getServletContext();
//獲取計(jì)數(shù)器
Object obj = context.getAttribute("count");
int count = Integer.parseInt(obj.toString());
//使用計(jì)數(shù)器進(jìn)行加一的操作
count++;
//覆蓋替換計(jì)數(shù)器的值
context.setAttribute("count", count);
}
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Object obj = context.getAttribute("count");
int count = Integer.parseInt(obj.toString());
count--;
context.setAttribute("count", count);
}
}