[Servlet]事件监听,ServletContext的事件监听

1. 应用程序事件以及事件监听:

    1) 在Web容器中,各个Servlet/JSP都是应用程序,在应用程序生命周期中会发生很多事件,最典型的事件就是生成和销毁;

    2) Web容器为这些应用程序事件提供了监听器,当这些事件发生时监听器会响应并作出相应的处理,处理代码需要用户自己实现,就和Windows的消息响应机制一样;

    3) Web容器主要为HttpServletRequest、HttpSession、ServletContext这三种对象提供了监听器,接下来也主要围绕这三者的监听器展开;


2. ServletContext事件、监听器:

    1) 和环境有关的监听器有两类,一类是ServletContextListener(监听应用程序初始化和销毁事件),另一类是ServletContextAttributeListener(监听ServletContext的属性被添加、删除和替换事件),这里主要介绍ServletContextListener;

    2) ServletContextListener接口原型:

public interface ServletContextListener extends EventListener {
    public void contextInitialized(ServletContextEvent sce);
    public void contextDestroyed(ServletContextEvent sce);
}
         i. 注意!事件的时间点是应用程序初始化“后”(即调用了init(config: ServletConfig)后,但init()还没调用!),和程序在被销毁“前”;

         ii. 可以在contextInitialized中实现应用程序相关资源的准备动作,比如数据库的连接、读取程序的配置信息等,而在contextDestroyed中可以实现应用程序资源的释放动作,如断开数据库连接,还有一些C++本地代码的内存释放等;

    3) ServletContextEvent类只有一个方法,那就是getServletContext方法,获取的还是应用程序ServletConfig中的ServletContext,和Servlet类的getServletContext一模一样;

!!获取ServletContext后就可以进行更多的操作了,如getInitParameter、setAttribute等,特别是getInitParameter来获取初始参数,因此Web应用程序的初始参数也常被成为ServletContext的初始参数;

    4) 实现该接口的类必须用@WebListener进行标注,例如:

@WebListener
public class ContextParameterReader implements ServletContextListener {
	public void contextInitialized(ServletContextEvent sce) {
		ServletContext context = sce.getServletContext();
		String iconPath = context.getInitParameter("ICON_PATH");
		context.setAttribute("ICON_PATH", iconPath);
	}
	public void contextDestroyed(ServletContextEvent sce) {}
}
!!标注@WebListener是给Web容器看的,表明该类是一个Web事件监听器,里面的每一个方法都必须实现!!

!!由于@WebListener标注是无属性的,因此要设置其属性就必须到web.xml中设置,也只有这一种方法来设置应用程序的环境参数:

        a. <context-param>:环境参数标签

        b. 底下的<param-name>和<param-value>来设置参数的名称和值

        c. 例如:

<context-param>
	<param-name>ICON_PATH</param-name>
	<param-value>/icon</param-value>
</context-param>
!!很显然,上面的演示是在从配置中读取程序中要用到的头像的路径;

    5) 由于初始化事件的监听并响应是发生在init(config: ServletConifg)后和init()前,上面演示中context的ICON_PATH对象在init()中就已经存在,此时可以在init()中用该环境属性来初始化自定义HttpServlet类中的一些自定义数据成员了,比如:

@WebServlet("/icon.view")
public class Icon extends HttpServlet {
	private String ICON_PATH;
	@Override
	public void init() throws ServletException {
		ICON_PATH = (String)getServletContext().getAttribute("ICON_PATH");
	}
}


!!!Web应用初始化的标准步骤:

            a. 理应使用context监听器进行初始化,即使用context-param初始化,而不是init-param来初始化,init-param可以应用于一些小的工程,但对于一些大的、复杂的工程应该使用context-param加监听器的方法进行初始化;

!!原则和MFC编程一样,用户应把精力集中在处理事件的逻辑上,而不是专注于事件发生的时间点上;

            b. 步骤总结:context-param中配置环境参数  ->  contextInitialized中读取并设置配置参数  ->  init()中提取环境参数并初始化自定义数据成员;

            c. 使用监听器初始化的好处就是大大简化了@WebServlet标注,只需要写一个url模式即可,不用在写很多默认的config参数,而是直接从context中提取想要的参数即可;


    6) 使用监听器初始化的典型案例——设置HttpSession的Cookie:

         i. 之前讲过要设置HttpSession的Cookie必须要使用web.xml,但是ServletContext有个方法,就是getSessionCookieConfig(),可以获取SessionCookieConfig对象,该对象有一系列方法,如setName等来配置Session的Cookie;

         ii. 但是Session Cookie是在init()之前就已经配置完毕,如果要在init()中修改则这些修改都是无效的,而刚好在init(config: ServletConfig)之后Session Cookie还没配置,因此可以利用ServletContextListener在这个时机点对Session Cookie进行配置:

@WebListener
public class Test implements ServletContextListener {
	public void contextInitialized(ServletContextEvent sce) {
		ServletContext context = sce.getServletContext();
		context.getSessionCookieConfig().setName("my-sessionId");
	}
	public void contextDestroyed(ServletContextEvent sce) {}
}
!这里就将Tomcat默认的JSESSIONID改成了my-sessionId了;


!!在Servlet3.0之前,Web监听器必须在web.xml中声明,否则Web容器无法识别:

<listener>
	<listener-class>com.lirx.TestListener</listener-class>
</listener>
!!标签就是<listener>和<listener-class>;

!!而3.0之后@WebListener标签就取代了web.xml的<listener>标签的功能了;


3. ServletContextAttribute事件、监听器:

    1) 监听器是ServletContextAttributeListener,用于监听并响应ServletContext属性的添加、删除和替换;

    2) 接口原型:

public interface ServletContextAttributeListener extends EventListener {
    public void attributeAdded(ServletContextAttributeEvent scae); 
    public void attributeRemoved(ServletContextAttributeEvent scae);
    public void attributeReplaced(ServletContextAttributeEvent scae);
}

    3) 所有Web监听器要么用@WebListener标注,要么就在web.xml中配置<listener>标签,这个也不例外;

    4) ServletContextAttributeEvent类中只包装了String getName();和Object getValue();两个方法,用来获取被加入、删除或是替换的那个属性的名称和值;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值