监听:对某一些操作进行监视,那么就称为监听;
在web中的监听主要的功能是用于对ServletConfig、Session、Request进行监听的一种操作;
监听器:
第三种Servlet程序称为监听Servlet,主要的功能是负责监听WEB的各种操作,当相关的事件触发之后将
产生事件,并对此事件进行处理,在WEB中可以对application、session、request三种操作进行监听;
1、对application进行监听:
Application是ServletContext接口的对象,表示的是整个上下文的环境;
javax.servlet.ServletContext接口;
注:application是针对容器的,而不是http协议,所以不像
request、response:
request:javax.servlet.http.HttpServletRequest;
response:javax.servlet.http.HttpServletResponse;
如果要想实现对application监听则可以使用如下两个接口:
·ServletContextListener:-----------对整个上下文环境的监控;
·ServletContextAttributeListener:--对属性的监听;
在ServletContextListener中有两个方法:
contextDestroyed(ServletContextEvent sce):-----销毁
contextInitialized(ServletContextEvent sce):---初始化
·做一个简单的监听,只完成简单的输出;
package listener.lid.servlet;
import javax.servlet.*;
public class ServletContextListenerDemo implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce){
System.out.println("**容器初始化-->"+sce.getServletContext().getContextPath());
}
public void contextDestroyed(ServletContextEvent sce){
System.out.println("**容器销毁**");
}
}
编译上面的servlet;
·配置映射:
简单的Servlet:<servlet> 、<servlet-mapping>---通过mapping进行访问
过滤器:<filter>、<filter-mapping>----通过mapping进行过滤,即过滤哪里
但是现在的监听器就省事了,直接编写<listener>即可;---(即使有mapping也没有意义,不用通过mapping去映射)
如果现在一个web.xml文件之中包含简单servlet、过滤器、监听器,则建议编写配置的顺序
·<filter>
·<filter-mapping>
·<listener>
·<servlet>
·<servlet-mapping>
<listener>
<listener-class>
listener.lid.servlet.ServletContextListenerDemo
</listener-class>
</listener>
重启服务器;
注意:监听器也是在服务器启动的时候加载初始化的,容器关闭时执行销毁;
只要是容器的启动和关闭都要触发这些操作;
还可以实现ServletContextAttributeListener接口:
2、对application属性进行监听:
·编写属性增加的监听:
package listener.lid.servlet;
import javax.servlet.*;
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener{
public void attributeAdded(ServletContextAttributeEvent event){
System.out.println("**增加属性--->属性名称:"+event.getName()+",属性值:"+event.getValue());
}
public void attributeRemoved(ServletContextAttributeEvent event){
System.out.println("**移除属性--->属性名称:"+event.getName()+",属性值:"+event.getValue());
}
public void attributeReplaced(ServletContextAttributeEvent event){
System.out.println("**替换属性--->属性名称:"+event.getName()+",属性值:"+event.getValue());
}
}
编译程序;
·在web.xml配置监听
<listener>
<listener-class>
listener.lid.servlet.ServletContextAttributeListenerDemo
</listener-class>
</listener>
·重启服务器;
·创建网页:
addAttribute.jsp:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<html>
<head><title>这是测试</title></head>
<body>
<%
this.getServletContext().setAttribute("userName1","lid");
this.getServletContext().setAttribute("userName2","yuj");
%>
<h3>属性设置完成</h3>
</body>
</html>
removeAttribute.jsp:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<html>
<head><title>这是测试</title></head>
<body>
<%
this.getServletContext().removeAttribute("userName1");
this.getServletContext().removeAttribute("userName2");
%>
<h3>属性移除完成</h3>
</body>
</html>
在浏览器中输入:http://localhost/lid/listerner/addAttribute.jsp这时会监听到"属性的增加";
如果不断地刷新该网页:这是会监听的"属性的替换";
在浏览器中输入:http://localhost/lid/listerner/removeAttribute.jsp这时会监听到"属性的移除";
3、对session进行监听:
在监听器中,针对于session的监听,提供了三个接口:
·HttpSessionListener
·HttpSessionAttributeListener
·HttpSessionBingdingListener
Session属于HTTP协议的范畴,所以这些接口肯定在javax.servlet.http包中定义的;
·在HttpSessionListener中定义有两种方法:
sessionCreated(HttpSessionEvent se)和sessionDestroyed(HttpSessionEvent se);
·创建一个session监听:
package listener.lid.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
public class HttpSessionListenerDemo implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent se){
System.out.println("**session创建,session id="+se.getSession().getId());
}
public void sessionDestroyed(HttpSessionEvent se){
System.out.println("**session销毁**");
}
}
编译session监听;
·在web.xml中配置:
<listener>
<listener-class>
listener.lid.servlet.HttpSessionListenerDemo
</listener-class>
</listener>
·重启服务器;
通过客户端向服务器发起请求时,session就会创建,这是就会监听到session被创建;
如果现在想让一个session销毁的话,有两种方法,但是这两种方法并不是通过直接关闭浏览器
就可以实现的:
·session的注销方法:invalidate();
·session的超时:在tomcat中session的超时时间默认的是30分钟;
在tomcat的目录conf中找到web.xml,在web.xml中有
<session-config>
<session-timeout>30</session-timeout>
</session-config>
有上面可以看到session的超时时间是30分钟;
当然我们可以自己配置session的超时时间,即在项目的web.xml中加上
<session-config>
<session-timeout>30</session-timeout>
</session-config>
注意:如果修改tomcat中的web.xml中的<session-timeout>的话,session的超时范围将应用
于发布在tomcat中的所有项目;
4、对session属性进行监听:
package listener.lid.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
public class HttpSessionAttributeListenerDemo implements HttpSessionAttributeListener{
public void attributeAdded(HttpSessionBindingEvent se){
System.out.println("**session属性,属性名称="+se.getName()+"属性值"+se.getValue());
}
public void attributeRemoved(HttpSessionBindingEvent se){
System.out.println("**session移除**");
}
public void attributeReplaced(HttpSessionBindingEvent se){
System.out.println("**session替换**");
}
}
配置web.xml:
<listener>
<listener-class>
listener.lid.servlet.HttpSessionAttributeListenerDemo
</listener-class>
</listener>
5、HttpSessionBingdingListener:
对该接口的监听不用在web.xml中进行配置;
package listener.lid.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginUser implements HttpSessionBindingListener{
private String name;
public LoginUser(String name){
this.setName(name);
}
public void valueBound(HttpSessionBindingEvent se){
System.out.println("**在session中保存LoginUser对象(name="+this.getName()+")");
}
public void valueUnbound(HttpSessionBindingEvent se){
System.out.println("**从session中移除**");
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
}
此处不需要任何配置文件的配置;
<%@ page contentType="text/html" pageEncoding="gbk"%>
<%@ page import="listener.lid.servlet.LoginUser"%>
<html>
<head><title>这是测试</title></head>
<body>
<%
LoginUser user=new LoginUser("lid");
session.setAttribute("info",user);//直接保存LoginUser的子类
%>
<h3>属性移除完成</h3>
</body>
</html>
由于此处需要手工绑定,所以才不需要做任何额外的配置;
6、对request监听:
package listener.lid.servlet;
import javax.servlet.*;
public class ServletRequestListenerDemo implements ServletRequestListener{
public void requestInitialized(ServletRequestEvent sre){
System.out.println("**request初始化**http://"+sre.getServletRequest().getRemoteAddr()+
sre.getServletContext().getContextPath());
}
public void requestDestroyed(ServletRequestEvent sre){
System.out.println("**request销毁**");
}
}
编译程序;
在web.xml中编译;
<listener>
<listener-class>
listener.lid.servlet.ServletRequestListenerDemo
</listener-class>
</listener>
7、对request属性监听:
package listener.lid.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
public class ServletRequestAttributeListenerDemo implements ServletRequestAttributeListener{
public void attributeAdded(ServletRequestAttributeEvent se){
System.out.println("**request属性,属性名称="+se.getName()+"属性值"+se.getValue());
}
public void attributeRemoved(ServletRequestAttributeEvent se){
System.out.println("**request移除**");
}
public void attributeReplaced(ServletRequestAttributeEvent se){
System.out.println("**request替换**");
}
}
在web.xml中配置,
<listener>
<listener-class>
listener.lid.servlet.ServletRequestListenerDemo
</listener-class>
</listener>
在实际中对request的监听并不常用,最常用的就是ServletContext、HttpSession监听;
8、监听器的实例:
经常会在各个站点上看到一些在线人员的列表,实际上此操作可以通过监听来完成;
在整个的操作中个,需要使用一下几个接口:
·所有的人员列表应该使用集合保存,但是这个集合所有的用户都能看到,而且以后也要操作,
那么证明整个监听中必然要有一个application对象保存;
·用户登陆成功,增加属性,肯定要使用属性监听接口(HttpSessionAttributeListener)
·当用户离开之后,删除session,所以还要用HttpSessionListener
package listener.lid.servlet;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class OnlineUserList implements ServletContextListener,HttpSessionAttributeListener,HttpSessionListener{
private ServletContext app=null;
public void contextInitialized(ServletContextEvent sce){
this.app=sce.getServletContext();
this.app.setAttribute("online",new TreeSet());//准备集合
}
public void contextDestroyed(ServletContextEvent sce){}
public void attributeAdded(HttpSessionBindingEvent se){
Set all=(Set) this.app.getAttribute("online");
all.add(se.getValue());
this.app.setAttribute("online",all);
}
public void attributeRemoved(HttpSessionBindingEvent se){
Set all=(Set)this.app.getAttribute("online");
all.remove(se.getSession().getAttribute("userid"));
this.app.setAttribute("online",all);
}
public void attributeReplaced(HttpSessionBindingEvent se){}
public void sessionCreated(HttpSessionEvent se){}
public void sessionDestroyed(HttpSessionEvent se){
Set all=(Set)this.app.getAttribute("online");
all.remove(se.getSession().getAttribute("userid"));
this.app.setAttribute("online",all);
}
}
在web.xml中配置:
<listener>
<listener-class>
listener.lid.servlet.OnlineUserList
</listener-class>
</listener>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
重新启动服务器;
login.jsp界面:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<%@ page import="listener.lid.servlet.LoginUser"%>
<html>
<head><title>这是测试</title></head>
<body>
<form action="login.jsp" method="post">
用户ID:<input type="text" name="userid">
<input type="submit" value="登陆">
</form>
<%
String userid=request.getParameter("userid");
if(!(userid==null||"".equals(userid))){
session.setAttribute("userid",userid);
response.sendRedirect("list.jsp");
}
%>
</body>
</html>
list.jsp界面:
<%@ page contentType="text/html" pageEncoding="gbk"%>
<%@ page import="java.util.*"%>
<html>
<head><title>这是测试</title></head>
<body>
<%
Set all=(Set) this.getServletContext().getAttribute("online");
Iterator iter=all.iterator();
while(iter.hasNext()){
%>
<h3><%=iter.next()%></h3>
<%
}
%>
</body>
</html>
还有可能做一些其他的辅助作用等等;