Servlet ServletContextEvent事件

當Web應用程序部署在服務器上時,會通知ServletContextEvent事件。

如果要在部署Web應用程序時執行某些操作,例如創建數據庫連接,創建項目的所有表等,則需要實現ServletContextListener接口並提供其方法的實現。

ServletContextEvent類的構造方法

ServletContextEvent類中只定義了一個構造函數。Web容器在ServletContext實例之後創建ServletContextEvent的實例。

  • ServletContextEvent(ServletContext e)

ServletContextEvent類的方法

ServletContextEvent類中只定義了一個方法:

  • public ServletContext getServletContext() - 返回ServletContext的實例。

ServletContextListener接口的方法

ServletContextListener接口中聲明瞭兩種方法,這些方法必須由servlet程序員實現,以執行一些操作,如創建數據庫連接等。

  • public void contextInitialized(ServletContextEvent e): 當應用程序部署在服務器上時被調用。
  • public void contextDestroyed(ServletContextEvent e): 當應用程序從服務器取消部署時被調用。

ServletContextEvent和ServletContextListener的示例

在這個例子中,從employees表中檢索數據。爲了實現這個服務,我們在監聽器類中創建了連接數據庫對象,並在servlet中使用了連接對象。

首先,在MySQL中創建一個名稱爲:testdb 的數據庫,創建以下表及以數據記錄 -

DROP TABLE IF EXISTS `employees`;
CREATE TABLE `employees` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL DEFAULT '',
  `age` int(3) unsigned NOT NULL DEFAULT '0',
  `address` varchar(254) DEFAULT NULL,
  `salary` float(8,2) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of employees
-- ----------------------------
INSERT INTO `employees` VALUES ('1', '李小春', '23', '海口市人民大道1800號', '8900.00');
INSERT INTO `employees` VALUES ('2', '張輝', '28', '廣州天河區珠村市場', '15800.00');
INSERT INTO `employees` VALUES ('3', '林賢弟', '25', '廣州白雲區龍塘村120號', '18990.00');

打開Eclipse,創建一個動態Web項目:ServletContextEvent,其完整的目錄結構如下 -

Servlet

以下是項目中的幾個主要的文件代碼。

文件:index.html -

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ServletContextListener實例</title>
</head>
<body style="text-algin: center;">
    <a href="getdata">點擊讀取employees表中的數據</a>
</body>
</html>

文件:MyListener.java -

package com.yiibai;

import java.sql.Connection;
import java.sql.DriverManager;

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

/**
 * Application Lifecycle Listener implementation class MyListener
 *
 */
@WebListener
public class MyListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {

        String jdbcDriver = "com.mysql.jdbc.Driver";
        String dbURL = "jdbc:mysql://localhost/testdb";

        // Database credentials
        String dbUser = "root";
        final String passwd = "123456";
        try {
            Class.forName(jdbcDriver);
            Connection con = DriverManager.getConnection(dbURL, dbUser, passwd);
            // storing connection object as an attribute in ServletContext
            ServletContext ctx = event.getServletContext();
            ctx.setAttribute("mycon", con);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("Servlet has contextDestroyed...");
    }

}

文件:FetchData.java -

package com.yiibai;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.servlet.ServletContext;
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 FetchData
 */
public class FetchData extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        try {
            // Retrieving connection object from ServletContext object
            ServletContext ctx = getServletContext();
            Connection con = (Connection) ctx.getAttribute("mycon");
            if(con==null) {
                System.out.println("獲取數據庫連接異常~!");
            }
            // retieving data from emp32 table
            String sql = "SELECT * FROM employees";
            PreparedStatement ps = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);

            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                out.print("<br>" + rs.getString(1) + " " + rs.getString(2));
            }
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        out.close();
    }
}

文件: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>ServletContextEvent</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <listener>
        <listener-class>com.yiibai.MyListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>FetchDataServlet</servlet-name>
        <servlet-class>com.yiibai.FetchData</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FetchDataServlet</servlet-name>
        <url-pattern>/getdata</url-pattern>
    </servlet-mapping>
</web-app>

在編寫上面代碼後,部署此Web應用程序(在項目名稱上點擊右鍵->」Run On Server…」),打開瀏覽器訪問URL: http://localhost:8080/ServletContextEvent/ ,如果沒有錯誤,應該會看到以下結果 -

Servlet

點擊上面鏈接後,從數據庫表中讀取到的數據如下所示 -

Servlet

ServletContextListener創建項目表的示例

在這個例子中,我們創建一個項目所使用的表。因此不需要在數據庫中手動創建所有表。

修改上面MyListener.java中的示例代碼:

package com.yiibai;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

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

/**
 * Application Lifecycle Listener implementation class MyListener
 *
 */
@WebListener
public class MyListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {

        String jdbcDriver = "com.mysql.jdbc.Driver";
        String dbURL = "jdbc:mysql://localhost/testdb";

        // Database credentials
        String dbUser = "root";
        final String passwd = "123456";
        try {
            Class.forName(jdbcDriver);
            Connection con = DriverManager.getConnection(dbURL, dbUser, passwd);
            String query="CREATE TABLE `employees` (" + 
                    "  `id` int(10) unsigned NOT NULL AUTO_INCREMENT," + 
                    "  `name` varchar(64) NOT NULL DEFAULT ''," + 
                    "  `age` int(3) unsigned NOT NULL DEFAULT '0'," + 
                    "  `address` varchar(254) DEFAULT NULL," + 
                    "  `salary` float(8,2) unsigned DEFAULT NULL," + 
                    "  PRIMARY KEY (`id`)" + 
                    ") ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;";  
            PreparedStatement ps=con.prepareStatement(query);  
            ps.executeUpdate();  

            System.out.println(query);  

            // storing connection object as an attribute in ServletContext
            ServletContext ctx = event.getServletContext();
            ctx.setAttribute("mycon", con);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("Servlet has contextDestroyed...");
    }

}

ServletContextListener的其他示例

  • 高性能ServletContextListener的示例