一个监听类,不是一个servlet或JSP,它能监听ServletContext一生中的两个关键事件:初始化(创建)和撤销。这个类实现了javax.servlet.ServletContextListener
这个监听类的功能:
1.上下文初始化时得到通知(应用得到部署)。
a.从ServletContext得到上下文初始化参数。
b.使用初始化参数查找名建立一个数据库连接。
c.把数据库连接存储为一个属性,使得Web应用的各个部分都能访问。
2.上下问撤销时得到通知(应用取消部署或结束)
a.关闭数据库连接。
1.ServletContextListener
MyServletContextListener.java
这个类实现了ServletContextListener,它得到上下文初始化参数,创建Dog,并把Dog设置为一个上下文属性。
package com.example;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//实现javax.servlet.ServletContextListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//由事件得到ServletContext
//监听者对象向ServletContextEvent对象请求应用ServletContext对象的一个引用
ServletContext sc = sce.getServletContext();
//使用上下文得到初始化参数
String dogBreed = sc.getInitParameter("breed");
//建立一个新Dog
Dog d = new Dog(dogBreed);
//使用上下文来设置属性(名/对象对),这个属性就是Dog。现在应用的其他部分就能得到属性(Dog)的值了...
sc.setAttribute("dog", d);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
2.属性类
Dog.java
Dog类只是一个普通的Java类。它的任务是作为一个属性值,由ServletContextListener实例化,并设置在ServletContext中,以便servlet获取。
package com.example;
public class Dog {
private String breed;
public Dog(String breed){
this.breed = breed;
}
public String getBreed(){
return breed;
}
}
3.Servlet
ListenerTester.java
这个类扩展了HttpServlet。它的任务是验证监听者的工作,为此这个Servlet会从上下文得到Dog属性,调用Dog的getBreed(),把结果打印到响应。
这里写代码片
```package com.example;
import java.io.IOException;
import java.io.PrintWriter;
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 ListenerTester
*/
@WebServlet("/ListenerTester")
public class ListenerTester extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ListenerTester() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("test context attributes set by listener<br>");
out.println("<br>");
//现在从ServletContext得到Dog。如果监听者正常,第一次调用服务方法之前,Dog就已经放在上下文中了。
Dog dog = (Dog)getServletContext().getAttribute("dog");
//如果有问题,肯定是在这里出现...倘若调用了getBreed(),但是没有Dog,就会得到一个的NullPointerException
out.println("Dog's breed is:"+dog.getBreed());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
4.web.xml
<div class="se-preview-section-delimiter"></div>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4">
<servlet>
<servlet-name>ListenerTester</servlet-name>
<servlet-class>com.example.ListenerTester</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListenerTester</servlet-name>
<url-pattern>/ListenTest.do</url-pattern>
</servlet-mapping>
<!-- 监听者需要这个参数来构造Dog -->
<context-param>
<param-name>breed</param-name>
<param-value>Great Dane</param-value>
</context-param>
<!-- 把这个类注册为监听者。
<listener>元素不放在<servlet>元素中。
因为上下文监听者对应一个ServletContext事件 -->
<listener>
<listener-class>com.example.MyServletContextListener</listener-class>
</listener>
</web-app>
上下文监听的工作步骤原理:
1.容器读这个应用的部署文件,包括和元素。
2.容器为这个应用创建一个新的ServletContext,应用的所有部分都会共享这个上下文。
3.容器为每个上下文初始化参数创建一个String名/值对。
4.容器将名/值参数的引用交给ServletContext。
5.容器创建MyServletContextListener类的一个新实例。
6.容器调用监听者的contextInitialized()方法,传入新的ServletContextEvent。这个事件对象有一个ServletContext引用,所以事件处理代码可以从事件得到上下文,并从上下文得到上下文初始化参数。
7.监听者向ServletContextEvent要ServletContext的一个引用。
监听者—-getServletContext()—>ServletContextEvent.
8.监听者向ServletContext要上下文初始化参数“breed”;
9.监听者使用初始化参数来构造一个新的Dog对象。
10.监听者把Dog设置为ServletContext中的一个属性。
监听者—-setAttribute(“dog”,d)—->ServletContext
11.容器建立一个新的servlet(也就是说,利用初始化参数建立一个新的ServletConfig,为这个ServletConfig提供ServletContext的一个引用,然后调用servlet的init()方法)。