1、课程名称:监听器
监听器的配置及使用
2、知识点
2.1、上次课程的主要知识点
1、 过滤器的配置及使用
2.2、本次预计讲解的知识点
1、 对application监听
2、 对session监听
3、具体内容
监听主要完成的是对容器或session的状态监视,监视的是其创建、销毁、属性操作。
对于监听器大部分情况都是实现若干个接口,而且主要的功能就只有一个:
• 在线人员列表
3.1、application监听
对于监听主要是实现若干个接口,如果对Application监听,则要实现以下两个接口:
• ServletContextListener:对上下文状态进行监听
|- public void contextInitialized(ServletContextEvent sce):上下文初始化
|- public void contextDestroyed(ServletContextEvent sce):上下文销毁
|- 监听事件:ServletContextEvent
|- public ServletContext getServletContext()
• ServletContextAttributeListener:对属性进行监听
|- public void attributeAdded(ServletContextAttributeEvent scab):属性增加
|- public void attributeRemoved(ServletContextAttributeEvent scab):属性删除
|- public void attributeReplaced(ServletContextAttributeEvent scab):属性替换
|- 事件:ServletContextAttributeEvent
|- public java.lang.String getName():取得属性名称
|- public java.lang.Object getValue():取得属性值
那么就可以通过实现以上接口设计一个类,此类就可以对所有上下文的状态进行监视。
ServletContextDemo.java:
package org.lxh.demo.servletcontext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServletContextDemo implements ServletContextListener,
ServletContextAttributeListener {
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("容器销毁。。。");
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("容器初始化。。。"
+ arg0.getServletContext().getRealPath("/"));
}
public void attributeAdded(ServletContextAttributeEvent arg0) {
System.out
.println("属性增加:" + arg0.getName() + " --> " + arg0.getValue());
}
public void attributeRemoved(ServletContextAttributeEvent arg0) {
System.out
.println("属性删除:" + arg0.getName() + " --> " + arg0.getValue());
}
public void attributeReplaced(ServletContextAttributeEvent arg0) {
System.out
.println("属性替换:" + arg0.getName() + " --> " + arg0.getValue());
}
}
要在web.xml中进行此监听器的配置。
web.xml:
<listener>
<listener-class>
org.lxh.demo.servletcontext.ServletContextDemo
</listener-class>
</listener>
demo01.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<%
getServletContext().setAttribute("info","HELLO") ;
getServletContext().removeAttribute("info") ;
%>
</body>
</html>
所有的属性状态都在监听器上有所反映,表示监听就是监控整个上下文状态的。
3.2、session监听
Application是所有用户都共同可以访问的对象,但是对于session是每一个用户都有自己的session。
所以对session的监听实际上是对每一个用户状态的监视。
Session监听的主要接口如下:
• HttpSessionListener:对session的状态监听,例如:创建、销毁
|- public void sessionCreated(HttpSessionEvent se):创建session
|- public void sessionDestroyed(HttpSessionEvent se):销毁session
|- HttpSessionEvent事件:
|- public HttpSession getSession()
• HttpSessionAttributeListener:属性操作的监听
|- public void attributeAdded(HttpSessionBindingEvent se)
|- public void attributeRemoved(HttpSessionBindingEvent se)
|- public void attributeReplaced(HttpSessionBindingEvent se)
|- 监听事件:HttpSessionBindingEvent
|- public HttpSession getSession()
|- public java.lang.String getName()
|- public java.lang.Object getValue()
HttpSessionDemo.java:
package org.lxh.demo.httpsession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class HttpSessionDemo implements HttpSessionListener,
HttpSessionAttributeListener {
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("** SESSION创建:" + arg0.getSession().getId());
}
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("** SESSION销毁:" + arg0.getSession().getId());
}
public void attributeAdded(HttpSessionBindingEvent arg0) {
System.out.println("** SESSION增加属性:" + arg0.getName() + " --> "
+ arg0.getValue());
}
public void attributeRemoved(HttpSessionBindingEvent arg0) {
System.out.println("** SESSION增加删除:" + arg0.getName() + " --> "
+ arg0.getValue());
}
public void attributeReplaced(HttpSessionBindingEvent arg0) {
System.out.println("** SESSION增加替换:" + arg0.getName() + " --> "
+ arg0.getValue());
}
}
web.xml:
<listener>
<listener-class>
org.lxh.demo.httpsession.HttpSessionDemo
</listener-class>
</listener>
demo02.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<%
session.setAttribute("info","hello") ;
session.removeAttribute("info") ;
%>
</body>
</html>
以上代码之中,完成了属性的操作,但是销毁的操作何时调用呢?
有两种情况可以销毁一个session:
• 手工注销session:invalidate
• 超时时间过了:session-timeout
|- 直接在web.xml中配置此时间即可
web.xml:
<session-config>
<session-timeout>1</session-timeout>
</session-config>
以上的配置表示,如果在一分钟之后还没有任何的操作,则会自动销毁session。
3.3、监听器实例 —— 在线用户列表
例如:只要用户登陆成功,则就保存一个完整的列表,此列表应该所有人都可以看见。所以此列表应该保存在application范围之中,但是此列表需要注意的是,如果用户已经走了,应该可以指定定期的删除操作。在一个用户列表的实现应该在application范围里保存一个集合,此集合就是所有用户。
如果要想实现以上的程序,则必须实现以下几个接口:
• ServletContextListener:里面有初始化方法,可以得到application
• HttpSessionListenern、HttpSessionAttributer
OnLine.java:
package org.lxh.demo.online;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnLine implements ServletContextListener, HttpSessionListener,
HttpSessionAttributeListener {
private ServletContext app = null ;
public void contextDestroyed(ServletContextEvent arg0) {
}
public void contextInitialized(ServletContextEvent arg0) {
this.app = arg0.getServletContext() ;
// 在application范围之中,设置一个集合
this.app.setAttribute("userlist", new ArrayList()) ;
}
public void sessionCreated(HttpSessionEvent arg0) {
}
public void sessionDestroyed(HttpSessionEvent arg0) {
// 用户离开之后要从集合中删除此离开的用户
List all = (List)this.app.getAttribute("userlist") ;
all.remove(arg0.getSession().getAttribute("id")) ;
// 把集合重新设置回去
this.app.setAttribute("userlist", all) ;
}
public void attributeAdded(HttpSessionBindingEvent arg0) {
// 如果用户登陆成功,则肯定要增加session的属性,从属性增加中取出用户设置属性的值
List all = (List)this.app.getAttribute("userlist") ;
all.add(arg0.getValue()) ;
// 把集合重新设置回去
this.app.setAttribute("userlist", all) ;
}
public void attributeRemoved(HttpSessionBindingEvent arg0) {
}
public void attributeReplaced(HttpSessionBindingEvent arg0) {
}
}
此监听器的作用,就是当用户增加session属性的时候,向application的集合中保存一个新的内容,如果用户离开之后,则自动从application的集合之中删除掉此用户的信息。
web.xml:
<listener>
<listener-class>
org.lxh.demo.online.OnLine
</listener-class>
</listener>
login.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="login.jsp" method="post">
输入用户ID:<input type="text" name="id">
<input type="submit" value="登陆">
</form>
<%
if(request.getParameter("id")!=null){
session.setAttribute("id",request.getParameter("id")) ;
}
%>
<a href="online.jsp">在线用户</a>
</body>
</html>
online.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<%
List all = (List)application.getAttribute("userlist") ;
Iterator iter = all.iterator() ;
while(iter.hasNext()){
%>
<h3><%=iter.next()%></h3>
<%
}
%>
</body>
</html>
4、总结
发现对于监听器来说,只是一个单独的组件程序,安装到整个项目之中的,本身并不影响项目的直接功能。






