一个简单的ServletContextListener示例
ServletContext可以初始化String类型的参数。但是,如果你希望应用初始化参数是一个数据库DataSource呢?
上下文参数只能是String。毕竟,你不能把一个Dog对象塞到XML部署描述文件中(事实上,可以用XML表示一个串行化对象,但是在当前的Servlet规范中还没有相关的支持……没准将来会提供)。
如果你真的想让Web应用的所有部分都能访问一个共享的数据连接,该怎么办?
当然可以把这个DataSource查找名放在一个上下文初始化参数里,这也是当前上下文参数最常见的一种用法。
不过,之后谁将这个String参数转换成由Web应用各部分共享的一个具体DataSource引用呢?
不能把这个代码放在servlet中,因为你选择谁作为第一个servlet来查找DataSource并把它存储在一个属性中呢?你真的想保证总是让某个特定的servlet最先运行吗?好好考虑一下。
解决办法:
可以建立一个单独的类,而不是一个servlet或JSP,它能监听ServletContext一生中的两个关键事件:初始化(创建)和撤销。这个类实现了javax.servlet.ServletContextListener。
ServletContextListener类:
package com.moonlit; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener { @Override
public void contextDestroyed(ServletContextEvent event) {
// 初始化数据库连接的代码
// and store it as a context attribute
} @Override
public void contextInitialized(ServletContextEvent event) {
// 关闭数据库连接的代码
}
}
教程:一个简单的ServletContextListener
在这个例子中,我们要把String初始化参数转换成一个真正的对象——一个Dog。监听者的任务是得到有关狗的品种的上下文初始化参数(Beagle、Poodle、等等),然后使用这个String来构造一个Dog对象。监听者再把这个Dog对象存到一个ServletContext属性中,以便servlet获取。
关键是,servlet现在能访问一个共享的数据对象(在这里,就是一个共享的Dog),而且不用读上下文对象。这个共享的对象是一个Dog还是一个数据库连接并没有关系。重点是要使用初始化参数来创建一个对象,让应用的所有部分都能共享这个对象。
这个例子将包括如下过程:
□ 监听者对象向ServletContextEvent对象请求应用ServletContext对象的一个引用。
□ 监听者使用这个ServletContext引用得到"breed"上下文初始化参数,这是一个String,表示狗的品种。
□ 监听者使用这个狗的品种String构造一个Dog对象。
□ 监听者使用ServletContext引用在ServletContext中设置Dog属性。
□ 这个Web应用的测试servlet从ServletContext得到Dog对象,并调用这个Dog的getBreed()方法。
建立和使用一个上下文监听者
要建立和使用一个上下文监听者,我们需要在web.xml中部署描述文件,在web.xml中添加如下内容:
<listener>
<listener-class>
com.moonlit.MyServletContextListener
</listener-class>
</listener>
除了设置ServletContextListener,我们还要设置ServletContext的初始化参数,以及测试的servlet的相关的参数。
完整的web.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>DogListenerExample</display-name> <servlet>
<servlet-name>ListenerTester</servlet-name>
<servlet-class>com.moonlit.ListenerTester</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListenerTester</servlet-name>
<url-pattern>/ListenerTester.do</url-pattern>
</servlet-mapping> <context-param>
<param-name>breed</param-name>
<param-value>Great Dane</param-value>
</context-param> <listener>
<listener-class>
com.moonlit.MyServletContextListener
</listener-class>
</listener> </web-app>
MyServletContextListener是监听者类。这个类实现了ServletContextListener,它得到上下文初始化参数,创建Dog,并把Dog作为一个上下文属性。
MyServlerContextListener.java:
package com.moonlit; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener { @Override
public void contextInitialized(ServletContextEvent event) {
ServletContext sc = event.getServletContext();
String dogBreed = sc.getInitParameter("breed");
Dog d = new Dog(dogBreed);
sc.setAttribute("dog", d);
} @Override
public void contextDestroyed(ServletContextEvent event) {
// do nothing here
}
}
我们需要建立一个属性类Dog。DOg只是一个普通的Java类,它的任务是作为一个属性值,由ServletContextListener实例化,并设置在ServletContext中,一遍servlet获取。
Dog.java:
package com.moonlit;
public class Dog {
    private String breed;
    public Dog(String breed) {
        this.breed = breed;
    }
    public String getBreed() {
        return breed;
    }
}
ListenerTest类是一个Servlet类,它的任务是验证监听者的工作。为此这个Servlet会从上下文得到Dog属性,调用Dog的getBreed(),把结果打印到响应(使我们能在浏览器中看到)。
ListenerTester.java:
package com.moonlit; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial")
public class ListenerTester extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("test context attributes set by listener<br>");
out.println("<br>");
Dog dog = (Dog) getServletContext().getAttribute("dog");
out.println("Dog's breed is : " + dog == null ? "no " : dog.getBreed());
}
}
效果如下:

一个简单的ServletContextListener示例的更多相关文章
- [MySQL5.6] 一个简单的optimizer_trace示例
		
[MySQL5.6] 一个简单的optimizer_trace示例 前面已经介绍了如何使用和配置MySQL5.6中optimizer_trace(点击博客),本篇我们以一个相对简单的例子来跟踪op ...
 - 一个简单的CSS示例
		
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 & ...
 - IDDD 实现领域驱动设计-一个简单的 CQRS 示例
		
上一篇:<IDDD 实现领域驱动设计-CQRS(命令查询职责分离)和 EDA(事件驱动架构)> 学习架构知识,需要有一些功底和经验,要不然你会和我一样吃力,CQRS.EDA.ES.Saga ...
 - (转)Web Service入门简介(一个简单的WebService示例)
		
Web Service入门简介 一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从I ...
 - Ajax得知(两)—— 一个简单的Ajax示例
		
通过部分博客认识Ajax之后,我们通过一个简单的实例来消化消化理论知识,一睹Ajax的庐山真面目. 1.实例功能: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...
 - Web Service入门简介(一个简单的WebService示例)
		
Web Service入门简介 一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从I ...
 - 从一个简单的 JPA 示例开始
		
本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示例:接着重构该示例,并引入 Sp ...
 - 一个简单的MapReduce示例(多个MapReduce任务处理)
		
一.需求 有一个列表,只有两列:id.pro,记录了id与pro的对应关系,但是在同一个id下,pro有可能是重复的. 现在需要写一个程序,统计一下每个id下有多少个不重复的pro. 为了写一个完整的 ...
 - 使用Unicode写文本文件:一个简单类的示例
		
参考了http://forums.codeguru.com/showthread.php?457106-Unicode-text-file示例. class WOFSTREAM : public st ...
 
随机推荐
- .NET框架- in ,out, ref , paras使用的代码总结  C#中in,out,ref的作用  C#需知--长度可变参数--Params  C#中的 具名参数 和 可选参数  DEMO
			
C#.net 提供的4个关键字,in,out,ref,paras开发中会经常用到,那么它们如何使用呢? 又有什么区别? 1 in in只用在委托和接口中: 例子: 1 2 3 4 5 6 7 8 9 ...
 - AutoFac文档3(转载)
			
目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 服务类型,名称和键 同 ...
 - Hadoop-2.2.0中文文档—— Shell命令
			
FS Shell 调用文件系统(FS)Shell命令应使用 bin/hadoop fs <args>的形式. 全部的的FS shell命令使用URI路径作为參数.URI格式是scheme: ...
 - atitit. java跟php的比较..为什么大企业喜欢java 而不是php
			
atitit. java跟php的比较..为什么大企业喜欢java 而不是php 1. 主要原因::php是"低技术.低价格.低素质人员使用"的三低武器 1 2. 三低武器的特点( ...
 - Atitit. Dwr 抛出异常error解决方案
			
Atitit. Dwr 抛出异常error解决方案 1. Dwr3的处理机制..setErrorHandler 1 2. remote Mteh try catch 1 3. 林吧,子好java 处 ...
 - 最新的Zynq资料整理
			
1.Zynq修炼秘籍 基于ZYNQ的FPGA基础入门 基于ZYNQ的Soc入门基础 基于ZYNQ的裸机应用开发 基于ZYNQ硬件的LINUX开发 基于ZYNQ的HLS图像算法设计 基于ZYNQ的图像处 ...
 - 解决Cocos2d-x3.0、3.1 "_opendir$INODE64"symbol(s) not found错误
			
升级系统和XCode后.在IOS8上编译之前的项目会报例如以下错误: Undefined symbols for architecture x86_64: "_opendir$INODE64 ...
 - libxml2实例
			
// libxmlTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdio.h> #includ ...
 - Codeforces Round #235 (Div. 2)   C. Team
			
C. Team time limit per test 1 second memory limit per test 256 megabytes input standard input output ...
 - windows phone 切换多语言时,商店标题显示错误的问题
			
前段时间,用业余时间写了一款 wp8 app(“超级滤镜”商店,中文地址:英文地址),在多语言的时候,给 app title 和 app tile title 进行多语言时(参考 MSDN),中文商店 ...