-
监听器接口汇总
- 上下文相关
- 初始化完成或者销毁监听器:ServletContextListener
- 新增、删除或者替换一个属性监听器:ServletContextAttributeListener(属性相关)
- 会话有关:
- 跟踪并发用户数量、跟踪活动的会话监听器:HttpSessionListener
- 对象绑定到会话或者对象从会话删除监听器:HttpSessionBindingListener
- 对象所绑定的会话从一个JVM迁移到另外一个JVM时通知:HttpSessionActivationListener
- 增加、删除或者替换一个会话属性监听器:HttpSessionAttributeListener(属性相关)
- 请求相关:
- 请求到来时监听器:ServletRequestListener
- 增加、删除或者替换一个请求属性监听器:ServletRequestAttributeListener(属性相关)
-
上下文监听器(ServletContextListener)--监听器触发时机
- ServletContextListener接口:
- 作用:在初始化ServletContext对象时触发的一个事件,可用于在这个时刻创建一些全局对象,比如数据库连接对象。由于ServletContext初始化时Servlet还没有形成,也就是不会接受外面的请求,所以该事件常用于在请求到来之前初始化一些对象
- 触发时机:
- 容器在初始化完成ServletContext对象后
- 读取web.xml文件,如果发现监听类实现了ServletContextListener接口(比如:MyServletContextListener类),则分别生成两个对象
- 生成监听类对象
- 类来源:用户自定义类:比如 MyServletContextListener
- 类实现的接口:ServletContextListener
- 构造方法:默认无参数构造方法
- 生成事件类对象
- 类来源:容器自动生成
- 类实现的接口:ServletContextEvent
- 构造方法:参数为ServletContext对象的构造方法
- 生成监听类对象
- 触发后效果:用户自定义监听类(比如:MyServletContextListener )就拥有了ServletContext对象,进而可以通过ServletContext对象设置某些属性到上下文中
-
上下文监听器(ServletContextListener)--实例讲解
- 实例操作
- 实体对象类
package model; public class Dog { private String string; public Dog(String str){ string = str; } public String getBeer(){ return string; } }
- 实现ServletContextListener接口的类MyServletContextListener ,生成实体对象并保存到ServletContext属性中
package listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import model.Dog; public class MyServletContextListener implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent sce){ ServletContext servletContext = sce.getServletContext(); Dog dog = new Dog(servletContext.getInitParameter("dog-desc")); //设置servletContext属性,在servlet类中可以获取 servletContext.setAttribute("dog", dog); System.out.println("日志测试:在创建完成servletContext时会触发调用监听类"); } @Override public void contextDestroyed(ServletContextEvent sce){ } }
- 新建listenersc.html,跳转到MyServletListener类的POST方法
<html> <body> <h1 align="center">Beer Selection Page</h1> <form method="POST" action="MyServletListener.do"> Select beer characteristics <p> Color: <select name="color" size="1"> <option value="light">one</option> <option value="amber">two</option> <option value="write">three</option> <option value="black">four</option> </select> <br> <br> <center> <input type="SUBMIT"> </center> </form> </body> </html>
- MyServletListenerTest类从ServletContext 属性中获取实体对象,并且回显属性到界面
package web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import model.Dog; public class MyServletListenerTest extends HttpServlet { /** * Constructor of the object. */ public MyServletListenerTest() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the GET method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the POST method"); //从ServletContext中获取Dog的属性并且打印在界面 ServletContext servletContext = getServletContext(); try { Dog dog = (Dog)servletContext.getAttribute("dog"); String str = ""; str = dog.getBeer(); //打印Dog对象 out.println("Dog:" + str); } catch (Exception e) { // TODO: handle exception System.out.println("获取Dog对象失败"); } out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
- 配置web.xml
<!-- 上下文设置 --> <context-param> <param-name>dog-desc</param-name> <param-value>my dog test</param-value> </context-param> <!-- 设置监听类 --> <listener> <listener-class>listener.MyServletContextListener</listener-class> </listener>
- 测试:
- tomcat启动的试试就进行了初始化
- 地址:http://localhost:8089/myWeb3/listenersc.html
- 结果:
-
上下文属性监听器(ServletContextAttributeListener)--触发时机:
- ServletContextAttributeListener接口:
- 作用:监听ServletContex对象的属性增加、删除、或者替换的触发
- 触发时机:当ServletContex对象调用以下几个方法时都会触发:
- 新增:public void setAttribute(String, Object)
- 删除:public void removeAttribute(String)
- 替换:public void setAttribute(String, Object) 对重复的值就是替换
- 触发结果:可获取属性的名称,属性的值对应的对象
-
上下文属性监听器(ServletContextAttributeListener)--实例讲解
- 定义类MyServletContextAttributeListener实现ServletContextAttributeListener接口
package listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; import model.Dog; public class MyServletContextAttributeListener implements ServletContextAttributeListener{ public void attributeAdded(ServletContextAttributeEvent scab){ System.out.println("attributeAdded:dog被这个方法调用时触发:getServletContext().setAttribute"); String name = scab.getName(); if(name.equals("dog")){ Dog dog = (Dog)scab.getValue(); System.out.println("从新增属性事件中获取属性对象:Dog,它的值是:"+ dog.getBeer()); } } public void attributeRemoved(ServletContextAttributeEvent scab){ System.out.println("attributeRemoved:dog被这个方法调用时触发:getServletContext().RemoveAttribute"); } public void attributeReplaced(ServletContextAttributeEvent scab){ System.out.println("attributeReplaced:dog被这个方法调用时触发:getServletContext().setAttribute"); } }
- 从web.xml中定义监听类
<!-- 设置监听类 --> <listener> <listener-class>listener.MyServletContextAttributeListener</listener-class> </listener>
- 测试重复调用ServletContext的setAttribute/removeAttribute方法,看触发情况
- 方法调用:
//设置servletContext属性,在servlet类中可以获取 servletContext.setAttribute("dog", dog); //这次应该是替换 servletContext.setAttribute("dog", dog); //删除属性 servletContext.removeAttribute("dog"); //又新增属性 servletContext.setAttribute("dog", dog);
- 测试结果:
attributeAdded:dog被这个方法调用时触发:getServletContext().setAttribute
从新增属性事件中获取属性对象:Dog,它的值是:my dog test
attributeReplaced:dog被这个方法调用时触发:getServletContext().setAttribute
attributeRemoved:dog被这个方法调用时触发:getServletContext().RemoveAttribute
attributeAdded:dog被这个方法调用时触发:getServletContext().setAttribute
从新增属性事件中获取属性对象:Dog,它的值是:my dog test
attributeAdded:dog被这个方法调用时触发:getServletContext().setAttribute
- 方法调用:
-
会话跟踪监听器(HttpSessionListener)---触发时机
- HttpSessionListener接口:
- 作用:新增会话或者销毁会话的时候触发
- 触发时机:
- 新增会话:请求参数HttpServletRequest request调用 getSession() 方法时触发新增会话
- 触发结果:可进行会话保存等操作
-
会话跟踪监听器(HttpSessionListener)--实例讲解
- 定义类MyHttpSessionListener实现HttpSessionListener接口
package listener; import java.util.Enumeration; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { // TODO Auto-generated method stub HttpSession httpSession = se.getSession(); System.out.println("新创建session:" + httpSession.getId()); Enumeration<String> enumeration= httpSession.getAttributeNames(); while(enumeration.hasMoreElements()){ System.out.println(enumeration.nextElement()); } } @Override public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub } }
- 从web.xml中定义监听类
<!-- 设置会话创建/销毁监听类 --> <listener> <listener-class>listener.MyHttpSessionListener</listener-class> </listener>
- 测试在任何的servlet类中调用request.getSession()方法,只看到创建一个会话
- 从BeerSelect类中创建
- BeerSelect类的doPost方法获取session
System.out.println("======进来本界面即<<BeerSelect.java>>创建会话======"); request.getSession();
- 测试结果:
======进来本界面即<<BeerSelect.java>>创建会话======
新创建session:3B82DAB9952B1100C22588E747B8ADEF
======进来本界面<<<MyServletListenerTest.java>>>即创建会话======
- BeerSelect类的doPost方法获取session
- 从MyServletListenerTest类中创建
- MyServletListenerTest类的doPost方法获取session
System.out.println("======进来本界面<<<MyServletListenerTest.java>>>即创建会话======"); request.getSession();
- 测试结果:
======进来本界面<<<MyServletListenerTest.java>>>即创建会话======
新创建session:3DF0918D468CD76A25DFA94440CD2265
======进来本界面即<<BeerSelect.java>>创建会话======
- MyServletListenerTest类的doPost方法获取session
- 从BeerSelect类中创建
-
对象绑定到会话监听器(HttpSessionBindingListener)--触发时机
- HttpSessionBindingListener接口:
- 作用:某个对象作为参数传入session.setAttribute或者session.RemoveAttribute方法移除该对象时触发该对象进行相关操作,
- 触发时机:
- 新增会话:某个对象作为参数传入session.setAttribute
- 删除会话:session.RemoveAttribute方法移除该对象时触发
- 触发结果:比如把该对象保存起来
-
对象绑定到会话监听器(HttpSessionBindingListener)--实例讲解
- 自定义类MyHttpSessionBindingListener实现HttpSessionBindingListener接口
package listener; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; public class MyHttpSessionBindingListener implements HttpSessionBindingListener { private String strString ; public MyHttpSessionBindingListener(String str){ strString = str; } @Override public void valueBound(HttpSessionBindingEvent event) { // TODO Auto-generated method stub System.out.println("MyHttpSessionBindingListener类被绑定:它的传入参数为:"+ strString + "它的属性名称为:"+ event.getName()); } @Override public void valueUnbound(HttpSessionBindingEvent event) { // TODO Auto-generated method stub System.out.println("MyHttpSessionBindingListener类被取消绑定:它的传入参数为:"+ strString + "它的属性名称为:"+ event.getName()); } }
- 通过session.setAttribute方法设置自定义对象
HttpSession session = request.getSession(); System.out.println("<<BeerSelect.java>>设置属性:"); String name = "HttpSessionBindingListener——NAME"; session.setAttribute(name, new MyHttpSessionBindingListener(" OKOKOK "));
- 通过session.RemoveAttribute方法取消自定义对象
System.out.println("<<BeerSelect.java>>取消属性:"); session.removeAttribute(name);
- 测试:
- 设置时触发绑定事件
<<BeerSelect.java>>设置属性:
MyHttpSessionBindingListener类被绑定:它的传入参数为: OKOKOK 它的属性名称为:HttpSessionBindingListener——NAME
- 取消时触发取绑定事件
<<BeerSelect.java>>取消属性:
MyHttpSessionBindingListener类被取消绑定:它的传入参数为: OKOKOK 它的属性名称为:HttpSessionBindingListener——NAME
- 设置时触发绑定事件
- 注意:如果被对象被重置,也就是属性名称不变,但是对象变了,这时候HttpSessionBindingListener会受到两个事件,一个是绑定事件,另外一个是原对象的取消事件