天天看點

第八章_監聽器

建立監聽器的監聽器接口屬于javax.servlet和javax.servlet.http包的一部分,詳情如下:

javax.servlet.servletcontextlistener。這是對servlet context生命周期事件做出響應的監聽器。建立好servlet context時會馬上調用它的一個方法,并在關閉servlet context之前調用它的另一個方法。

javax.servlet.servletcontextattributelistener。這是在添加、删除或替換某個servlet context屬性時采取相應動作的監聽器。

javax.servlet.http.httpsessionattributelistener。這是在建立、移除或替換servlet上下文屬性時響應的監聽器。

javax.servlet.http.httpsessionattributelistener。這是在添加、删除或替換某個session屬性時被調用的監聽器。

javax.servlet.httpsessionactivationlistener。這是在打開和關閉某個httpsession時被調用的監聽器。

javax.servlet.http.httpsessionbindinglistener。這是一個類,其執行個體将被儲存為可以實作這個接口的httpsession屬性。當它在httpsession中被添加或者删除時,實作httpsessionbindinglistener的類執行個體會收到通知。

javax.servlet.servletrequestlistener。這是對servletrequest的建立和删除做出響應的監聽器。

javax.servlet.servletrequestattributelistener。當servletrequest中添加、删除或替換掉某個屬性時,會調用該監聽器的方法。

javax.servlet.asynclistener。用于異步操作的監聽器。

1、注解

@weblistener

public class listenerclass implements listenerinterface{

}

2、配置檔案

<listener>

<listener-class>fully-qualified listener class</listener-class>

</listener>

在應用程式中可以想要多少個監聽器就可以有多少個監聽器。注意,對監聽器方法的調用是同步進行的。

在servletcontext級别上有兩個監聽器接口:servletcontextlistener和servletcontextattributelistener。

servletcontextlistener會對servletcontext的初始化和解構做出響應。servletcontext被初始化時,servlet容器會在所有已注冊的servletcontextlistener中調用contextinitialized方法,其方法簽名如下:

void contextinitialized(servletcontextevent event)

當servletcontext要被解構和銷毀時,servlet容器會在所有已注冊的servletcontextlistener中調用contextdestroyed方法,以下是contextdestroyed的方法簽名:

void contextdestroyed(servletcontextevent event)

contentinitialized和contextdestroyed都會收到一個來自servlet容器的servletcontextevent。java.util.eventobject類的一個派生類:javax.servlet.servletcontextevent。定義了一個傳回servletcontext的getservletcontext方法:

servletcontext getservletcontext()

這個方法很重要,因為這是方位servletcontext的唯一簡便方法。它有許多servletcontextlistener,可以将屬性儲存在servletcontext中。

下面是個例子:

countries.jsp

<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>  

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  

<html>  

  <head>  

    <title>my jsp 'countries.jsp' starting page</title>  

  </head>  

  <body>  

    we operate in these countries:  

    <ul>  

        <c:foreach items="${countries}" var="country">  

            <li>${country.value}</li>  

        </c:foreach>  

    </ul>  

  </body>  

</html>  

applistener.java

package app08a.listener;  

import java.util.hashmap;  

import java.util.map;  

import javax.servlet.servletcontext;  

import javax.servlet.servletcontextevent;  

import javax.servlet.servletcontextlistener;  

import javax.servlet.annotation.weblistener;  

@weblistener  

public class applistener implements servletcontextlistener{  

    @override  

    public void contextdestroyed(servletcontextevent sce) {  

    }  

    public void contextinitialized(servletcontextevent sce) {  

        system.out.println("servletcontextlistener started");  

        servletcontext servletcontext = sce.getservletcontext() ;  

        map<string,string> countries = new hashmap<string,string>() ;  

        countries.put("ca", "canada") ;  

        countries.put("us", "united states") ;  

        servletcontext.setattribute("countries", countries) ;  

}  

第八章_監聽器
第八章_監聽器

每當servletcontext中添加、删除或替換了某個屬性時,servletcontextattributelistener的實作都會收到通知。下面就是監聽器中定義的三個方法。

void attributeadded(servletcontextattributeevent event)

void attributeremoved(servletcontextattributeevent event)

void attributereplaced(servletcontextattributeevent event)

每當servletcontext中添加了某個屬性時,servlet容器就會調用attributeadded方法。每當servletcontext中删除了某個屬性時,則是調用attributeremoved方法。每當servletcontext被新的替代時,則是調用attributereplaced方法。

servletcontextattributeevent類派生于servletcontextattribute,并添加了下面這兩個方法,分别用來擷取屬性名稱和屬性值。

java.lang.string getname()

java.lang.object.getvalue()

與httpsession有關的監聽器接口有4個:httpsessionlistener、httpsessionactivationlistener、httpsessionattributelistener和httpsessionbindinglistener。

當有httpsession被建立或者銷毀時,servlet容器就會調用所有已注冊的httpsessionlistener。httpsessionlistener中定義的兩個方法是sessioncreated和sessiondestroyed

void sessioncreated(httpsessionevent event)

void sessiondestroyed(httpsessionevent event)

這兩個方法都收到一個httpsessionevent執行個體,它是java.util.event的派生類。我們可以在httpsessionevent中調用getsession方法以獲得所建立或銷毀的httpsession,getsession方法簽名如下:

httpsession getsession()

下面是一個計數器的例子:

sessionlistener.java

import java.util.concurrent.atomic.atomicinteger;  

import javax.servlet.http.httpsession;  

import javax.servlet.http.httpsessionevent;  

import javax.servlet.http.httpsessionlistener;  

public class sessionlistener implements httpsessionlistener,servletcontextlistener{  

        servletcontext.setattribute("usercontroller", new atomicinteger());  

    public void sessioncreated(httpsessionevent se) {  

        httpsession session = se.getsession() ;  

        servletcontext servletcontext = session.getservletcontext() ;  

        atomicinteger usercounter = (atomicinteger)servletcontext.getattribute("usercontroller") ;  

        int usercount = usercounter.incrementandget() ;  

        system.out.println("usercount increment to :" + usercount);  

    public void sessiondestroyed(httpsessionevent se) {  

        int usercount = usercounter.decrementandget() ;  

        system.out.println("usercount decrement to :" + usercount);  

對剛才的jsp進行測試,控制台輸出如下:

usercount increment to :1

如果你換個浏覽器運作,或者等到session過期,你會發現控制台輸出如下:

usercount increment to :2

下面是方法:

void attributeadded(httpsessionbindingevent event)

void attributeremoved(httpsessionbindingevent event)

void attributereplaced(httpsessionbindingevent event)

所有的監聽器方法都會收到一個httpsessionbindingevent執行個體,你可以從中獲得相應的httpsession和屬性值及名稱。

java.lang.object getvalue()

在分布式環境中,多個servlet容器會配置成可伸縮的,為了節省記憶體,servlet容器可以對session屬性進行遷移或者序列化。一般來說,當記憶體比較低時,相對較少通路的對象可以序列化到備用儲存設備中,這樣,servlet容器就能夠注意到哪些session屬性的類實作了httpsessionactivationlistener接口。

這個接口中定義了兩個方法:sessiondisactivate和sessionwillpassivate

void sessiondisactivate(httpsessionevent event)

void sessionwillpassivate(httpsessionevent event)

當httpsessionbindinglistener綁定到httpsession,或者取消綁定時,都會收到通知。如果一個類想要知道什麼時候綁定或取消綁定到httpsession上,那麼這個類要實作httpsessionbindinglistener接口,然後将它的執行個體儲存為session屬性。例如,有個對象的類實作了這個接口,當它儲存為httpsession屬性時,它就可以自動更新。再比如,一但httpsessionbindinglistener與httpsession取消綁定,它的實作就可以釋放占用的資源。

package app08a.model;  

import javax.servlet.http.httpsessionbindingevent;  

import javax.servlet.http.httpsessionbindinglistener;  

public class product implements httpsessionbindinglistener{  

    private string id ;  

    private string name ;  

    private double price ;  

    public string getid() {  

        return id;  

    public void setid(string id) {  

        this.id = id;  

    public string getname() {  

        return name;  

    public void setname(string name) {  

        this.name = name;  

    public double getprice() {  

        return price;  

    public void setprice(double price) {  

        this.price = price;  

    public void valuebound(httpsessionbindingevent event) {  

        string attributename = event.getname() ;  

        system.out.println(attributename + " valuebound");  

    public void valueunbound(httpsessionbindingevent event) {  

        system.out.println(attributename + " valueunbound");  

當監聽器與httpsession綁定或者取消綁定時,它索要做的隻是将内容輸出到控制台即可。

在servletrequest級别上有3個監聽器接口:servletrequestlistener、servletrequestattributelistener和asynclistener。

servletrequestlistener對servletrequest的建立和銷毀做出響應。在servlet容器中是通過池來重用servletrequest的,建立servletrequest花費的時間相當于從池中擷取它的時間,servletrequest銷毀時間則相當于它傳回到池中的時間。

servletrequestlistener接口定義了兩個方法:簽名如下:

void requestinitialized(servletrequestevent event)

void requestdestroyed(servletrequestevent event)

建立servletrequest時會調用requestinitialized方法,servletrequest被銷毀時會調用requestdestroyed方法。這兩個方法都會收到一個servletrequestevent,通過調用getservletrequest方法,可以從中擷取到響應的servletrequest執行個體

servletrequest getservletrequest()

此外,servletrequestevent接口還定義了傳回servletcontext的getservletcontext方法,簽名如下:

下面的這個例子是計算servletrequest建立到銷毀之間的時間差,進而準确得出執行請求所花費的時間。

import javax.servlet.servletrequest;  

import javax.servlet.servletrequestevent;  

import javax.servlet.servletrequestlistener;  

import javax.servlet.http.httpservletrequest;  

public class perfstatlistener implements servletrequestlistener{  

    public void requestdestroyed(servletrequestevent sre) {  

        // todo auto-generated method stub  

        servletrequest servletrequest = sre.getservletrequest() ;  

        long start = (long)servletrequest.getattribute("start") ;  

        long end = system.nanotime() ;  

        httpservletrequest httpservletrequest = (httpservletrequest)servletrequest ;  

        string uri = httpservletrequest.getrequesturi() ;  

        system.out.println("time taken to execute " + uri + ":" + ((end-start)/100) + "microseconds");  

    public void requestinitialized(servletrequestevent sre) {  

        servletrequest.setattribute("start", system.nanotime());  

第八章_監聽器
第八章_監聽器

nanotime方法傳回一個表示任意時間的long。這個傳回值與任何系統概念或者壁鐘的時間無關,但是在同一台jvm中得到的兩個傳回值,最适合用來計算第一個nanotimes調用和第二個調用之間過了多長時間。

但在servletrequest中添加、删除或者替換某個屬性時,會調用servletrequestattributelistener。servletrequestattributelistener接口中定義了3個方法:attributeadded、attributereplaced和attributeremoved,定義如下:

void attributeadded(servletrequestattributeevent event)

void attributereplaced(servletrequestattributeevent  event)

void attributeremoved(servletrequestattributeevent  event)

所有方法都會收到一個servletrequestattributeevent 執行個體。servletrequestattributeevent 類通過getname和getvalue方法暴露有關的屬性: