這一章我們不深究Servlet是什麼,我們來講講Servlet有什麼。首先先新建一個class,繼承HttpServlet,然後重寫Servlet生命週期的三個重要方法。
package com.hxl.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
首先說一下init(ServletConfig config)方法,該方法在整個servlet生命週期中只會運行一次,所以通常用來做一些變量的初始化工作,那麼,init(ServletConfig)方法到底在什麼時候運行呢?方法包含一個ServletConfig對象,那麼ServletConfig到底是什麼東西呢?
我們不妨看看它有什麼方法:
我們不難發現,它包含的方法很少,從紅色方框中我們很容易就能猜到,第一個是根據參數名拿到參數值,第二個是拿到全部參數名稱,我們來看看第三個,該方法會返回一個ServletContext對象,不仔細看,一眼還以爲它和SercletConfig是同名呢。那麼,ServletConfig和ServletContext的區別是什麼?
首先,它們作用域不同,ServletConfig的作用域是Servlet,ServletContext作用域是整個項目。一個項目可以有多個Servlet,每個Servlet有一個ServletConfig,但是所有的Servlet共享一個ServletContext。
其次,ServletContext有setInitParameter()方法,我們可以在任意能獲取到ServletContext的地方()對其進行設置值,但是ServletConfig沒有,也就是說ServletConfig不能手動設置值,那麼,問題來了,我們怎麼對其設置值?
要回答以上的問題,我們先看看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>testWeb</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<!-- 設置servlet名稱,這個沒要求 -->
<servlet-name>first</servlet-name>
<!-- 這裏是servlet類全路徑(包名.類名) -->
<servlet-class>com.hxl.servlet.FirstServlet</servlet-class>
<!-- 這裏就是初始化ServletConfig的地方 -->
<init-param>
<param-name>name</param-name>
<param-value>hxl</param-value>
</init-param>
<!-- 值如果大於0,則該Servlet跟隨服務器啓動 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!-- 這裏的值和servlet-name的值對應,形成一種映射關係 -->
<servlet-name>first</servlet-name>
<!-- 設置匹配地址 -->
<url-pattern>/first/*</url-pattern>
</servlet-mapping>
<!-- 這裏就是對ServletContext進行初始化 -->
<context-param>
<param-name>name</param-name>
<param-value>root</param-value>
</context-param>
</web-app>
這裏我們先做一個簡單的理解:<servlet>中的<servlet-name>和<servlet-mapping>中的<servlet-name>是對應的,這個名字可以隨意給,<url-pattern>是響應的請求地址。當我們發起一個請求時,服務器會先去尋找匹配的url-pattern,獲取同一個<servlet-mapping>中<servlet-name>的值,再找到<servlet-name>相同的<servlet>中的<servlet-class>,調用該class的service(request,response)方法。
問題1:init(ServletConfig)方法什麼時候執行?
答:當servlet設置<load-on-startup>1</load-on-startup>的時候,服務器啓動該servlet就會跟隨着啓動,就會執行init(ServletConfig)方法。如果不設置<load-on-startup>,那麼則會在第一個客戶端訪問的時候調用init方法
延伸問題:<load-on-startup>標籤裏的數字必須是1麼,可以設置成其他數字麼,如果可以,數字的大小會不會影響servlet初始化的順序?
答:只要是大於0並且在int最大值範圍內的數都可以,數字的大小不影響初始化順序
問題2:怎麼設置ServletConfig和ServletContext的值?
答:ServletConfig:在<servlet>裏的<init-param>標籤裏設置。
ServletContext:在<context-param>裏設置,或者通過getServletContext().setInitParameter()進行設置值。
問題3:ServletConfig和ServletContext有什麼用?
答:存放變量。所有的Servlet都能訪問ServletContext,只能單獨訪問各自的ServletConfig,知道這個就能知道什麼變量該存放到什麼地方。這時候你會想到:我定義一個Constant類,裏面的變量都是public static 修飾的,照樣能實現ServletContext的作用啊......確實,在開發中,這樣也可以
==================分割線=======================
接下來我們看service()方法,我們可以看到兩個變量,分別是HttpServletRequest和HttpServletResponse。那麼,service方法什麼時候會調用?HttpServletRequest和HttpServletResponse又是怎麼得到的?
首先,當瀏覽器發出一個請求時,服務器就會創建一個新的線程,並初始化一個HttpServletRequest和HttpServletResponse對象,並把請求的信息設置到HttpServletRequest對象中,之後會執行service方法,將兩個對象傳遞到service()方法中。所以,每有一次請求,就會調用一次service方法
destroy()方法就更不用說了,當服務器關閉時,會調用destroy()方法。
這一章我們不再過多的講述HttpServletRequest和HttpServletResponse過多的知識點,後面會結合session和cookie再深入討論。
後記:如果本文中有什麼說得不對的地方,歡迎指正交流,將不勝感激~~~