Java EE入门教程系列第四章Servlet(五)——侦听器

4.5 侦听器

4.5.1 侦听器的工作原理

侦听器用于监听web容器中的事件,并触发响应的事件。从侦听对象的角度划分,用于侦听的事件源分别为Servlet、HttpSession、ServletRequest这三个域对象。

侦听器是基于观察者模式设计的,能够方便地从一个纵向维度控制程序和数据。目前,Servlet中提供了3类共计8种事件的观察者接口及对应的6种事件:

1、源于ServletContext域对象的侦听:主要是对web应用中上下文事件的侦听,以及基于上下文属性编辑动作的侦听。

1)ServletContextEvent接口表示上下文的事件,ServletContextListener接口用于侦听这些事件.

ServletContextListener接口的主要方法如下:

void contextInitialized(ServletContextEvent se):通知正在接收的对象,应用程序已经被加载及初始化

void contextDestroyed(ServletContextEvent se):通知正在接收的对象,应用程序已经被销毁

ServletContextEvent的主要方法如下:

ServletContext.getServletContext():取得当前的ServletContext对象

2)ServletContextAttributeEvent接口表示上下文中的属性事件,对应的ServletContextAttributeListener接口表示对这些属性的 侦听。

ServletContextAttributeListener接口的主要方法如下:

void attributeAdded(ServletContextAttributeEvent se):若有对象加入application的范围,通知正在收听的对象

void attributeRemoved(ServletContextAttributeEvent se):若有对象从application的范围移除,通知正在收听的对象

void attributeReplaced(ServletContextAttributeEvent se):若在application的范围有对象取代另一个对象时,通知正在收听的对象

ServletContextAttributeEvent接口的主要方法如下:

getName():返回属性名称

getValue():返回属性的值

2、源于HttpSession域对象的侦听,主要是针对session相关行为的侦听。

1)接口用于侦听session的生命周期,HttpSessionEvent接口代表session声明周期的事件。

HttpSessionListener接口的主要方法如下:

sessionCreated(HttpSessionEvent se):当一个session被创建时,该方法被调用

sessionDestroyed(HttpSessionEvent se):当一个session被销毁时,该方法被调用

2)HttpSessionAttributeListener接口是用来侦听session绑定属性的行为,HttpSessionAttributeBindingEvent接口代表了session中属性绑定行为的事件,另一个接口HttpSessionAttributeBindingListener代表侦听http会话中对象的绑定信息。

HttpSessionAttributeListener接口的主要方法如下:

void attributeAdded(HttpSessionAttributeBindingEvent se):监听http会话中的属性添加功能

void attributeRemoved(HttpSessionAttributeBindingEvent se):监听http会话中的属性移除功能

void attributeReplaced(HttpSessionAttributeBindingEvent se):监听http会话中的属性更改功能

HttpSessionBindingListener接口的主要方法如下:

getSession():获取session对象

getName():返回session增加、删除或替换的属性名称

getValue():返回session增加、删除或替换的属性值

3、源于ServletRequest域对象的侦听,主要用于对有关客户端发起请求的侦听。

1)ServletRequestListener接口用于监听客户端的请求初始化和销毁事件,ServletRequestEvent接口是指客户端发起的请求事件。

ServletRequestListener接口的主要方法如下:

requestInitialized(ServletRequestEvent):通知当前对象请求已经被加载及初始化

requestDestroyed(ServletRequestEvent):通知当前对象,请求已经被小柴胡

ServletRequestEvent的主要方法如下:

getServletRequest():获取ServletRequest对象

getServletContext():获取ServletContext对象

2)ServletRequestAttributeListener接口用于监听web应用属性改变的事件。ServletRequestAttributeEvent接口代表对属性进行编辑的事件。

ServletRequestAttributeListener接口的主要方法如下:

void attributeAdded(ServletRequestAttributeEvent se):向Request对象添加新属性

void attributeRemoved(ServletRequestAttributeEvent se):向Request对象删除属性

void attributeReplaced(ServletRequestAttributeEvent se):替换对象中现有的属性值

ServletRequestAttributeEvent接口的主要方法如下:

getName():返回Request增加、删除或替换的属性名称

getValue():返回Request增加、删除或替换的属性值

4.5.2 创建侦听器

项目右键-new-listener-填写包名和类名,这里填写的分别是cy.listener和Listener

接着选择需要的接口,本例中选择如下几个:

package cy.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

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

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

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    }

	/**
     * @see HttpSessionAttributeListener#attributeAdded(HttpSessionBindingEvent)
     */
    public void attributeAdded(HttpSessionBindingEvent event)  { 
         // TODO Auto-generated method stub
    	//当侦听到一个session的属性发生绑定时,获取它的名称
    	String name=event.getName();
    	System.out.println("新建session属性:"+name+" 值为:"+event.getValue());
    }

	/**
     * @see HttpSessionAttributeListener#attributeRemoved(HttpSessionBindingEvent)
     */
    public void attributeRemoved(HttpSessionBindingEvent event)  { 
         // TODO Auto-generated method stub
    	String name=event.getName();
    	System.out.println("删除session属性:"+name+" 值为:"+event.getValue());
    }

	/**
     * @see HttpSessionAttributeListener#attributeReplaced(HttpSessionBindingEvent)
     */
    public void attributeReplaced(HttpSessionBindingEvent event)  { 
         // TODO Auto-generated method stub
    	//获取修改后的session值
    	HttpSession session=event.getSession();
    	String name=event.getName();
    	Object oldValue=event.getValue();
    	System.out.println("修改session属性:"+name+" 原值为:"+oldValue+" 新值为:"+session.getAttribute(name));
    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    }
	
}

创建好这个文件后,就可以进行测试了,随便找一个之前博客写过的有关session的代码加入此包中

运行session.java


package cy.listener;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
 
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;
 
/**
 * Servlet implementation class SetParam
 */
@WebServlet("/SetParam")
public class Session extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Session() {
        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.setContentType("text/html;charset=UTF-8");
		PrintWriter out=response.getWriter();
		HttpSession session=request.getSession();
		Date crtTime=new Date(session.getCreationTime());//创建对象的时间
		Date lastAccessTime=new Date(session.getLastAccessedTime());//上次访问session的时间
		Integer visitCount=new Integer(0);//统计访问次数
		String visitCountKey=new String("visitCount");
		String userIDKey=new String("userID");
		String userID=new String("ABCD");
		if(session.isNew()) {
			//为空会自动创建一个session对象
			session.setAttribute(userIDKey, userID);
			
		}
		else {
			visitCount=(Integer)session.getAttribute(visitCountKey);
			if(visitCount!=null) {
				visitCount+=1;
			}
			if(session.getAttribute(userIDKey)!=null) {
				userID=(String)session.getAttribute(userIDKey);
			}
		}
		session.setAttribute(visitCountKey, visitCount);
		response.setContentType("text/html;charset=UTF-8");
		try {
			
			out.println("<html");
			out.println("<head>");
			out.println("<title></title>");
			out.println("</head>");
			out.println("<body>");
			out.println("<table border='1' align='center'>");
			out.println("<tr><th>session</th><th>value</th></tr>");
			out.println("<tr><td>id</td><td>"+session.getId()+"</td></tr>");
			out.println("<tr><td>creation time</td><td>"+crtTime+"</td></tr>");
			out.println("<tr><td>last access time</td><td>"+lastAccessTime+"</td></tr>");
			out.println("<tr><td>User ID</td><td>"+userID+"</td></tr>");
			out.println("<tr><td>number of visit</td><td>"+visitCount+"</td></tr>");
			out.println("</body>");
			out.println("</html");
		}finally {
			out.close();
		}
	}
 
	/**
	 * @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);
	}
 
}

注意观察控制台输出,第一次session是新创建的,所以attributeAdded()方法作出处理 

刷新当前页面,访问次数发生改变,所以控制台多了一行信息对修改的属性作出描述

侦听程序是对于一个项目活动的侦听,所以项目中任何有关动作都会触发侦听程序的动作。

18天终于写完了前4章,每天总会遇到一个不好解决的问题导致频繁凌晨才能更博,后面几章更复杂,Hedy冲鸭!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值