up:: 监听器的第一个范例

本篇博客主要介绍:监听器的应用于三大内置对象的创建以及销毁;内置对象中属性的新增和删除;


一:简介

监听器中六中常用接口:对象监听接口;(对象中的)属性监听接口:

如果对三大内置对象不清楚了,可以查看Java Web三大作用域对象这篇博客;


二:三个内置对象的监听器(内置对象的创建和销毁)

第二部分,主要展示,监听器可以监听“对象的创建”和“对象的销毁”;;;主要观察整个过程啦!

1.案例内容:

首先,编写一个Servlet:HelloServlet

这个Servlet中,设置了ServletContext,HttpSession,HttpServletRequest三个对象的属性;

 
    package com.imooc.listener;
 
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
 
    /**
     * Servlet implementation class HelloServlet
     */
    @WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
 
        /**
         * @see HttpServlet#HttpServlet()
         */
        public HelloServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
 
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		response.getWriter().println("This is HelloSerrvler!");
    		// 得到应用程序全局对象;并在其中设置一个属性;
    		request.getServletContext().setAttribute("sc-attr1", "sc-attr-value1");
    		// 得到用户会话对象;并在其中设置一个属性;
    		request.getSession().setAttribute("session-attr1", "session-attr-value1");
    		// 在请求对象中设置一个属性;
    		request.setAttribute("request-attr1", "request-attr-value1");
    	}
 
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		doGet(request, response);
    	}
 
    }

然后,编写监听器类:WebListener

实现了ServletContextListener,HttpSessionListener,ServletRequestListener三个接口,,每个接口都有两个方法需要实现(分别是创建和销毁的操作)

 
    package com.imooc.listener;
 
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.ServletRequestEvent;
    import javax.servlet.ServletRequestListener;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
 
    /**
     * WebListener类实现ServletContextListener接口,以使该监听器类可以监听ServletContext对象;
     * WebListener类实现HttpSessionListener接口,以使该监听器类可以监听HttpSession对象;
     * WebListener类实现ServletRequestListener接口,以使该监听器类可以监听ServletRequest对象;
     * @author Administrator
     *
     */
    public class WebListener implements ServletContextListener,HttpSessionListener,ServletRequestListener{
 
    	@Override
    	public void contextDestroyed(ServletContextEvent arg0) {
    		// TODO Auto-generated method stub
    		System.out.println("ServletContext已经被销毁。");
 
    	}
 
    	@Override
    	public void contextInitialized(ServletContextEvent arg0) {
    		// TODO Auto-generated method stub
    		System.out.println("ServletContext已经被初始化。");
 
    	}
 
    	@Override
    	public void sessionCreated(HttpSessionEvent se) {
    		// TODO Auto-generated method stub
    		// se:HttpSessionEvent对象(即HttpSession事件对象),这个se参数可以调用方法,获取到已经被创建的Session对象;
    		HttpSession session = se.getSession();
    		System.out.println("Session已经被创建,SessionID为:"+session.getId());
 
    	}
 
    	@Override
    	public void sessionDestroyed(HttpSessionEvent arg0) {
    		// TODO Auto-generated method stub
    		System.out.println("Session已经被销毁。");
    	}
 
    	@Override
    	public void requestDestroyed(ServletRequestEvent arg0) {
    		// TODO Auto-generated method stub
    		System.out.println("HttpServletRequest请求对象已经被销毁。");
    	}
 
    	@Override
    	public void requestInitialized(ServletRequestEvent sre) {
    		// TODO Auto-generated method stub
    		// sre可以获取ServletRequest请求对象,这儿需要强转一下,转成HttpServletRequest类型的;
    		HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();
    		System.out.println("HttpServletRequest请求对象已经被创创建,uri是:"+request.getRequestURI());
 
    	}
 
    }
 

最后,在web.xml中配置监听器

2.启动应用,观察效果:

首先,打开浏览器,发起一次请求:

并打开浏览器,访问上面的Servlet:这个过程,发起了一个请求,会创建一个HttpServletRequest对象;自然这是打开了一个会话,也附带会创建一个HttpSession对象;(具体原理见:用户会话Session对象这篇博客的Session原理解释部分)

访问localhost:8080/listener-interface/hello这个地址的时候,一个HttpServletRequest对象就会被创建;;;因为这是一个新的浏览器窗口发来的请求,所以Tomcat会为其创建一个新的Session对象;;;;紧接着,Servlet处理完成,伴随着响应的输出,刚才创建的HttpServletRequest对象就被销毁了;;;(这几个创建和销毁的过程,自然会触发监听器中对应的方法啦)

然后,关闭浏览器窗口,重新发起请求:

如果此时,关闭浏览器,重新访问localhost:8080/listener-interface/hello:

关闭浏览器窗口时,并不会触发Session对象销毁的操作,这是因为客户端关闭了,只是客户端通信的SessionnId凭证不存在了,而存在于服务器的这个Session对象还是存在的(30min后自动过期,或者人为调用Session销毁的方法来销毁它):

假如,如果不关闭浏览器窗口,而是刷新界面:

最后,关闭应用:


疑问??????为什么,关闭应用的时候,没有调用销毁Session的方法???,解决后,回头补上。。。


三:属性的监听器(内置对象属性的新增和删除)(属性监听器实际中用的不多)

注:属性监听接口,在实际项目中使用的不多,所以这儿一般性了解即可

1.准备工作;增添属性

编写属性的监听器:WebAttributeListener:其中每一个对象的属性接口中,需要实现Add新增方法;Removed删除方法;Replaced修改方法;

 
    package com.imooc.listener;
 
    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
    import javax.servlet.ServletRequestAttributeEvent;
    import javax.servlet.ServletRequestAttributeListener;
    import javax.servlet.http.HttpSessionAttributeListener;
    import javax.servlet.http.HttpSessionBindingEvent;
 
    public class WebAttributeListener implements ServletContextAttributeListener,HttpSessionAttributeListener,ServletRequestAttributeListener{
 
    	@Override
    	public void attributeAdded(ServletContextAttributeEvent event) {
    		// TODO Auto-generated method stub
    		// event.getName();  // 用于获取新增属性的名称;
    		// event.getValue();// 获取新增属性的值;
    		System.out.println("ServletContext对象新增属性了。"+event.getName()+":"+event.getValue());
    	}
 
    	@Override
    	public void attributeRemoved(ServletContextAttributeEvent event) {
    		// TODO Auto-generated method stub
 
    	}
 
    	@Override
    	public void attributeReplaced(ServletContextAttributeEvent event) {
    		// TODO Auto-generated method stub
 
    	}
 
    	@Override
    	public void attributeAdded(HttpSessionBindingEvent event) {
    		// TODO Auto-generated method stub
    		System.out.println("HttpSession对象新增属性了。"+event.getName()+":"+event.getValue());
 
    	}
 
    	@Override
    	public void attributeRemoved(HttpSessionBindingEvent event) {
    		// TODO Auto-generated method stub
 
    	}
 
    	@Override
    	public void attributeReplaced(HttpSessionBindingEvent event) {
    		// TODO Auto-generated method stub
 
    	}
 
    	@Override
    	public void attributeAdded(ServletRequestAttributeEvent event) {
    		// TODO Auto-generated method stub
    		System.out.println("HttpServletRequest对象新增属性了。"+event.getName()+":"+event.getValue());
 
    	}
 
    	@Override
    	public void attributeRemoved(ServletRequestAttributeEvent event) {
    		// TODO Auto-generated method stub
 
    	}
 
    	@Override
    	public void attributeReplaced(ServletRequestAttributeEvent event) {
    		// TODO Auto-generated method stub
 
    	}
 
    }
 

在web.xml配置监听器:

启动应用:访问localhost:8080/listener-interface/hello:


2.属性更新;删除(这两个更少用的到,先有个印象就好啦)

属性的更新: 自然,接上,当已经访问了localhost:8080/listener-interface/hello的时候,再次刷新界面(即再次访问localhost:8080/listener-interface/hello),这个过程自然会重新执行Servlet中给对象中属性赋值的语句,这个给属性重新复制就是修改值啦:


属性的删除: 为了演示效果,在Servlet中添加一个删除属性的语句;然后在监听器的删除方法中添加一个输出语句:

效果: