您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎樣解析Servlet Session機制,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
一、Servlet的會話管理機制
HttpSession接口提供了存儲和返回標準會話屬性的方法。標準會話屬性如會話標識符、應用數據等,都以“名字-值”對的形式保存。簡而言之,HttpSession接口提供了一種把對象保存到內存、在同一用戶的后繼請求中提取這些對象的標準辦法。在會話中保存數據的方法是setAttribute(String s, Object o),從會話提取原來所保存對象的方法是getAttribute(String s)。
每當新用戶請求一個使用了HttpSession對象的JSP頁面,JSP容器除了發回應答頁面之外,它還要向瀏覽器發送一個特殊的數字。這個特殊的數字稱為“會話標識符”,它是一個***的用戶標識符。此后,HttpSession對象就駐留在內存之中,等待同一用戶返回時再次調用它的方法。
在客戶端,瀏覽器保存會話標識符,并在每一個后繼請求中把這個會話標識符發送給服務器。會話標識符告訴JSP容器當前請求不是用戶發出的***個請求,服務器以前已經為該用戶創建了HttpSession對象。此時,JSP容器不再為用戶創建新的HttpSession對象,而是尋找具有相同會話標識符的HttpSession對象,然后建立該HttpSession對象和當前請求的關聯。
會話標識符以Cookie的形式在服務器和瀏覽器之間傳送。如果客戶端不支持cookie,運用url改寫機制來保證會話標識符傳回服務器。
二、 Servlet Session事件偵聽
HttpSessionBindingEvent類\
定義\
public class HttpSessionBindingEvent extends EventObject
這個事件是在監聽到HttpSession發生綁定和取消綁定的情況時連通HttpSessionBindingListener的。這可能是一個session被終止或被認定無效的結果。
事件源是HttpSession.putValue或HttpSession.removeValue。
構造函數
public HttpSessionBindingEvent(HttpSession session, String name);
通過引起這個事件的Session和發生綁定或取消綁定的對象名構造一個新的HttpSessionBindingEvent。
方法
1、getName
public String getName();
返回發生綁定和取消綁定的對象的名字。
2、getSession
public HttpSession getSession();
返回發生綁定和取消綁定的session的名字。
HttpSessionBindingListener接口
定義\
public interface HttpSessionBindingListener
這個對象被加入到HTTP的session中,執行這個接口會通告有沒有什么對象被綁定到這個HTTP session中或被從這個HTTP session中取消綁定。
方法
1、valueBound
public void valueBound(HttpSessionBindingEvent event);
當一個對象被綁定到session中,調用此方法。HttpSession.putValue方法被調用時,Servlet引擎應該調用此方法。
2、valueUnbound
public void valueUnbound(HttpSessionBindingEvent event);
當一個對象被從session中取消綁定,調用此方法。HttpSession.removeValue方法被調用時,Servlet引擎應該調用此方法。
Session的事件處理機制與swing事件處理機制不同。Swing采用注冊機制,而session沒有;當任一session發生綁定或其他事件時,都會觸發HttpSessionBindingEvent ,如果servlet容器中存在HttpSessionBindingListener的實現類,則會將事件作為參數傳送給session偵聽器的實現類。在HttpSessionBindingEvent 中可以通過getsession得到發生綁定和取消綁定的session的名字,而偵聽器可以據此做更多處理。
因此,對session的事件偵聽,只需實現HttpSessionBindingListener即可。
從servlet2.3增加了
HttpSessionEvent(This is the class representing event notifications for changes to sessions within a web application)
HttpSessionActivationListener(Objects that are bound to a session may listen to container events notifying them that sessions will be passivated and that session will be activated.)
HttpSessionAttributeListener(This listener interface can be implemented in order to get notifications of changes to the attribute lists of sessions within this web application.)
分別執行不同的任務,處理基本相同。
三、 例子(zz)
捕獲Servlet Session事件的意義:
1、 記錄網站的客戶登錄日志(登錄,退出信息等)
2、 統計在線人數
3、 等等還有很多,呵呵,自己想吧……總之挺重要的。
Session代表客戶的會話過程,客戶登錄時,往Session中傳入一個對象,即可跟蹤客戶的會話。在Servlet中,傳入Session的對象如果是一個實現HttpSessionBindingListener接口的對象(方便起見,此對象稱為監聽器),則在傳入的時候(即調用HttpSession對象的setAttribute方法的時候)和移去的時候(即調用HttpSession對象的removeAttribute方法的時候或Session Time out的時候)Session對象會自動調用監聽器的valueBound和valueUnbound方法(這是HttpSessionBindingListener接口中的方法)。由此可知,登錄日志也就不難實現了。
另外一個問題是,如何統計在線人數,這個問題跟實現登錄日志稍微有點不同,統計在線人數(及其信息),就是統計現在有多少個Session實例存在,我們可以增加一個計數器(如果想存儲更多的信息,可以用一個對象來做計數器,隨后給出的實例中,簡單起見,用一個整數變量作為計數器),通過在valueBound方法中給計數器加1,valueUnbound方法中計數器減1,即可實現在線人數的統計。當然,這里面要利用到ServletContext的全局特性。(有關ServletContext的敘述請參考Servlet規范),新建一個監聽器,并將其實例存入ServletContext的屬性中,以保證此監聽器實例的***性,當客戶登錄時,先判斷ServletContext的這個屬性是否為空,如果不為空,證明已經創建,直接將此屬性取出放入Session中,計數器加1;如果為空則創建一個新的監聽器,并存入ServletContext的屬性中。
舉例說明:
實現一個監聽器:
// SessionListener.java import java.io.*; import java.util.*; import javax.servlet.http.*; //監聽登錄的整個過程 public class SessionListener implements HttpSessionBindingListener { public String privateInfo=""; //生成監聽器的初始化參數字符串 private String logString=""; //日志記錄字符串 private int count=0; //登錄人數計數器 public SessionListener(String info){ this.privateInfo=info; } public int getCount(){ return count; } public void valueBound(HttpSessionBindingEvent event) { count++; if (privateInfo.equals("count")) { return; } try{ Calendar calendar=new GregorianCalendar(); System.out.println("LOGIN:"+privateInfo+" TIME:"+calendar.getTime()); logString="\nLOGIN:"+privateInfo+" TIME:"+calendar.getTime()+"\n"; for(int i=1;i<1000;i++){ File file=new File("yeeyoo.log"+i); if(!(file.exists())) file.createNewFile(); //如果文件不存在,創建此文件 if(file.length()>1048576) //如果文件大于1M,重新創建一個文件 continue; FileOutputStream foo=new FileOutputStream("yeeyoo.log"+i,true); //以append方式打開創建文件 foo.write(logString.getBytes(),0,logString.length()); //寫入日志字符串 foo.close(); break;//退出 } }catch(FileNotFoundException e){} catch(IOException e){} } public void valueUnbound(HttpSessionBindingEvent event) { count--; if (privateInfo.equals("count")) { return; } try{ Calendar calendar=new GregorianCalendar(); System.out.println("LOGOUT:"+privateInfo+" TIME:"+calendar.getTime()); logString="\nLOGOUT:"+privateInfo+" TIME:"+calendar.getTime()+"\n"; for(int i=1;i<1000;i++){ File file=new File("yeeyoo.log"+i); if(!(file.exists())) file.createNewFile(); //如果文件不存在,創建此文件 if(file.length()>1048576) //如果文件大于1M,重新創建一個文件 continue; FileOutputStream foo=new FileOutputStream("yeeyoo.log"+i,true); //以append方式打開創建文件 foo.write(logString.getBytes(),0,logString.length()); //寫入日志字符串 foo.close(); break;//退出 } }catch(FileNotFoundException e){} catch(IOException e){} } } |
登錄日志的實現:
下面再來看看我們的登錄Servlet中使用這個監聽器的部分源代碼:
…… HttpSession session = req.getSession (true); …… ////////////////////////////////////////////////////////////////// SessionListener sessionListener= new SessionListener("IP:"+req.getRemoteAddr()); //對于每一個會話過程均啟動一個監聽器 session.setAttribute("listener",sessionListener); //將監聽器植入HttpSession,這將激發監聽器調用valueBound方法, //從而記錄日志文件。 ////////////////////////////////////////////////////////////////// |
當系統退出登錄時,只需簡單地調用session.removeAttribute(“listener”);
即可自動調用監聽器的valueUnbound方法。或者,當Session Time Out的時候也會調用此方法。
登錄人數的統計:
ServletContext session1=getServletConfig().getServletContext(); //取得ServletContext對象實例 if((SessionListener)session1.getAttribute("listener1")==null) { SessionListener sessionListener1=new SessionListener("count"); //只設置一次,不同于上面日志文件的記錄每次會話均設置。 //即當***個客戶連接到服務器時啟動一個全局變量, //此后所有的客戶將使用相同的上下文。 session1.setAttribute("listener1",sessionListener1); //將監聽器對象設置成ServletContext的屬性,具有全局范圍有效性, //即所有的客戶均可以取得它的實例。 } session.setAttribute("listener1",(SessionListener)session1. getAttribute("listener1")); //取出此全局對象,并且將此對象綁定到某個會話中, //此舉將促使監聽器調用valueBound,計數器加一。 |
在此后的程序中隨時可以用以下代碼取得當前的登錄人數:
((SessionListener)session.getAttribute("listener1")).getCount() |
Servlet Session中的getCount()是監聽器的一個方法,即取得當前計數器的值也就是登錄人數了。
上述內容就是怎樣解析Servlet Session機制,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。