Servlet监听器是web应用程序事件模型的一部分,它用于监听一些web应用中重要事件的发生,监听对象可以在事件发生前,发生后,Servlet容器就会产生相应的事件,Servlet监听器用来处理这些事件。
以下是Servlet中8个监听器接口:
监听对象 | 监听器接口 | 说明 |
ServletRequest(监听请求消息对象) | ServletRequestListener/ ServletRequestAattributeLlistener |
ServletRequestListener主要监听request内置对象的创建和销毁事件;而ServletRequestAttributeListener主要侦听request属性的变化,包括添加新的属性,删除一个已有的属性,修改一个已有的属性; |
ServletContext(监听应用程序环境对象) | ServletContextListener/ ServletContextAttributeListener |
ServletContextListener主要监听web应用程序的创建和销毁事件;ServletContextAttributeListener用来监听ServletContext对象任何属性的变化 |
HttpSession(监听用户会话对象) | HttpSessionListener/ HttpSessionActivationListener/ HttpSessionAttributeListener/ HttpSessionBindingListener |
见后面 |
ServletRequest接口:该接口中定义了两个事件处理方法:
1,public void requestInitialized(ServletRequestEvent event);当产生的request准备进入web应用作用范围事件时,侦听此事件的侦听器被激活,此方法被执行;
2,public void requestDestroyed(ServletRequestEvent event);当产生的request准备超出web应用作用范围事件时,侦听此事件的侦听器被激活,此方法被执行;
ServletRequestEvent是一个事件类,其中有两个关键方法:
(1)public ServletContext getServletContext():返回当前web应用的上下文对象;
(2)public ServletRequest getServletRequest();返回当前请求对应的ServletRequest对象;
ServletRequestAattributeLlistener接口:该接口定义了三个事件处理方法:
1,public void attributeAdded(ServletRequestAttributeEvent event):当上下文添加了新的request属性事件的时候,监听器被激活,这个方法被执行;例如jsp页面使用request.setAttribute("name","Tom")会激活此方法;
2,public void attributeRemoved(ServletRequestAttributeEvent event):当删除了一个已有request属性事件的时候,监听器被激活,这个方法被执行;例如jsp页面使用request.removeAttribute("name","Tom")会激活此方法;
3,public void attributeReplaced(ServletRequestAttributeEvent event):当替换了一个已有的request属性事件的时候,监听器被激活,这个方法被执行;例如jsp页面使用request.replaceAttribute("name","cat")会激活此方法;
ServletContextListener接口:定义了两个事件处理方法,分别监听web应用程序的初始化和结束;
1.public void contextInitalized(ServletContextEvent event):在web应用程序初始化阶段调用该方法,在初始化之前,通知所有ServletContextListener关于上下文初始化的消息;
2,public void contextDestroyed(ServletContextEvent event):在web应用程序结束阶段,Servlet容器会调用该方法,通知侦听器ServletContext对象进入销毁阶段;
ServletContextListenerEvent是一个事件类,当web应用程序启动或者关闭的时候,Servlet容器将事件包装成ServletContextEvent对象,该对象提供了一个方法:
public ServletContext getServletContext();返回ServletContext对象;
ServletContextAttributeListener该接口提供了三个方法:
1,public void attributeAdded(ServletContextAttributeEvent event):通知Servlet上下文中添加了一个新的属性,在添加了新属性之后调用该方法;比如application.addAttribute("userName","张无忌")时会调用该方法;
2,public void attributeRemoved(ServletContextAttributeEvent event):通知现有属性已经从Servlet上下文中移除,在移除属性之后调用该方法;比如application.removeAttribute("userName","张无忌")时会调用该方法;
3,public voidattributeReplaced(ServletContextAttributeEvent event):通知已经替换Servlet上下文中的一个属性。在替换属性之后调用该方法;比如application.replaceAttribute("userName","赵敏")时会调用该方法;
当有对象添加到application中时,application.setAttribute("object",other)触发attributeAdded事件,
当该对象从application移除时,application.removeAttribute("object")触发attriubteRemoved事件,
当该属性的值发生变化时, application.replaceAttribute("object",another)触发attributeRepalced事件。
注意:只要有对象保存到application中或从application中移除或改变属性的值都会触发相应事件,不论该对象是否实现了ServletCcontextAttributeListener。
HttpSessionListener:该监听器有两个方法:
1,sessionCreated:新建一个会话时候触发也可以说是客户端第一次和服务器交互时候触发
2,sessionDestroyed:销毁会话的时候
HttpSessionAttributeListener该接口主要用来侦听session属性的变化,包括session属性的创建,销毁和修改事件,该接口有三个方法:
1,public void attributeAdded(HttpSessionBindingEvent event):当添加了一个新的session属性的时候,监听器被激活,此方法被调用;例如session.addAttribute("userPwd","123");
2,public void attributeRemoved(HttpSessionBindingEvent event):当删除了一个已有的session属性的时候,监听器被激活,此方法被调用;例如session.removeAttribute("userPwd","123");
3,public voidattributeReplaced(HttpSessionBindingEvent event):当替换一个已有的session属性的时候,监听器被激活,此方法被调用;例如session.removeAttribute("userPwd","345");
代码示例:
MyListener implements HttpSessionAttributeListener { attributeAdded(HttpSessionBindingEvenet event) { System.out.println("有对象加入session中"); } attributeRemoved(HttpSessionBindingEvent event) { System.out.println("有对象从session中移除"); } attributeReplaced(HttpSessionBindingEvent event) { System.out.println("属性值改变"); } }
当有对象添加到session中时,session.setAttribute("object",other)触发attributeAdded事件,
当该对象从session移除时,session.removeAttribute("object")触发attriubteRemoved事件,
当该属性的值发生变化时, session.replaceAttribute("object",another)触发attributeRepalced事件。
注意:只要有对象保存到session中或从session中移除或改变属性的值都会触发相应事件,不论该对象是否实现了AttributeListener。
HttpSessionBindingListener:当一个对象实现了该接口,且该对象被绑定到session中或从session中删除时,Servlet容器会通知该对象,该对象在接收到通知后做初始化操作或清除状态操作;
该接口提供了如下方法:
1,public void valueBound(HttpSessionBindingEvent event):当对象正在被绑定到session中时,Servlet容器通知对象它将被绑定到某个对话并标识该对话;
2,public void valueUnBound(HttpSessionBindingEvent event):当从session中删除该对象时,Servlet容器通知对象要从某个会话中取消对它的绑定并标识该对话;
所谓对session进行数据绑定,就是调用session.setAttribute()把HttpSessionBindingListener保存进session中。我们在LoginServlet.java中进行这一步。即HttpSessionListener只需要设置到web.xml中就可以监听整个应用中的所有session。 HttpSessionBindingListener必须实例化后放入某一个session中,才可以进行监听。
代码示例:
public class UserObject implements HttpSessionBindingListener { public void valueBound(HttpSessionBindingEvent event) { System.out.println("触发绑定事件!"); } public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("解除和session的绑定"); } }
UserObject user = new UserObject();
当把该监听器保存到session中,session.setAttribute("user",user)时就会触发valueBound事件.
当该监听器从session中移除时即session.removeAttribute("user"),触发valueUnbound事件;session失效或超时
时也会触发valueUnbound事件。
注意:只有当该监听器(UserObject)保存到session中或从session移除时才会触发事件,其他没有实现该listener对象保存到session时不会触发该事件。
———————————————————————————————————————————————
实例:通过监听器实现页面浏览量,原理:在application对象销毁之前将这次的浏览量存入到数据库中,当下次初始化application对象的时候,将上次的数据库中存储的数据取出来;
MyListener2.java:该类实现监听器接口,并在application销毁之前,将数据存储到数据库中;
package listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import Dbutil.insertemp; public class MyListener2 implements ServletContextListener,ServletContextAttributeListener { @Override public void contextDestroyed(ServletContextEvent event) { System.out.println("销毁application对象"); Object obj = event.getServletContext().getAttribute("aa"); if (obj != null) { try{ int num = (Integer) obj; //在appliation对象销毁之前,将num存储到数据库中 Dbutil.insertemp.insertEmp(num); }catch(Exception e){ e.printStackTrace(); } } } @Override public void contextInitialized(ServletContextEvent event) { System.out.println("初始化application对象"); } @Override public void attributeAdded(ServletContextAttributeEvent event) { String name = event.getName(); Object value = event.getValue(); System.out.println("保存了一个名值对" + name + "<>" + value); } @Override public void attributeRemoved(ServletContextAttributeEvent event) { String name = event.getName(); Object value = event.getValue(); System.out.println("移除了一个名值对" + name + "<>" + value); } @Override public void attributeReplaced(ServletContextAttributeEvent event) { String name = event.getName(); Object value = event.getValue(); System.out.println("修改了一个名值对" + name + "<>" + value); } }
监听器在web.xml中的配置:
<listener> <listener-class>listener.MyListener2</listener-class> </listener>
dbutil.java:该类实现java和数据库的连接
package Dbutil; import java.sql.Connection; import java.sql.DriverManager; public class dbutil { private static Connection conn; public static Connection getConn() throws Exception { if(conn==null){ Class.forName("oracle.jdbc.driver.OracleDriver"); String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL"; conn = DriverManager.getConnection(url, "scott", "1234"); } return conn; } }
insertEmp.java:该类实现将数据插入到数据库中;
package Dbutil; import java.sql.Connection; import java.sql.PreparedStatement; public class insertemp { public static void insertEmp(int num) throws Exception{ //首先获得数据库的连接 Connection conn=dbutil.getConn(); //编写sql语句 String sql="insert into dataemp values(seq_dataemp.nextval,?)"; //获得预编译对象 PreparedStatement stm=conn.prepareStatement(sql); //给预编译对象赋值 stm.setInt(1, num); //执行sql语句 stm.execute(); System.out.println("插入成功"); } }
Dbutil.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.sql.*" %> <% //获得数据库连接 Class.forName("oracle.jdbc.driver.OracleDriver"); String url="jdbc:oracle:thin:@127.0.0.1:1521:ORCL"; Connection conn=DriverManager.getConnection(url,"scott","1234"); %>
login.jsp:当每次运行该页面的时候,浏览量会自动增加
%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="Dbutil.jsp" %> <!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> <% int number; Integer obj=(Integer)application.getAttribute("aa"); if(obj==null){ String sql="select data from dataemp order by id desc"; Statement stm=conn.createStatement(); //执行sql语句 ResultSet rs=stm.executeQuery(sql); if(rs.next()){ number=rs.getInt("data"); System.out.println(number); }else{ number=4000; } }else{ number=obj; } number++; application.setAttribute("aa", number); %> <h3>你是<%=number %>位访客</h3> <form > 账号:<input type="text" name="userName" value="${cookie.userName.value}" /> <br /> 密码:<input type="password" name="password" value="${cookie.password.value}" /><br /> <input type="submit" value="我要登录" /><br /> </form> </body> </html>