程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解JavaWeb中的 Listener

詳解JavaWeb中的 Listener

編輯:關於JAVA

詳解JavaWeb中的 Listener。本站提示廣大學習愛好者:(詳解JavaWeb中的 Listener)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解JavaWeb中的 Listener正文


1、根本概念

JavaWeb外面的listener是經由過程不雅察者設計形式停止完成的。關於不雅察者形式,這裡不做過量引見,年夜概講一下甚麼意思。

不雅察者形式又叫宣布定閱形式或許監聽器形式。在該形式中有兩個腳色:不雅察者和被不雅察者(平日也叫做主題)。不雅察者在主題外面注冊本身感興致的事宜,當這個事宜產生時,主題會經由過程回調接口的方法告訴不雅察者。

舉個生涯中的例子:定閱報紙。任何一個家庭或小我都可以向報社定閱報紙。這裡報社就是“主題”,家庭就是“不雅察者”。好比家庭須要定閱今天凌晨的報紙,這個就是“事宜”。到了第二天凌晨,報紙臨盆出來了,這個就是“事宜產生”。當事宜產生時,送報員將報紙送抵家庭的信箱外面,這裡的信箱就是“回調接口”。

關於JavaWeb外面的監聽器,Servlet標准界說了一些列的Listener接口類,經由過程接口類的方法將事宜裸露給運用法式,運用法式假如想監聽其感興致的事宜,那末不用去直接注冊對應的事宜,而是編寫本身的listener完成響應的接口類,並將本身的listener注冊到servlet容器。當法式關懷的事宜產生時,servlet容器會告訴listener,回調listener外面的辦法。這裡自界說的listener就是不雅察者,servlet容器就是主題。

2、樣例剖析

下面說了,servlet容器是經由過程Listener接口類將事宜裸露給運用法式的。所以我們與其說是注冊事宜,不如說是注冊監聽器。對應到編程步調就是:1.編寫本身的listener,完成特定的Listener接口。2.在web.xml外面注冊本身的listener。這裡以最簡略的監聽器接口ServletContextListener舉例:

1.TestListener.java

public class TestListener implements ServletContextListener {
public TestListener() {}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContextListener.contextInitialized");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContextListener.contextDestroyed");
}
}

2.web.xml

<listener>
<listener-class>com.nantang.listener.TestListener</listener-class>
</listener>

當容器啟動時會向日記中輸入"ServletContextListener.contextInitialized",當容器封閉時會輸入"ServletContextListener.contextDestroyed"。具體的說明前面會進一步剖析。

這裡須要留意是,假如在IDE(Eclipse、STS等)演示下面的例子,當啟動辦事器時,在掌握台可以看到"ServletContextListener.contextInitialized",當封閉辦事器時,是看不到"ServletContextListener.contextDestroyed"的。這不是沒有履行contextDestroyed辦法,而是IDE完成的不敷完善。要想驗證確切挪用了contextDestroyed,可以在contextDestroyed外面寫一段代碼邏輯往文件輸入內容而不要輸入到掌握台。

3、源碼剖析

如今我們剖析下,servlet標准為我們界說了哪些事宜。更精確的說是界說了哪些監聽接口。上面的引見都是以servlet3.0標准為准。

servlet3.0為我們供給了8個監聽器接口,依照它們的感化域來劃分的話可以分為三類:

1.servlet高低文相干監聽接口,包含:ServletContextListener和ServletContextAttributeListener。

2.http session相干監聽接口,包含:HttpSessionListener、HttpSessionActivationListener、HttpSessionAttributeListener和HttpSessionBindingListener。

3.servlet request相干監聽接口,包含:ServletRequestListener和ServletRequestAttributeListener。

其實從接口的定名,列位看官應當能猜出其根本功效。上面我們按分類來說明。

1.servlet高低文相干監聽接口

之前在引見Servlet的時刻,我們說明過一個web運用對應一個servlet高低文。所以ServletContextListener和ServletContextAttributeListener監聽的事宜的性命規模是貫串全部web運用的。上面是這兩個接口的類圖層級關系。

 

1.1 EventListener

EventListener是一個標志接口,一切的事宜監聽器都必需繼續這個接口,這就是servlet標准,沒甚麼好說明的。

1.2 EventObject

和EventListener相似,EventObject是個事宜頂級類,一切詳細的事宜類都必需繼續EventObject。

public class EventObject implements java.io.Serializable {
protected transient Object source;
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
public Object getSource() {
return source;
}
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}

這個類很簡略,其實質就一個器械:source。經由過程類名EventObject和屬性名source,就可以看出這個類就干了一件事,持有“事宜源對象”。

1.3 ServletContextEvent

public class ServletContextEvent extends java.util.EventObject { 
public ServletContextEvent(ServletContext source) {
super(source);
}
public ServletContext getServletContext () { 
return (ServletContext) super.getSource();
}
}

servlet高低文事宜,這個事宜類就是對EventObject的簡略繼續。結構辦法中供給ServletContext實例作為事宜源。由於事宜源是servlet高低文,所以供給個getServletContext獲得ServletContext實例。

在我們後續講授其他事宜類的時刻,都是一個模型,每一個事宜類都供給響應的結構辦法,傳入響應的事宜源對象,並供給額定的獲得事宜源辦法。所以EventObject就是個事宜源的基類,一切事宜子類的實質就干了一件事,肯定詳細的事宜源對象。

所以我們前面講授事宜的處所,一帶而過。

1.4 ServletContextListener

public interface ServletContextListener extends EventListener {
public void contextInitialized ( ServletContextEvent sce );
public void contextDestroyed ( ServletContextEvent sce );
}

servlet高低文監聽器接口,對應著兩個事宜:servlet高低文初始化事宜和servlet高低文行將封閉事宜。

當web運用初始化的時刻,servlet容器會結構ServletContextEven實例,並回調contextInitialize辦法。

當servlet高低文行將封閉時,普通是封閉辦事器之前,servlet容器會結構ServletContextEven實例,並回調contextDestroyed辦法。這裡須要留意的是,contextDestroyed辦法的履行會在一切的servlet和filter履行完destroy辦法以後。

所以假如我們想在運用啟動或封閉時須要做些工作的話,就編寫本身的listener完成該接口。

一切的事宜監聽器也是一個模型,依照servlet標准界說響應的事宜回調接口辦法,辦法的入參就是響應的事宜源實例。所以我們前面講授監聽器的處所也一帶而過。

1.5 ServletContextAttributeEvent

public class ServletContextAttributeEvent extends ServletContextEvent { 
private String name;
private Object value;
public ServletContextAttributeEvent(ServletContext source, String name, Object value) {
super(source);
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public Object getValue() {
return this.value; 
}
}

ServletContextAttributeEvent表現servlet高低文屬性相干事宜,普通當屬性產生轉變時會觸發該事宜。這個類繼續ServletContextEven,事宜源也是ServletContext實例。額定供給屬性名和屬性值的獲得辦法。

1.6 ServletContextAttributeListener

public interface ServletContextAttributeListener extends EventListener {
public void attributeAdded(ServletContextAttributeEvent scab);
public void attributeRemoved(ServletContextAttributeEvent scab);
public void attributeWordStrd(ServletContextAttributeEvent scab);
}

當servlet上文屬性產生增、刪、改的時刻,servlet容器結構ServletContextAttributeEvent事宜對象,分離回調attributeAdded、attributeRemoved、attributeWordStrd辦法。

這裡須要留意的是attributeWordStrd辦法,當屬性的值被調換的時刻回調。這個時刻假如挪用ServletContextAttributeEvent.getValue()辦法前往的是調換之前的屬性值。

2 http session相干監聽接口

2.1 HttpSessionEvent

public class HttpSessionEvent extends java.util.EventObject {
public HttpSessionEvent(HttpSession source) {
super(source);
}
public HttpSession getSession () { 
return (HttpSession) super.getSource();
}
}

http session相干事宜,當session產生變更時會觸發該事宜。事宜源是HttpSession實例,並供給額定的HttpSession獲得辦法。

2.2 HttpSessionListener

public interface HttpSessionListener extends EventListener {
public void sessionCreated ( HttpSessionEvent se );
public void sessionDestroyed ( HttpSessionEvent se );
}

當session被創立和燒毀的時刻,servlet容器結構HttpSessionEvent事宜對象,並回調sessionCreated和sessionDestroyed辦法。

2.3 HttpSessionActivationListener

public interface HttpSessionActivationListener extends EventListener { 
public void sessionWillPassivate(HttpSessionEvent se); 
public void sessionDidActivate(HttpSessionEvent se);
}

當session將要鈍化或已被激活時,servlet容器結構HttpSessionEvent事宜對象,回調sessionWillPassivate和sessionDidActivate辦法。

這裡說明下鈍化和激活:鈍化是指辦事器內存不敷了或許session的運動超不時間到了,把比來不運動的session序列化到磁盤。激活是指某個鈍化的session又被拜訪了,從磁盤將session反序列化到內存。

這裡可以看出要想鈍化和激活,起首session得可序列化和反序列化。同時我們在編程進程中,session盡可能用String、Integer等簡略的對象,盡可能不要用list、map等聚集。

2.4 HttpSessionBindingEvent

public class HttpSessionBindingEvent extends HttpSessionEvent {
private String name;
private Object value;
public HttpSessionBindingEvent(HttpSession session, String name) {
super(session);
this.name = name;
}
public HttpSessionBindingEvent(HttpSession session, String name, Object value) {
super(session);
this.name = name;
this.value = value;
}
public HttpSession getSession () { 
return super.getSession();
}
public String getName() {
return name;
}
public Object getValue() {
return this.value; 
}
}

http session的屬性相干事宜,當session屬性產生變更時會觸發該事宜。事宜源是HttpSession實例,並供給額定的獲得HttpSession、屬性名、屬性值的辦法。

2.5 HttpSessionAttributeListener

public interface HttpSessionAttributeListener extends EventListener {
public void attributeAdded ( HttpSessionBindingEvent se );
public void attributeRemoved ( HttpSessionBindingEvent se );
public void attributeWordStrd ( HttpSessionBindingEvent se );
}

當session屬性產生增、刪、改的時刻,servlet容器結構HttpSessionBindingEvent事宜對象,分離回調attributeAdded、attributeRemoved、attributeWordStrd辦法。

這裡須要留意的是attributeWordStrd辦法,當屬性的值被調換的時刻回調。這個時刻假如挪用ServletContextAttributeEvent.getValue()辦法前往的是調換之前的屬性值。

當挪用session的invalidate辦法或許session掉效時,也會回調attributeRemoved辦法。

2.6 HttpSessionBindingListener

public interface HttpSessionBindingListener extends EventListener {
public void valueBound(HttpSessionBindingEvent event);
public void valueUnbound(HttpSessionBindingEvent event);
}

這個監聽器也是監聽session的屬性變更。當session屬性產生增和刪,也就是屬性值綁定和屬性值解綁的時刻,servlet容器結構HttpSessionBindingEvent事宜對象,分離回調valueBound、valueUnbound辦法。

這麼一看和HttpSessionAttributeListener沒甚麼差別,其實不是如許。二者有個實質的差別就是事宜觸發的前提。

當session的屬性有任何的變更,servlet容器都邑告訴HttpSessionAttributeListener。然則關於HttpSessionBindingListener,只要當綁定或解綁的屬性值是監聽器的實例時,servlet容器才會告訴。舉例來講:

public class TestListener implements HttpSessionBindingListener{
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("HttpSessionBindingListener.valueBound");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("HttpSessionBindingListener.valueUnbound");
}
}

我們自界說監聽器TestListener完成HttpSessionBindingListener,上面我們在代碼中設置以下session屬性:

HttpSession session = request.getSession();
TestListener testListener=new TestListener();
session.setAttribute("listener", testListener);
session.removeAttribute("listener");

這裡session的屬性值是我們的監聽器TestListener實例。所以這段代碼履行時,servlet容器會告訴TestListener並回調valueBound和valueUnbound辦法。

這裡須要留意的是,當挪用session的invalidate辦法或許session掉效時,也會回調valueUnbound辦法。

3 servlet request相干監聽接口

3.1 ServletRequestEvent

public class ServletRequestEvent extends java.util.EventObject { 
private ServletRequest request;
public ServletRequestEvent(ServletContext sc, ServletRequest request) {
super(sc);
this.request = request;
}
public ServletRequest getServletRequest () { 
return this.request;
}
public ServletContext getServletContext () { 
return (ServletContext) super.getSource();
}
}

servlet要求的相干事宜,當request產生變更時會觸發該事宜。事宜源是ServletContext實例,並供給額定的獲得ServletContext和ServletRequest辦法。

3.2 ServletRequestListener

public interface ServletRequestListener extends EventListener {
public void requestDestroyed ( ServletRequestEvent sre );
public void requestInitialized ( ServletRequestEvent sre );
}

當要求初始化或許燒毀時,即客戶端要求進入web運用(進入servlet或許第一個filter)或web運用前往呼應給客戶端(加入servlet或許第一個filter)。servlet容器結構ServletRequestEvent實例,回調requestInitialized和requestDestroyed辦法。

3.3 ServletRequestAttributeEvent

public class ServletRequestAttributeEvent extends ServletRequestEvent { 
private String name;
private Object value;
public ServletRequestAttributeEvent(ServletContext sc, ServletRequest request, String name, Object value) {
super(sc, request);
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public Object getValue() {
return this.value; 
}
}

servlet要求屬性的相干事宜,當要求屬性產生變更時會觸發該事宜。事宜源是ServletContext實例,並供給額定的獲得屬性名和屬性值的辦法。

3.4 ServletRequestAttributeListener

public interface ServletRequestAttributeListener extends EventListener {
public void attributeAdded(ServletRequestAttributeEvent srae);
public void attributeRemoved(ServletRequestAttributeEvent srae);
public void attributeWordStrd(ServletRequestAttributeEvent srae);
}

當要求的屬性產生增、刪、改的時刻,servlet容器結構ServletRequestAttributeEvent事宜對象,分離回調attributeAdded、attributeRemoved、attributeWordStrd辦法。

這裡須要留意的是attributeWordStrd辦法,當屬性的值被調換的時刻回調。這個時刻假如挪用ServletRequestAttributeEvent.getValue()辦法前往的是調換之前的屬性值。

4、總結

至此,listener講完了。我們可以發明listener和servlet、filter有個配合點,都是由容器停止調劑。我們只須要編寫本身的listener去完成我們關懷的監聽器接口並注冊,剩上去的任務就是在我們本身的listener外面編寫營業邏輯。

這邊博文引見的listener是servlet3.0標准制訂的。3.1曾經增長了一些事宜監聽器接口,事理都是相似的,讀者可以自行去懂得。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved