JavaWeb学习笔记(Servlet事件监听器)
Servlet事件监听器概述
在好处呢关系开发中,经常需要对某些事件进行监听,如监听鼠标单击事件、监听按键事件等,此时需要使用事件监听器。
监听器中有几个重要组成部分:
(1)事件:用户的一个操作
(2)事件源:产生事件的对象
(3)事件监听器:负责监听发生在事件源上的事件
(4)事件处理器:监听器的成员方法,当事件发生的时候会触发对应的处理器的方法。
事件监听器在进行工作是的步骤:
(1)将监听器绑定到事件源上,也就是注册监听器
(2)事件发生是会触发监听器的成员方法,即事件处理器,传递事件对象
(3)事件处理器通过事件对象获得事件源,并对事件源进行处理。
事件监听器的种类
(1)用于监听域对象创建和小会的时间监听器(ServletContextListener接口,HttpSessionListener接口,ServletRequestListener接口)。
(2)用于监听域对象属性增加和删除的时间监听器(ServletContextAttributeListener接口、HttpSessionAttributeListener接口、ServletRequestAttributeListener接口)。
(3)用于监听绑定到HTTPSession域中某个对象状态的时间监听器(HttpSessionBindingListener接口、HttpSessionActivationListener接口)。
监听域对象的生命周期
在Web应用程序的运行期间,Web容器会创建和销毁三个比较重要的对象ServletContext、HttpSession和ServletRequest,这些对象被称为域对象。
ServletContextListener接口
ServletContextListener用来监听ServletContext对象的生命周期,ServletContext对象用于监听该对象的创建于销毁过程。ServletContextListener接口定义了两个事件处理方法。
(1)contextlnitialized()方法
语法定义:
public void contextInitialized(servletContextEvent sce)
当ServletContext对象被创建时,Web容器会调用contextInitialized()方法,contextInitalized()方法接收一个ServletContextEvent类型的参数,contextInitialized()方法内部通过参数创建ServletContext对象。
(2)contextDestroyed()方法
语法定义为:
public void contextDestroyed(servletContextEvent sce)
当ServletContext对象快要被销毁时,Web容器回调用contextDestroy()方法。
HttpSessionListener接口
HttpSession用于完成会话操作,为了监听HttpSession 对象的创建和销毁ServletAPI提供一个HTTPSessionListener接口,当Web应用程序注册了一个或多个实现了HTTPSessionListener接口的事件监听器,Web容器在创建或销毁每个HttpSession对象就会产生一个HttpSessionEvent事件对象,然后依次调用HttpSession事件监听器的相应方法,并将HttpSessionEvent事件对象传递给这些方法。
(1)sessionCreated()方法
语法定义:
public void sessionCreated(HttpSessionEvent se)
每当一个HttpSession对象被创建时,Web容器都会调用sessionCreated()方法,sessionCreated()方法接收一个HttpSessionEvent类型的参数,sessionCreated()方法,内部都可以通过这个参数来获取当前创建的HttpSession对象。
(2)sessionDestroy()方法
语法定义:
public void sessionDestroyed(HttpSessionEvent se)
每当一个HttpSession对象即将被销毁时,Web容器都会调用sessionDestroyed()方法,并将HttpSessionEvent事件对象传递给这个方法。
ServletRequestListener接口
ServletRequest对象用于获取客户端发送的请求数据,为了监听ServletRequest对象的创建和销毁过程,Servlet API提供了ServletRequestListener接口,当Web应用程序中注册了一个或多个实现了ServletRequestListener接口的事件监听器时,Web容器在创建或销毁每个ServletRequest对象时都会产生一个ServletRequestEvent事件对象,然后依次调用每个ServletRequest事件监听器中的相应处理关系。
(1)RequestInitialized()方法
public void requestInitialized(servletRequestEvent sre)
每当一个ServletRequest对象创建时,Web容器都会调用requestIntitlized()方法,resquestInitlized()方法就收一个ServletRequestEvent类型的参数,requestInitialized()方法内部可以通过这个参数来获取当前创建的ServletRequest对象。
(2)requestDestroyed()方法
语法定义:
pubic voidrequestDestroyed(ServletRequestEvent sre)
每当一个ServletRequest对象销毁时,Web容器都会调用requestDestroyed()方法,并将ServletRequestEvent对象传递给这个方法。
示例:
监听域对象的生命周期
(1)创建一个工程,在工程中创建一个cn.itcast.chapter05.listener包,该包中编写一个MyListener类,这个类实现了ServletContextListener、HttpSessionListener和ServletRequestListener三个监听器接口。
package cn.itcast.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyListener implements ServletRequestListener, HttpSessionListener, ServletContextListener {
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContext对象被创建了");
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContext对象被销毁了");
}
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("HttpSession对象被创建了");
}
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("HttpSession对象被销毁了");
}
public void requestInitialized(ServletRequestEvent arg0) {
System.out.println("ServletRequest对象被创建了");
}
public void requestDestroyed(ServletRequestEvent arg0) {
System.out.println("ServletRequest对象被销毁了");
}
}
(2)在web.xml文件中配置MyListener事件监听器
<listener>
<listener-class>cn.itcast.listener.MyListener</listener-class>
</listener>
启动tomcat服务器。
(3)编写一个简单的myjsp.jsp文件,用来查看HttpSessionListener和ServletRequestListener监听器的运行。
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
first.jsp
</body>
</html>
(4)为了尽快查到HttpSession对象销毁过程,在web.xml文件下设置session的超时时间为2min,具体代码如下:
<session-config>
<session-timeout>2</session-timeout>
</session-config>
重新启动Web服务器,运行myjsp.jsp文件,关闭访问myjsp.jsp页面的浏览窗口或保持浏览器的窗口不刷新,与之对应的HttpSession对象将在2min之后被销毁。
监听域对象的属性变更
ServletContext、HttpSession和ServletRequest这三个对象,都可以创建、删除和修改,为了监听这三个对象属性的变更。ServletContextAttributeListener、HttpSessionAttributeListener和ServletRequestAttributeListener接口。
监听对象属性变更的接口
1.attributeAdded()方法
当向被监听的域对象中增加一个属性时,Web容器就会调用事件监听器的attributeAdded方法进行响应,该方法接收一个时间类型的参数,监听器可以通过这个参数来获取正在增加属性的域对象和被保存到域中的属性对象,语法定义为:
public void attributeAdded(ServletContextAtttributeEvent scab)
上述是ServletContextAttributeListener接口中定义的方法,当向ServletContext中增加一个属性时,Web就会调用这个方法并传递一个ServletContextEvent类型参数。
public void attributeAdded(HttpSessionBindEvent se)
上述是ServletRequestAttributeListener接口定义的方法,当向HttpSession对象增加一个属性时,Web容器就会调用这个方法,并传递一个HttpSessionBindingEvent类型的参数。
public void attributeAdded(ServletRequestAttributeEvent sare)
上述是ServletRequestAttributeListener接口定义的方法,当向ServletRequest中增加一个属性时,Web容器就会调用这个方法并传递一个ServletRequestAttributeEvent类型的参数。
2.attributeRemoved()方法
当删除被监听对象中的一个属性时,Web容器调用事件监听器的attributeRemoved()方法进行响应,语法定义为:
public void attributeRemove(ServletContextAttributeEvent scab)
public void attributeRemove(HttpSessionBindEvent se)
public void attributeRemove(ServletRequestAttributeEvent sare)
3.attributeReplace()方法
当监听器的域对象中的某个属性被替换是,Web容器会调用事件监听器的attributeReplaced()方法进行响应。语法定义如下:
public void attributeReplaced(ServletContextAttributeEvent scab)
public void attributeReplaced(HttpSessionBindEvent se)
public void attributeReplaced(ServletRequestAttributeEvent sare)
监听域对象的属性变更
(1)编写一个testattribute.jsp页面,用来观察各个域对象属性事件监听器的作用。
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<h3>这是一个测试界面</h3>
<%
getServletContext().setAttribute("username", "itcast");
getServletContext().setAttribute("username", "itheima");
getServletContext().removeAttribute("username");
session.setAttribute("username", "itcast");
session.setAttribute("username", "itheima");
session.removeAttribute("username");
request.setAttribute("username", "itcast");
request.setAttribute("username", "itcast");
request.removeAttribute("username");
%>
</body>
</html>
(2)编写一个MyAttributeListener类,该类实现ServletContextAttributeListener、HttpSessionAttributeListener和ServletRequestAttributeListener接口。
package cn.itcast.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class MyAttributeListener implements ServletContextAttributeListener, HttpSessionAttributeListener, ServletRequestAttributeListener {
public MyAttributeListener() {
}
public void attributeAdded(ServletContextAttributeEvent scae) {
String name=scae.getName();
System.out.println("ServletContext添加属性:"+name+"="+scae.getServletContext().getAttribute(name));
}
public void attributeRemoved(ServletContextAttributeEvent scae) {
String name=scae.getName();
System.out.println("ServletContext删除属性为:"+name+"="+scae.getServletContext().getAttribute(name));
}
public void attributeRemoved(ServletRequestAttributeEvent srae) {
String name=srae.getName();
System.out.println("ServletRequest移除属性:"+name+"="+srae.getServletRequest().getAttribute(name));
}
public void attributeAdded(ServletRequestAttributeEvent srae) {
String name=srae.getName();
System.out.println("ServletRequest添加属性:"+name+"="+srae.getServletRequest().getAttribute(name));
}
public void attributeReplaced(ServletRequestAttributeEvent srae) {
String name=srae.getName();
System.out.println("ServletRequest替换属性:"+name+"="+srae.getServletRequest().getAttribute(name));
}
public void attributeAdded(HttpSessionBindingEvent se) {
String name=se.getName();
System.out.println("HttpSession添加属性:"+name+"="+se.getSession().getAttribute(name));
}
public void attributeRemoved(HttpSessionBindingEvent se) {
String name=se.getName();
System.out.println("HttpSession移除属性:"+name+"="+se.getSession().getAttribute(name));
}
public void attributeReplaced(HttpSessionBindingEvent se) {
String name=se.getName();
System.out.println("HttpSession替换属性:"+name+"="+se.getSession().getAttribute(name));
}
public void attributeReplaced(ServletContextAttributeEvent scae) {
String name=scae.getName();
System.out.println("ServletContext替换属性:"+name+"="+scae.getServletContext().getAttribute(name));
}
}
(3)修改web.xml文件,
<listener>
<listener-class>cn.itcast.listener.MyAttributeListener</listener-class>
</listener>
(4)启动Web服务器,地址栏中输入http://localhost:9090/Listener/testattribute.jsp
感知被HttpSession绑定的时间监听器
程序开发中经常使用Session域来存储对象,没个对象在该域中都有各种多种状态,如果保存到Session中,从Session中解除绑定,随Session对象持久化到一个存储设备中,随Session对象从一个存储设备中恢复。
HttpSessionBindingListener接口
在使用JavaBean对象时经常会判断该对象是否绑定到HttpSessionBindingListener接口,该接口用于监听JavaBean对象绑定到HttpSession对象和从HttpSession对象的解绑的事件。HttpSessionBindingListener接口定义了两个方法:
1.valueBound()方法
语法定义为
public void valueBound(HttpSessionBindingEvent event)
当对象被绑架到HttpSession对象中,Web容器将调用对象的valueBound()方法并传递一个HttpSessionBindingEvent类型的事件对象,程序可以通过这个事件对象来获得将要绑定到的HttpSession对象。
2.valueUnbound()方法
语法定义为
public void valueUnbound(HttpSessionBindingEvent event)
当对象从HttpSession对象中解除绑定时,Web容器同样将调用valueUnbound()方法并传递一个HttpSessionBindingEvent类型的事件对象。
示例:
编写一个MyBean.java
package cn.itcast.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class Mybean implements HttpSessionBindingListener {
public Mybean() {
}
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("Mybean对象被添加到Session域..."+this);
}
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("MyBean对象从Session中移除了..."+this);
}
}
编写testbinding.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="cn.itcast.listener.Mybean"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<%
session.setAttribute("MyBean",new Mybean());
%>
</body>
</html>
启动Web服务器打开浏览器输入http://localhost:9090/Listener/testbinding.jsp
点击刷新
HttpSessionActivationListener接口
Servlet容器在某些特殊情况下会把这些Http对象从内存转移至硬盘,这个过程称为持久化(钝化),在持久化会话时,Servlet容器不仅会持久化HttpSession对象,还会对它所有可以序列化的属性进行持久化,从而确保存放在会话范围内共享数据不会丢存。当会话从持久化的状态转变为运行状态称为活化。
为了监听HttpSession中能够对象活化和钝化的过程,Servlet API专门提供了HttpSessionActivationListener接口,该接口定义了两个方法。
1.sessionWillPassivate()方法
语法定义:
public void sessionWillPassivate(HttpSessionEvent se)
当绑定HttpSession对象中的对象将要随HttpSession对象被钝化之前,Web容器将调用这个方法并传递一个HttpSessionEvent类型的事件对象,程序通过这个事件对象可以获得之前被钝化的HttpSession对象。
2.sessionDidActivate()方法
语法定义:
public void sessionDidActivate(HttpSessionEvent se)
当绑定到HttpSession对象中将要活化之后,Web容器调用这个方法并传递一个HttpSessionEvent类型的事件对象。
示例:
打开< Tomcat安装目录>\conf\context.xml文件,在< Context>元素中增加如下信息。
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="root"/>
</Manager>
其中< Manager>元素专门用于配置会话管理器,它的className属性用于指定负责创建、销毁和持久化Session。
maxIdleSwap属性用于指定Session被吨花钱的空闲时间间隔。
< Store>元素勇于负责完成具体的持久化任务的类。
directory属性指定保存持久化文件的目录。
(2)编写一个MyBean2.java类,该类实现了HttpSessionActivationListener接口,并实现这个接口中的所有方法。
package cn.itcast.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
public class MyBean2 implements HttpSessionActivationListener {
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("MyBean的对象活化了");
}
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("MyBean的对象钝化了");
}
}
(3)编写一个write.jsp页面,在这个页面将MyBean2对象保存到Session对象中,已查看MyBean2感知自己的Session绑定事件。
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="cn.itcast.listener.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<h1>向Session中存入数据</h1>
<%
MyBean2 myBean=new MyBean2();
myBean.setName("TOM");
myBean.setAge(20);
session.setAttribute("myBean",myBean);
%>
</body>
</html>
(4)编写一个read.jsp页面,这个页面中读取Session域中的对象
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="cn.itcast.listener.MyBean2"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>从Session域中读取数据</h1>
姓名: ${sessionScope.myBean.name}
年龄: ${sessionScope.myBean.age}
</body>
</html>
启动服务器,地址栏输入http://localhost:9090/Listener/write.jsp
启动服务器,地址栏输入http://localhost:9090/Listener/read.jsp
再次访问http://localhost:9090/Listener/read.jsp