java程序设计——监听器

java程序设计——监听器

监听器简介

监听器主要用来监听对象的创建,属性的变化,是一个实现特定接口的普通java类

在这里插入图片描述
Listener接口与事件对应表
在这里插入图片描述

编写监听器的步骤
  • 编写实现类
  • 在web.xml中进行部署
  • 编写测试页面
概览:
  • 与ServletContext相关监听器:
    监听器的作用范围是单个web站点,如从Tomcat启动到关闭

  • 与HttpSession相关监听器:
    作用范围是一次会话,如:通过firefox给s1 进行属性赋值后关闭firefox,再次通过Chrome打开通过s1的getAttribute(“”)来进行获取属性,是获取不倒的

  • 与ServletRequest相关监听器:
    作用范围是一次请求

与ServletContext相关监听器

全局对象:application范围对象
  • 单个Web站点的资源都共享一个javax.servlet.ServletContext类的实体。通过该对象可以存取应用程序的全局对象以及初始化阶段的变量
  • 全局对象即为application范围对象,其生命周期从容器启动至容器关闭。初始阶段的变量是指在web.xml中,由元素设定的变量,该变量的范围是application范围
ServletContextListener接口
  • 实现了该接口的程序,当JavaWeb应用程序启动时,会自动开始监听工作
  • 首先调用contextInitialized()方法接收对应的ServletContextEvent事件
  • 当应用从容器中移除时,会自动调用contextDestroyed()方法
  • 以上两个方法都会接收到ServletContextEvent事件对象,该对象可以调用getServletContext()方法取得ServletContext对象(全局对象)

创建一个监听ServletContext创建和属性改变的监听器,步骤:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package listener;

import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class CSServletContextListener
 *
 */
@WebListener
public class CSServletContextListener implements ServletContextListener {

    /**
     * Default constructor. 
     */
    public CSServletContextListener() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("CSServletContext销毁");
    	sce.getServletContext().removeAttribute("count");
    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("CSServletContext启动");
    	ServletContext context=sce.getServletContext();
    	context.setAttribute("count", 0);
    	context.setAttribute("count", 5);//这一次相当于将属性修改,会调用attributeReplaced方法;
    }
	
}

package listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class ChangeAttributeListener
 *
 */
@WebListener
public class ChangeAttributeListener implements ServletContextAttributeListener {

    /**
     * Default constructor. 
     */
    public ChangeAttributeListener() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see ServletContextAttributeListener#attributeAdded(ServletContextAttributeEvent)
     */
    public void attributeAdded(ServletContextAttributeEvent scae)  { 
         // TODO Auto-generated method stub
    	System.out.println("ServletContext新建属性: "+scae.getName()+"-----"+scae.getValue());
    }

	/**
     * @see ServletContextAttributeListener#attributeRemoved(ServletContextAttributeEvent)
     */
    public void attributeRemoved(ServletContextAttributeEvent scae)  { 
         // TODO Auto-generated method stub
    	System.out.println("ServletContext移除属性: "+scae.getName()+"-----"+scae.getValue());
    }

	/**
     * @see ServletContextAttributeListener#attributeReplaced(ServletContextAttributeEvent)
     */
    public void attributeReplaced(ServletContextAttributeEvent scae)  { 
         // TODO Auto-generated method stub
    	System.out.println("ServletContext修改前的旧的属性: "+scae.getName()+"-----"+scae.getValue());
    	System.out.println("ServletContext修改后新的属性: "+scae.getServletContext().getAttribute(scae.getName()));
    }
	
}

package servlet优快云;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Servlet;
import javax.servlet.ServletContext;
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 ServletForContext
 */
@WebServlet("/ServletForContext")
public class ServletForContext extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ServletForContext() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		1、设置请求编码方法
		request.setCharacterEncoding("utf-8");
		//2、设置响应编码方式
		response.setContentType("text/html;charset=utf-8");
//		3、获取请求信息getParameter getAttribute
//		4、处理请求(例如查询数据库)
//		5、处理响应结果
//		每访问一次、,count+1
		PrintWriter writer=response.getWriter();
		ServletContext context=getServletContext();
		int count=(int)context.getAttribute("count");
		count++;
		System.out.println(count);
		
		writer.write("当前页面的访问量"+count);
		context.setAttribute("count", count);//设置属性为变化后的count值
		
		
	}

	/**
	 * @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);
	}

}

通过上述代码,可以实现访问站点的次数的统计工作,当通过Chrome打开网页时,如果为24,此时再通过Firefox打开次网页,访问量会变为25,原因就是ServletContext的作用范围是整个站点。
在这里插入图片描述

与httpSession相关监听器

  • HttpSessionListener监听Session对象的创建与销毁,当有Session对象产生或销毁时,会自动调用sessionCreated()或sessionDestroyed()两个方法
  • HttpSessionListener接口与HttpSessionActivationListener接口都使用HttpSessionEvent事件对象
  • HttpSessionEvent类主要的方法:
    getSession()

HttpSessionActivationListener接口

  • 该接口主要用于:同一个Session转移到不同JVM的情形(如:负载均衡,这些JVM可以在同一台机器或分散在网络中的多台机器)
  • 当Session被储存起来,并且等待转移至另一个JVM,这段时间称为失效状态(Passivate),若Session中的属性对象实现HttpSessionActivationListener接口时,Container会自动调用sessionWillPassivate()方法通知该对象的Session已变成失效状态
  • 当Session被转移至其他JVM之后,它又成为有效状态(Activate),此时Container会自动调用sessionDidActivate()方法通知该对象的Session已变成有效状态
接口方法列表

在这里插入图片描述
HttpSessionAttributeListener

  • HttpSessionAttributeListener会监听Session属性的变化,功能与ServletContextAttributeListener接口类似,包含三个方法
    attributeAdded()
    attributeReplaced()
    attributeRemove()

HttpSessionBindingEvent事件

  • HttpSessionBindingEvent事件主要有三个方法
    getName()
    getSession()
    getValue()

HttpSessionBindingListener

  • 实现HttpSessionBindingListener接口的对象加入Session范围或从Session范围中移除时,容器会分别自动调用下面两个方法:
    valueBound(HttpSessionBindingEvent e)
    valueUnbound(HttpSessionBindingEvent e)

  • HttpSessionBindingListener接口是唯一不需要在web.xml中设定的Listener

  • HttpSessionAttributeListener使用的事件与HttpSessionBindingListener使用的事件相同: HttpSessionBindingEvent

  • HttpSessionAttributeListener与HttpSessionBindingListener的不同在于:
    前者监听Web站点所有Session范围的变化
    后者只监听Session范围内实现了HttpSessionBindingListener接口的对象移入移出

在这里插入图片描述

package listener;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * Application Lifecycle Listener implementation class SessionListener
 *
 */
@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {

    /**
     * Default constructor. 
     */
    public SessionListener() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see HttpSessionListener#sessionCreated(HttpSessionEvent)
     */
    public void sessionCreated(HttpSessionEvent se)  { 
         // TODO Auto-generated method stub
    	System.out.println("Session创建");
    	
    	ServletContext context=se.getSession().getServletContext();
    	int count=(int)context.getAttribute("userCount");
    	count++;
    	context.setAttribute("userCount", count);
    }

	/**
     * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)
     */
    public void sessionDestroyed(HttpSessionEvent se)  { 
         // TODO Auto-generated method stub
    	System.out.println("Session销毁");
    	
    	ServletContext context=se.getSession().getServletContext();
    	int count=(int)context.getAttribute("userCount");
    	count--;
    	context.setAttribute("userCount", count);
    }

	/**
     * @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
     */
    public void attributeAdded(HttpSessionBindingEvent se)  { 
         // TODO Auto-generated method stub
    	System.out.println("aaa:"+se.getSession());
    	System.out.println("Session添加属性: "+se.getName()+se.getValue());
    }

	/**
     * @see HttpSessionAttributeListener#attributeRemoved(HttpSessionBindingEvent)
     */
    public void attributeRemoved(HttpSessionBindingEvent se)  { 
         // TODO Auto-generated method stub
    	System.out.println("Session移除属性: "+se.getName()+se.getValue());

    }

	/**
     * @see HttpSessionAttributeListener#attributeReplaced(HttpSessionBindingEvent)
     */
    public void attributeReplaced(HttpSessionBindingEvent se)  { 
         // TODO Auto-generated method stub
    	System.out.println("Session修改的旧的属性: "+se.getName()+se.getValue());
    	System.out.println("Session修改的新的属性: "+se.getSession().getAttribute(se.getName()));

    }
	
}

package servlet优快云;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.websocket.Session;

/**
 * Servlet implementation class ServletSession
 */
@WebServlet("/ServletSession")
public class ServletSession extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ServletSession() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		1、设置请求编码方法
		request.setCharacterEncoding("utf-8");
		//2、设置响应编码方式
		response.setContentType("text/html;charset=utf-8");
		
		HttpSession session=request.getSession();
		PrintWriter writer=response.getWriter();
		ServletContext context=getServletContext();
		int count=(int)context.getAttribute("userCount");
		count++;
		System.out.println(count);
		
		session.setAttribute("name", "tom");
		session.setAttribute("name", "huayu");
		session.setAttribute("name", "jerry");
		
		writer.write("当前页面的访问量"+count);
		context.setAttribute("count", count);//设置属性为变化后的count值
		
		
	 }

	/**
	 * @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);
	}

}

package listener;

import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class CSServletContextListener
 *
 */
@WebListener
public class CSServletContextListener implements ServletContextListener {

    /**
     * Default constructor. 
     */
    public CSServletContextListener() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("CSServletContext销毁");
    	sce.getServletContext().removeAttribute("count");
    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("CSServletContext启动");
    	ServletContext context=sce.getServletContext();
//    	String count=context.getInitParameter("count");
//    	context.setAttribute("count", Integer.parseInt("count"));
    	context.setAttribute("count", 0);
    	context.setAttribute("count", 5);//这一次相当于将属性修改,会调用attributeReplaced方法;
    	context.setAttribute("userCount", 0);//这一次相当于将属性修改,会调用attributeReplaced方法;
    }
	
}

在这里插入图片描述

在这里插入图片描述
如果通过chrome打开则会再次创建一个新的session

与ServletRequest相关监听器

ServletRequestListener接口

  • 当有请求产生或销毁,会自动调用该接口实现的requestInitialized()或requestDestroyed()方法
  • 该接口使用ServletRequestEvent事件

在这里插入图片描述

  • ServletRequestEvent的主要方法:
    getServletContext()
    getServletRequest()

ServletRequestAttributeListener

  • 该接口监听Request范围的变化,有三个主要方法:
    attributeAdded()
    attributeReplaced()
    attributeRemoved()
  • 使用ServletRequestAttributeEvent事件

在这里插入图片描述

  • ServletRequestAttributeEvent主要方法
    getName()
    getValue()

监听器的应用

  • ServletContext范围的监听器可以进行一些初始化的动作,如:当Web应用启动的时候进行全局配置
  • Session范围的监听器对一个会话过程(与客户端关联)中所产生的事件进行响应,可以对客户端信息的变化进行跟踪
  • Request范围的监听器可以监听用户的每次请求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值