我们可以用ServletConfig来获取web.xml中的参数值供特定的servlet用,也可以用ServletContext来调用参数供整个webapp里的对象用,但是ServletContext只能获取string类型的参数,如果我们需要在整个工程运行之前从上下文中获取一个参数并用这个参数初始化一个类的对象,这时就需要ServletContextListener

ServletContextListener类的主要作用:
1.上下文初始化时得到通知:
  • * 从ServletContext中得到上下文的初始化参数
  • * 用这个参数创建一个对象
  • * 把对象储存为ServletContext的一个属性,让webapp中的各个部分都能访问
2.上下文撤销时得到通知
  • * 销毁对象
在这个例子中,需要三个类以及一个配置文件:
  • * MyServletContextListener:监听类
  • * MyServlet:Servlet类
  • * City:城市类
  • * web.xml:配置文件

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener{
  public void contextDestroyed(ServletContextEvent arg0) {
  }
  public void contextInitialized(ServletContextEvent event) {
    ServletContext sc = event.getServletContext();//由事件得到servletcontext
    String name = sc.getInitParameter("cityname");//通过参数获取ServletContext的value
    City city = new City(name);
    sc.setAttribute("city", city);//保存成ServletContext的属性
  }

}

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;

public class MyServlet extends HttpServlet{
  public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException{
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("email is :"+getServletConfig().getInitParameter("email"));//获取servleconfig的value
    City city = (City) getServletContext().getAttribute("city");//获取ServletContext的value
    out.println("<br>city'name is :"+city.getName());
  }
}

public class City {
  private String name = "";
  public City(String name){
    this.name = name;
  }
  public String getName(){
    return this.name;
  }

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
        <servlet>
          <servlet-name>select</servlet-name>
          <servlet-class>com.zyun.MyServlet</servlet-class>
          <init-param>
            <param-name>email</param-name>
            <param-value>bitzyun@china.com</param-value>
          </init-param>
        </servlet>
        <servlet-mapping>
          <servlet-name>select</servlet-name>
          <url-pattern>/select.do</url-pattern>
        </servlet-mapping>
        <context-param>
          <param-name>cityname</param-name>
          <param-value>Beijing</param-value>
        </context-param>
        <listener>
          <listener-class>
            com.zyun.MyServletContextListener
          </listener-class>
        </listener>
</web-app>

让我们回顾一下整个调用的过程:
1.容器读这个应用的部署文件,包括<listener>和<context-param>元素
2.容器为这个应用创建一个新的ServletContext,应用的所有部分都会共享这个上下文
3.容器为每个上下文初始化参数创建一个string名/值对
4.容器将名/值参数的引用交给ServletContext
5.容器创建MyServletContextListener类的一个新实例
6.容器调用监听者的contextInitialized(),传入新的ServletContextEvent。这个事件对象有一个ServletContext的引用,所以时间处理代码可以从事件得到上下文,并从上下文得到上下文的初始化参数
7.监听者向ServletContextEvent要ServletContext的一个引用
8.监听者向ServletContext要上下文参数“cityname
9.监听者使用初始化参数来构造一个新的City对象
10.监听者把City对象设置为ServletContext的一个属性("city",city);
11.容器建立一个新的servlet(也就是说,利用初始化参数建立一个新的ServletConfig,为这个ServletConfig提供ServletContext的一个引用,然后调用servlet的init()方法)
12.servlet得到一个请求,向ServletContext请求属性“city”
13.servlet在City上调用getName(),并将结果打印到HttpResponse