從零開始學習Java Web(二):初步認識Servlet

    這一章我們不深究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方法什麼時候會調用?HttpServletRequestHttpServletResponse又是怎麼得到的?

首先,當瀏覽器發出一個請求時,服務器就會創建一個新的線程,並初始化一個HttpServletRequest和HttpServletResponse對象,並把請求的信息設置到HttpServletRequest對象中,之後會執行service方法,將兩個對象傳遞到service()方法中。所以,每有一次請求,就會調用一次service方法

destroy()方法就更不用說了,當服務器關閉時,會調用destroy()方法。


這一章我們不再過多的講述HttpServletRequestHttpServletResponse過多的知識點,後面會結合session和cookie再深入討論。


後記:如果本文中有什麼說得不對的地方,歡迎指正交流,將不勝感激~~~


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章