一個簡單的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());
    }
}

效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM