Servlet监听
监听器的作用是监听Web容器的有效期事件,因此它是要容器管理。自用Listener接口监听在Container中的某个执行程序,并且根据其应用程序的需求作出适当的响应。
以下列出了Servlet2.4和JSP2.0中的8个Listener接口和6个Event类。
Listener接口与Event类
监听对象
| Listener
| Event
|
监听Servlet上下文
| ServletContextListener
| ServletContextEvent
|
ServletContextAttributeListener
| ServletContextAttributeEvent
|
监听Sessin
| HttpSessionListener
| HttpSessionEvent
|
HttpSessinActivationListerner
|
HttpSessionAttributeListener
| HttpSessionBindingEvent
|
HttpSessionBindingListener
|
监听Request
| ServletRequestListener
| ServletRequestEvent
|
ServletRequestAttributeListener
| ServletRequestAttributeEvent
|
一、Servlet上下文监听
要实现对Servlet上下文监听(ServletContext)需要实现2个接口。
1 ServletContextListener接口
ServletContextListener接口实现ServletContext的创建和删除。ServletContextListener接口提供了2个方法,它们被称为”Web应用程序的生命周期方法”。
(1)ContextInitialized(ServletContextEvent event)方法:通知正在收听的对象,应用程序已加载及初始化。
(2)ContextDestroyed(ServletContextEvent event)方法:通知正在收听的对象,应用程序已卸载。
2 ServletAttributeListener接口
ServletAttributeListener接口实现监听ServletContext属性的增加、删除、修改;ServletAttributeListener提供3个方法。
(1)AttributeAdded(ServletContextAttributeEvent event)方法:若有对象加入Application的范围时,通知正在收听的对象。
(2)AttributeReplaced(ServletContextAttributeEvent event)方法:若在Application的范围内,有对象取代另一个对象时,通知正在收听的对象。
(3)AttributeRemoved(ServletContextAttributeEvent event)方法:若有对象从Application的范围移除时,通知正在收听的对象。
二、HTTP会话监听
HTTP会话监听(HttpSession)信息,有4个接口可以进行监听。
1 HttpSessionListener接口
HttpSessionListener接口实现监听HTTP会话创建、销毁。其提供2个方法。
(1)SessionCreated(HttpSessionEvent event)方法:通知正在收听的对象,Session被加载或初始化。
(2)SessionDestroyed(HttpSessionEvent event)方法:通知正在收听的对象,Session被卸载。(HttpSessionEvent类的getSession()方法返回一个Session对象。)
2 HttpSessionActivationListener接口
HttpSessionActivateionListener接口实现监听HTTP会话active、passivate情况。
HttpSessionActivateionListener接口提供3个方法。
(1)AttributeAdded(HttpSessionBindingEvent event)方法:若有对象加入Session对象时。通知正在收听的对象。
(2)AttributeReplaced(HttpSessionBindingEvent event)方法:若在Session的范围有对象取代另一个对象时,通知正在收听的对象。
(3)AttributeRemoved(HttpSessionBindingEvent event)方法:若有对象从Session的范围移除时,通知正在收听的对象(HttpSessionBindingEvent类主要的3个方法:getName()、getValue()、getSession())。
3 HttpBindingListener接口
HttpBindingListener接口实现监听HTTP会话中对象的绑定信息。它是惟一不需要在web.xml中设定的Listener。其提供2个方法。
(1)ValueBound(HttpSessonBindingEvent event)方法:当有对象加入Session的范围时会被自动调用。
(2)ValueUnBound(HttpSessionBindingEvent event)方法:当有对象从Session的范围内移除时会被自动调用。
4 HttpSessionAttributeListener接口
HttpSessionAttributeListener 接口实现监听HTTP会话中属性的设置请求。其提供2个方法。
(1)SessionDidActivate(HttpSessionEvent event)方法:通知正在收听的对象,它的Session已经变为有效状态。
(2)SessionWillPassivate(HttpSessionEvent event)方法:通知正在收听的对象,它的Session已经变为无效状态。
三、Servlet请求监听
在Servlet2.4中,新增加了一个技术,就是可以监听客户端的请求。要实现监听客户端请求,必须实现以下两个接口。
1 ServletRequestListener接口
(1)RequestInitalized(ServletRequestEvent event)方法:通知正在收听的对象ServletRequest已经被加载及初始化。
(2)RequestDestroyed(ServletRequestEvent event)方法:通知正在收听的对象ServletRequest已经被卸载。
2 ServletRequestAttributeListener接口
(1)AttributeAdd(ServletRequestAttributeEvent event)方法:若有对象加入Request的范围时,通知正在收听的对象。
(2)AttributeReplaced(ServletRequestAttributeEvent event)方法:若在Request的范围内有对象取代另一个对象时,通知正在收听的对象。
(3)AttributeRemoved(ServletRequstAttributeEvent event)方法:若有对象从Request的范围移除时,通知正在收听的对象。
示例1:使用监听查看在线用户
HttpSessionBindingListener接口是惟一一个不用在web.xml中设置的接口。
UserList.java代码如下:
test.jsp代码如下:
<%
@ page language
=
"
java
"
import
=
"
java.util.*,cn.dao.*
"
pageEncoding
=
"
gb18030
"
%>
<%
String path
=
request.getContextPath();
String basePath
=
request.getScheme()
+
"
://
"
+
request.getServerName()
+
"
:
"
+
request.getServerPort()
+
path
+
"
/
"
;
%>

<!
DOCTYPE HTML PUBLIC
"
-//W3C//DTD HTML 4.01 Transitional//EN
"
>
<
html
>
<
head
>
<
base href
=
"
<%=basePath%>
"
>
<
title
>
HttpSessionBindingListener
</
title
>
<
meta http
-
equiv
=
"
refresh
"
content
=
"
60
"
>
<
meta http
-
equiv
=
"
pragma
"
content
=
"
no-cache
"
>
<
meta http
-
equiv
=
"
cache-control
"
content
=
"
no-cache
"
>
<
meta http
-
equiv
=
"
expires
"
content
=
"
0
"
>
<
meta http
-
equiv
=
"
keywords
"
content
=
"
keyword1,keyword2,keyword3
"
>
<
meta http
-
equiv
=
"
description
"
content
=
"
This is my page
"
>
<!--
<
link rel
=
"
stylesheet
"
type
=
"
text/css
"
href
=
"
styles.css
"
>
-->
<%
UserList list
=
UserList.getInstance();
UserListener ul
=
new
UserListener();
String name
=
request.getParameter(
"
name
"
);
ul.setUser(name);
session.setAttribute(
"
list
"
,ul);
list.addUser(ul.getUser());
session.setMaxInactiveInterval(
10
);
%>
</
head
>
<
body
>
<
center
>
<
h2
>
在线用户名单
</
h2
>
<
p
>
<
textarea rows
=
"
10
"
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
>
</
p
>
</
center
>
</
body
>
</
html
>
示例2:利用监听使本机免登录
Test.java代码如下:
package
cn.dao;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletRequestAttributeEvent;
import
javax.servlet.ServletRequestAttributeListener;
import
javax.servlet.ServletRequestEvent;
import
javax.servlet.ServletRequestListener;


public
class
Test
implements
ServletRequestAttributeListener,

ServletRequestListener
...
{

/** *//**
* ServletRequestAttributeListener接口的方法
*/

public void attributeAdded(ServletRequestAttributeEvent arg0) ...{
// TODO 自动生成方法存根
System.out.println("requst attribte add>>");
System.out.println(arg0.getName()+"="+arg0.getValue());

}


public void attributeRemoved(ServletRequestAttributeEvent arg0) ...{
// TODO 自动生成方法存根
System.out.println("request attrbite removed>>");
System.out.println(arg0.getName()+"="+arg0.getValue());
}


public void attributeReplaced(ServletRequestAttributeEvent arg0) ...{
// TODO 自动生成方法存根
System.out.println("request attrbite replaced>>");
System.out.println(arg0.getName()+"="+arg0.getValue());
}


/** *//**
* ServletRequestListener接口的方法
*/

public void requestDestroyed(ServletRequestEvent arg0) ...{
// TODO 自动生成方法存根
System.out.println("request destroy");
}


public void requestInitialized(ServletRequestEvent arg0) ...{
// TODO 自动生成方法存根
System.out.println("request init:");
ServletRequest request=arg0.getServletRequest();
System.out.println("RemoteAddr():"+request.getRemoteAddr());
System.out.println("LocalAddr():"+request.getLocalAddr());

if(request.getRemoteAddr().equals(request.getLocalAddr())) ...{
request.setAttribute("login", "true");

}else ...{
request.setAttribute("login", "false");
}
}
}
default.jsp代码如下:
test1.html代码如下:
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
title
>
对请求监听
</
title
>
<
meta
http-equiv
="keywords"
content
="keyword1,keyword2,keyword3"
>
<
meta
http-equiv
="description"
content
="this is my page"
>
<
meta
http-equiv
="content-type"
content
="text/html; charset=UTF-8"
>
<!--
<link rel="stylesheet" type="text/css" href="./styles.css">
-->

</
head
>
<
body
>
<
span
>
这是本地访问页面,
如果是远程访问,一定要先登录!
</
span
>
</
body
>
</
html
>
web.xml配置如下:
<
listener
>
<
display-name
>
login
</
display-name
>
<
listener-class
>
cn.dao.Test
</
listener-class
>
</
listener
>

<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
gb18030
"
%>
<%
String path
=
request.getContextPath();
String basePath
=
request.getScheme()
+
"
://
"
+
request.getServerName()
+
"
:
"
+
request.getServerPort()
+
path
+
"
/
"
;
%>

<!
DOCTYPE HTML PUBLIC
"
-//W3C//DTD HTML 4.01 Transitional//EN
"
>
<
html
>
<
head
>
<
base href
=
"
<%=basePath%>
"
>
<
title
>
My JSP
'
test1.jsp
'
starting page
</
title
>
<
meta http
-
equiv
=
"
pragma
"
content
=
"
no-cache
"
>
<
meta http
-
equiv
=
"
cache-control
"
content
=
"
no-cache
"
>
<
meta http
-
equiv
=
"
expires
"
content
=
"
0
"
>
<
meta http
-
equiv
=
"
keywords
"
content
=
"
keyword1,keyword2,keyword3
"
>
<
meta http
-
equiv
=
"
description
"
content
=
"
This is my page
"
>
<!--
<
link rel
=
"
stylesheet
"
type
=
"
text/css
"
href
=
"
styles.css
"
>
-->
<%
String login
=
(String)request.getAttribute(
"
login
"
);

if
(
!
login.equals(
"
true
"
))
...
{
response.sendRedirect("/el/test1.jsp");

}
else
...
{
response.sendRedirect("/el/test1.html");
}
%>
</
head
>
<
body
>
This is my JSP page.
<
br
>
</
body
>
</
html
>
test1.jsp代码如下:
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
gb18030
"
%>
<%
String path
=
request.getContextPath();
String basePath
=
request.getScheme()
+
"
://
"
+
request.getServerName()
+
"
:
"
+
request.getServerPort()
+
path
+
"
/
"
;
%>

<!
DOCTYPE HTML PUBLIC
"
-//W3C//DTD HTML 4.01 Transitional//EN
"
>
<
html
>
<
head
>
<
base href
=
"
<%=basePath%>
"
>
<
title
>
登录
</
title
>
<
meta http
-
equiv
=
"
pragma
"
content
=
"
no-cache
"
>
<
meta http
-
equiv
=
"
cache-control
"
content
=
"
no-cache
"
>
<
meta http
-
equiv
=
"
expires
"
content
=
"
0
"
>
<
meta http
-
equiv
=
"
keywords
"
content
=
"
keyword1,keyword2,keyword3
"
>
<
meta http
-
equiv
=
"
description
"
content
=
"
This is my page
"
>
<!--
<
link rel
=
"
stylesheet
"
type
=
"
text/css
"
href
=
"
styles.css
"
>
-->
<%
String submit
=
request.getParameter(
"
Submit
"
);

if
(submit
!=
null
)
...
{
response.sendRedirect("/test.html");
}
%>
</
head
>
<
body
>
<
center
>
<
form action
=
""
>
<
input type
=
"
submit
"
name
=
"
Submit
"
value
=
"
登录
"
>
</
form
>
</
center
>
</
body
>
</
html
>
package
cn.dao;

import
java.util.Vector;


public
class
UserList
...
{
private Vector container;
private static UserList instance=new UserList();

/** *//**
* 利用private调用构造方法
* 防止被外界产生新的instance对象
*/

private UserList() ...{
container=new Vector();
}

/** *//**
* 外界使用instance对象
*/

public static UserList getInstance() ...{
return instance;
}

/** *//**
* 增加用户
*/

public void addUser(String user) ...{

if(user!=null) ...{
container.addElement(user);
}
}

/** *//**
* 获取用户列表
*/

public Vector getList() ...{
return container;
}

/** *//**
* 移除用户
*/

public void removeUser(String user) ...{

if(user!=null) ...{
container.removeElement(user);
}
}
}
UserListener.java代码如下:
package
cn.dao;

import
javax.servlet.http.HttpSessionBindingEvent;
import
javax.servlet.http.HttpSessionBindingListener;



public
class
UserListener
implements
HttpSessionBindingListener
...
{
private String user;
private UserList container=UserList.getInstance();

public UserListener() ...{
user="";
}

/** *//**
* 设置在线监听人员
*/

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

/** *//**
* 获取在线监听
*/

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

public void valueBound(HttpSessionBindingEvent arg0) ...{
// TODO 自动生成方法存根;
System.out.println(user+ " 用户上线!");
}


public void valueUnbound(HttpSessionBindingEvent arg0) ...{
// TODO 自动生成方法存根
container.removeUser(user);
System.out.println(user+" 用户下线!");
}

}
test.html代码如下:
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
title
>
在线监听
</
title
>
<
meta
http-equiv
="keywords"
content
="keyword1,keyword2,keyword3"
>
<
meta
http-equiv
="description"
content
="this is my page"
>
<
meta
http-equiv
="content-type"
content
="text/html; charset=UTF-8"
>
<!--
<link rel="stylesheet" type="text/css" href="./styles.css">
-->

</
head
>
<
body
>
<
form
action
="/el/test.jsp"
>
<
center
>
<
h2
>
在线系统
</
h2
><
br
>
请输入用户名
<
br
>
<
input
type
="text"
id
="name"
><
br
>
<
input
type
="submit"
value
="登 录"
>
</
center
>
</
form
>
</
body
>
</
html
>