创建监听器时,只要创建一个实现监听器接口的java类即可
监听器接口有ServletContextListener,HttpSessionListener,HttpSessionBindingListener,ServletRequestListener等接口,下面那进行详细解读
在Servlet3.0中,有两种方法创建
@webListener
public class ListenerClass implements ListenerInterface(){
}
第二种方法时在web.xml部署描述符中使用一个listener元素
</listener>
<listener-class>listener class name</listener-class>
</listener>
一,Servlet Context监听器
ServletContext有两个监听器:ServletContextListener和ServletContextAttributeListener
1ServletContextListener会对ServletContext的初始化和解构做出响应,下面通过一个实例来演示,
一旦ServletContext被初始化,它会将属性map保存在ServletContext属性中
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) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
ServletContext servletContext=sce.getServletContext();
Map<String, String> countries=new HashMap<String, String>();
countries.put("ca", "Canada");
countries.put("cn", "China");
servletContext.setAttribute("countries", countries);
}
}
2,ServletContextAttributeListener
每当ServletContext中添加,删除,替换了某个属性,ServletContextAttributeListener分别
会运行 void attributeAdded(ServletContextAttributeEvent event)
void attributeRemoved(ServletContextAttributeEvent event)
void attributeReplaced(ServletContextAttributeEvent event)方法
ServletContextAttributeEvent类派生与ServletContetAttribute,并添加了下面两个方法
java.lang.String getName()
java.lang.Object getValue()
二,Session监听器
1,HttpSessionListener
当有httpSession被创建或者销毁,Servlet容器就会调用所有已注册的HttpSessionListener
下面通过一个十分实用的例子来演示,用了一个AtomicInteger作为计数器,并保存为ServletContext属性
每当创建HttpSession时,这个计数器就会递增,每当销毁HttpSession时,计数器就会递减,可以用于显示在线人数
import java.util.concurrent.atomic.AtomicInteger;
import javax.print.attribute.standard.Severity;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class SessionListener implements HttpSessionListener,
ServletContextListener {
int userCount;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
ServletContext servletContext=arg0.getServletContext();
servletContext.setAttribute("userCounter", new AtomicInteger());
}
@Override
public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
HttpSession session=arg0.getSession();
ServletContext servletContext=session.getServletContext();
AtomicInteger userCounter= (AtomicInteger) servletContext.
getAttribute("userCounter");
int userCount=userCounter.incrementAndGet();
System.out.println("userCount incremented to :"+userCount);
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
HttpSession session=arg0.getSession();
ServletContext servletContext=session.getServletContext();
AtomicInteger userCounter= (AtomicInteger) servletContext.
getAttribute("userCounter");
int userCount=userCounter.decrementAndGet();
System.out.println("userCount incremented to :"+userCount);
}
}
2,HttpSessionBindingListener
当HttpSessionBindingListener绑定到HttpSession,或者解除绑定时,都会收到通知
3,HttpSessionAttributeListener
当HttpSession中有添加,删除,替换属性的时候它才会被调用,如ServletContextAttributeListener中一样
4,HttpSessionActivationListener
在分布式中,多个Servlet容器会被配置成可伸缩的,为了节省内存,Servlet容器可以对session属性进行迁移或者序列化。
一般来说,当内存比较时,相对较少访问的对象可以序列化到备用设备中,这个接口定义了两个方法
void sessionDidActive(HttpSessionEvent event)
void sessionWillPassivate(HttpSessionEvent event)
三,ServletRequest监听器
ServletRequestListener对ServletRequest的创建和销毁做出响应
下面通过一个实例,来计算完成一个HTTP请求要花费的时间。通过比较运行requestInitiallized 和requestDestroyed
方法中间所隔的时间差,得知完成一个HTTP所花的时间
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
@WebListener
public class PerfStatListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
ServletRequest servletRequest=arg0.getServletRequest();
long start=(Long) servletRequest.getAttribute("start");
//nanoTime方法返回一个表示任意时间的long,在同一台JVM得到两个返回值可以用于所间隔的时间差
long end=System.nanoTime();
HttpServletRequest httpServletRequest=(HttpServletRequest)
arg0.getServletRequest();
String url=httpServletRequest.getRequestURI();
System.out.println("time taken to execute"+url+":"+
(end-start)/1000+" microseconds");
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
ServletRequest servletRequest=arg0.getServletRequest();
servletRequest.setAttribute("start", System.nanoTime());
}
}