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代码如下:
<%
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代码如下:
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代码如下:
< 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配置如下:
< display-name > login </ display-name >
< listener-class > cn.dao.Test </ listener-class >
</ listener >
<%
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代码如下:
<%
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 >
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代码如下:
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代码如下:
< 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 >