天天看点

第八章_监听器

创建监听器的监听器接口属于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方法暴露有关的属性: