天天看点

Servlet监听器1、Servlet监听器简介2、Servlet监听器的原理3、Servlet上下文监听4、HTTP会话监听5、Servlet请求监听6、AsyncListener异步监听7、Servlet监听器统计在线人数

在Servlet技术中已经定义了一些事件,并且可以针对这些事件来编写相关的事件监听器,从而对事件做出相应处理。例如,想要在Web应用程序启动和关闭时执行一些任务(如数据库连接的建立和释放),或者想要监听Session的创建和销毁,那么就可以通过监听器来实现。

1、Servlet监听器简介

监听器的作用是监听Web容器的有效期事件,因此它是由容器管理的。利用Listener接口监听在容器中的某个执行程序,并且根据其应用程序的需求做出适当的响应。下表列出了Servlet中的9个Listener接口和7个Event类。

Listener接口与Event类:

Listener接口 Event类
ServletContextListener ServletContextEvent
ServletContextAttributeListener ServletContextAttributeEvent
HttpSessionListener HttpSessionEvent
HttpSessionActivationListener
HttpSessionAttributeListener HttpSessionBindingEvent
HttpSessionBindingListener
ServletRequestListener ServletRequestEvent
ServletRequestAttributeListener ServletRequestAttributeEvent
AsyncListener AsyncEvent

2、Servlet监听器的原理

Servlet监听器是当今Web应用开发的一个重要组成部分。它是在Servlet2.3规范中和Servlet过滤器一起引入的,并且在Servlet 2.4规范中对其进行了较大的改进,主要就是用来对Web应用进行监听和控制的,极大地增强了Web应用的事件处理能力。

Servlet监听器的功能比较接近Java的GUI程序的监听器,可以监听由于Web应用中状态改变而引起的Servlet容器产生的相应事件,然后接受并处理这些事件。

3、Servlet上下文监听

Servlet上下文监听可以监听ServletContext对象的创建、删除以及属性添加、删除和修改操作,该监听器需要用到如下两个接口。

3.1 ServletContextListener接口

该接口存放在 javax.servlet 包内,它主要实现监听ServletContext的创建和删除。ServletContextListener接口提供了两个方法,它们也被称为“Web应用程序的生命周期方法”。

contextInitialized(ServletContextEvent sce)方法:通知正在收听的对象,应用程序已经被加载及初始化。

contextDestroyed(ServletContextEvent sce)方法:通知正在收听的对象,应用程序已经被载出,即关闭。

示例:创建ServletContextListener接口的监听器。

package com.pjb.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

public class MyContextListener implements ServletContextListener
{
	public MyContextListener()
	{
		// TODO Auto-generated constructor stub
	}

	public void contextInitialized(ServletContextEvent sce)
	{
		// TODO Auto-generated method stub
	}

	public void contextDestroyed(ServletContextEvent sce)
	{
		// TODO Auto-generated method stub
	}
}
           

要让Web容器在Web应用程序启动时通知MyContextListener,需要在 web.xml 文件中使用<listener>元素来配置监听器类。对于本示例,在 web.xml 文件中需要进行配置。

<listener>
	<listener-class>com.pjb.listener.MyContextListener</listener-class>
</listener>
           

3.2 ServletContextAttributeListener接口

该接口存放在 javax.servlet 包内,主要实现监听ServletContext属性的增加、删除和修改。ServletContextAttributeListener接口提供了以下3个方法。

attributeAdded(ServletContextAttributeEvent event)方法:当有对象加入ServletContext对象的范围时,通知正在收听的对象。

attributeReplaced(ServletContextAttributeEvent event)方法:当有ServletContext对象的范围取代另一个对象时,通知正在收听的对象。

attributeRemoved(ServletContextAttributeEvent event)方法:当有ServletContext对象的范围移除时,通知正在收听的对象。

4、HTTP会话监听

HTTP会话监听(HttpSession)信息,有4个接口可以进行监听。

4.1 HttpSessionListener接口

HttpSessionListener接口实现监听HTTP会话的创建、销毁。HttpSessionListener接口提供了以下两个方法。

sessionCreated(HttpSessionEvent se)方法:通知正在收听的对象,session已经被加载及初始化。

sessionDestroyed(HttpSessionEvent se)方法:通知正在收听的对象,session已经被销毁。(HttpSessionEvent 类的主要方法是getSession(),可以使用该方法回传一个session对象)。

4.2 HttpSessionActivationListener接口

HttpSessionActivationListener接口实现监听HTTP会话active和passivate。HttpSessionActivationListener接口提供了以下两个方法。

sessionDidActivate(HttpSessionEvent se)方法:通知正在收听的对象,它的session已经变为有效状态。

sessionWillPassivate(HttpSessionEvent se)方法:通知正在收听的对象,它的session已经变为无效状态。

4.3 HttpSessionAttributeListener接口

HttpSessionAttributeListener接口实现监听HTTP会话中属性的设置请求。HttpSessionAttributeListener接口提供了3个方法。

attributeAdded(HttpSessionBindingEvent event)方法:当有对象加入session的范围时,通知正在收听的对象。

attributeReplaced(HttpSessionBindingEvent event)方法:当在session的范围有对象取代另一个对象时,通知正在收听的对象。

attributeRemoved(HttpSessionBindingEvent event)方法:当有对象从session的范围移除时,通知正在收听的对象。(HttpSessionBindingEvent类主要有3个方法:getName() 、getSession() 、getValue())。

4.4 HttpSessionBindingListener接口

HttpSessionBindingListener接口实现监听HTTP会话中对象的绑定信息,它是唯一不需要再 web.xml 文件中设定Listener的。HttpSessionBindingListener接口提供了以下两个方法。

valueBound(HttpSessionBindingEvent event)方法:当有对象加入session的范围时会被自动调用。

valueUnbound(HttpSessionBindingEvent event)方法:当有对象从session的范围内移除时会被自动调用。

5、Servlet请求监听

在Servlet 2.4规范中,新增加了一个技术,就是可以监听客户端的请求。一旦能够在监听程序中获取客户端的请求,就可以对请求进行统一处理。要实现客户端的请求和请求参数设置的监听需要实现两个接口。

5.1 ServletRequestListener接口

ServletRequestListener接口提供了以下两个方法。

requestInitialized(ServletRequestEvent sre)方法:通知正在收听的对象,ServletRequest已经被加载及初始化。

requestDestroyed(ServletRequestEvent sre)方法:通知正在收听的对象,ServletRequest已经被载出,即关闭。

5.2 ServletRequestAttributeListener接口

ServletRequestAttributeListener接口提供了以下3个方法。

attributeAdded(ServletRequestAttributeEvent srae)方法:当有对象加入request的范围时,通知正在收听的对象。

attributeReplaced(ServletRequestAttributeEvent srae)方法:当在request的范围内有对象取代另一个对象时,通知正在收听的对象。

attributeRemoved(ServletRequestAttributeEvent srae)方法:当有对象从request的范围移除时,通知正在收听的对象。

6、AsyncListener异步监听

Servlet 3.0为异步处理提供了一个监听器,使用AsyncListener接口表示。此接口负责管理异步事件,AsyncListener接口提供了4个方法。

onStartAsync(AsyncEvent event)方法:当异步线程开始时,通知正在收听的对象。

onError(AsyncEvent event)方法:当异步线程出错时,通知正在收听的对象。

onTimeout(AsyncEvent event)方法:当异步线程执行超时,通知正在收听的对象。

onComplete(AsyncEvent event)方法:当异步执行完毕时,通知正在收听的对象。

7、Servlet监听器统计在线人数

监听器的作用是监听Web容器的有效事件,它由Servlet容器管理,利用Listener接口监听某个执行程序,并根据该程序的需求做出适当的响应。下面介绍一个应用Servlet监听器实现统计在线人数的实例。       

示例:应用Servlet监听器统计在线人数。

(1)创建UserInfoList类文件,主要是用来存储在线用户和对在线用户进行具体操作。

package com.pjb.listener;

import java.util.Vector;

/**
 * 用户信息实体类
 * 
 * @author pan_junbiao
 *
 */
public class UserInfoList
{
	private static UserInfoList user = new UserInfoList();
	private Vector vector = null;

	public UserInfoList()
	{
		this.vector = new Vector();
	}

	/* 外界使用的instance对象 */
	public static UserInfoList getInstance()
	{
		return user;
	}

	/* 增加用户 */
	public boolean addUserInfo(String user)
	{
		if (user != null)
		{
			this.vector.add(user);
			return true;
		} else
		{
			return false;
		}
	}

	/* 获取用户列表 */
	public Vector getList()
	{
		return vector;
	}

	/* 移除用户 */
	public void removeUserInfo(String user)
	{
		if (user != null)
		{
			vector.removeElement(user);
		}
	}
}
           

(2)创建UserInfoTrace类文件,主要实现HttpSessionBindingListener接口。HttpSessionBindingListener接口实现监听HTTP会话中对象的绑定信息,它是唯一不需要再 web.xml 文件中设定Listener的。

package com.pjb.listener;

import javax.servlet.http.HttpSessionBindingEvent;

/**
 * 用户信息监听器
 * 
 * @author pan_junbiao
 *
 */
public class UserInfoTrace implements javax.servlet.http.HttpSessionBindingListener
{
	private String user;
	private UserInfoList container = UserInfoList.getInstance();

	public UserInfoTrace()
	{
		user = "";
	}

	public void setUser(String user)
	{
		this.user = user;
	}

	public String getUser()
	{
		return this.user;
	}

	public void valueBound(HttpSessionBindingEvent arg0)
	{
		System.out.println("上线" + this.user);

	}

	public void valueUnbound(HttpSessionBindingEvent arg0)
	{
		System.out.println("下线" + this.user);
		if (user != "")
		{
			container.removeUserInfo(user);
		}
	}
}
           

(3)创建login.jsp登录页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>使用监听查看在线用户</title>
<script language="javascript">
	function checkEmpty(form)
	{
		for(i=0;i<form.length;i++)
		{
			if(form.elements[i].value=="")
			{
				alert("表单信息不能为空");
				return false;
			}
		}
	}
</script>
</head>

<body>
	<form name="form" method="post" action="showUser.jsp" onSubmit="return checkEmpty(form)">
	  	用户名:<input type="text" name="user"><br><br>
	  	<input type="submit" name="Submit" value="登录">
	</form>
</body>
</html>
           

(4)创建showUser.jsp显示页面,在页面中设置session的setMaxInactiveInterval()方法值为10秒,这样可以缩短session的生命周期。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="com.pjb.listener.*"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>使用监听查看在线用户</title>
</head>
<%
	UserInfoList list=UserInfoList.getInstance();
	UserInfoTrace ut=new UserInfoTrace();
	String name=request.getParameter("user");
	ut.setUser(name);
	session.setAttribute("list",ut);
	list.addUserInfo(ut.getUser());
	session.setMaxInactiveInterval(10);
%>
<body>
<h3>当前在线用户:</h3>
<textarea rows="4" cols="20">
<%
	Vector vector=list.getList();
	if(vector!=null&&vector.size()>0){
		for(int i=0;i<vector.size();i++){
		  out.println(vector.elementAt(i));
		}
	}
%>
</textarea><br>
<a href="login.jsp" target="_blank" rel="external nofollow" >返回</a>
</body>
</html>
           

执行结果:

Servlet监听器1、Servlet监听器简介2、Servlet监听器的原理3、Servlet上下文监听4、HTTP会话监听5、Servlet请求监听6、AsyncListener异步监听7、Servlet监听器统计在线人数

当用户输入用户名,点击“登录”后,会进入到在线人数界面。

Servlet监听器1、Servlet监听器简介2、Servlet监听器的原理3、Servlet上下文监听4、HTTP会话监听5、Servlet请求监听6、AsyncListener异步监听7、Servlet监听器统计在线人数

8、Servlet3.0新特性:@WebListener注释

在Servlet3.0中新增了@WebListener注释,使用该注释就不需要在 web.xml 文件中配置<listener>标签了。

@WebListener注释用于声明监听器,该注释用于充当给定web应用上下文中各种web应用事件的监听器的类。可以使用@WebListener来标注一个实现:ServletContextListener、ServletContextAttributeListener、ServletRequestListener、ServletRequestAttributeListener、HttpSessionListener、HttpSessionAttributeListener的类。@WebListener注释有一个value的属性,该属性为可选属性,用于描述监听器信息。

示例:使用@WebListener注释,创建监听器。

@WebListener("监听器的描述信息")
public class MyContextListener implements ServletContextListener
{
	// 省略了监听器中间的代码
}
           

这样配置完成后,就不必在 web.xml 文件中配置相应的<listener>元素了。与上面的代码等价的 web.xml 文件的配置如下:

<listener>
	<listener-class>MyContextListener</listener-class>
</listener>