【代碼審計】Java Web 核心技術(shù)-Servlet

0x00 前言

Servlet 是 Java Web 容器中運行的小程序谬哀,Servlet 原則上可以通過任何客戶端-服務端協(xié)議進行通信封字,但它們常與 HTTP 一起使用辛藻,因此 Servlet 通常作為 “HTTP Servlet”的簡寫。

Servlet 是 Java EE 的核心牙勘,也是所有 MVC 框架實現(xiàn)的根本职恳。

0x01 Servlet 的配置

版本不同,Servlet 的配置不同方面,Servlet 3.0 之前的版本都是在 web.xml 中配置的放钦,在 3.0 之后的版本中則使用更為方便的注解方法來配置。

此外不同版本的 Servlet 所需要的 Java/JDK 版本也不同恭金,具體如下圖所示操禀。

image

1、基于 web.xml 的配置

以下是一個基于 web.xml 的 Servlet 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
         version="2.5">
  
  <display-name>manage</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
    <description></description>
    <display-name>user</display-name>
    <servlet-name>user</servlet-name>
    <servlet-class>com.sec.servlet.UserServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>user</servlet-name>
    <url-pattern>/user</url-pattern>
  </servlet-mapping>
  </web-app>

在 web.xml 中横腿,Servlet 的配置在 Servlet 標簽中颓屑,Servlet 標簽由 Servlet 和 Servlet-mapping 標簽組成,兩者通過標簽中相同的 Servlet-name 實現(xiàn)關(guān)聯(lián)耿焊,上述配置文件中的標簽含義如下:

<servlet>               聲明 Servlet 配置入口
<description>       聲明 Servlet 描述信息
<display-name>  定義 Web 應用的名稱
<servlet-name>  聲明 Servlet 名稱以便在后面的映射時使用
<servlet-class> 指定當前 Servlet 對應的類的路徑
<servlet-mapping>   注冊組件訪問配置的路徑入口
<servlet-name>  指定上文配置的 Servlet 名稱
<url-pattern>       指定配置這個組件的訪問路徑

2揪惦、基于注解方式

Servlet 3.0 以上的版本中,開發(fā)者無須在 web.xml 里配置 Servlet罗侯,只需要添加 @WebServlet 注解即可修改 Servlet 的屬性器腋,如下代碼所示。

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 基于注解開發(fā)Servlet
 */
@WebServlet(urlPatterns = "/ann.do")
public class AnnotationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN'>");
        out.println("<HTML>");
        out.println("<HEAD><TITLE> ITBZ </TITLE></HEAD>");
        out.println("<BODY>");
        out.println("Annotation Servlet!");
        out.println("</BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }
}

注解參數(shù)

image

通過圖中的「等價于 web.xml 的標簽」一欄可以看出,web.xml 可以配置的 Servlet 屬性都可以通過 @WebServlet 的方式進行配置纫塌。

0x02 Servlet 的訪問流程

以上文中的 web.xml 配置文件為例诊县,其訪問流程如下所示。

image

首先用戶在瀏覽器里輸入URL措左,然后瀏覽器發(fā)起請求依痊,服務器通過 servlet-mapping 標簽找到文件名為 user 的 url-pattern,通過其對應的 servlet-name 尋找 servlet 標簽中 servlet-name 相同的 servlet怎披,再獲取其 servlet 標簽里的 servlet-class 參數(shù)胸嘁,最后得到具體的 class 文件路徑,從而執(zhí)行相關(guān)文件凉逛。

0x03 Servlet 的接口方法

1缴渊、init() 接口

在 Servlet 實例化后,Servlet 容器會調(diào)用 init() 方法來初始化該對象鱼炒,主要是為了讓 Servlet 對象在處理客戶請求前可以完成一些初始化的工作,例如建立數(shù)據(jù)庫連接蝌借,獲取配置信息等昔瞧。

對于每一個 Servlet 實例,init() 方法只能被調(diào)用一次菩佑。

init() 方法的定義如下:

public void init() throws ServletException{
    // 開發(fā)者自定義代碼
}

2自晰、service() 接口

service() 方法是執(zhí)行實際任務的主要方法,Servlet 容器調(diào)用 service() 方法來處理來自客戶端(瀏覽器)的請求稍坯,并將格式化的響應寫回客戶端酬荞,每次服務器接收到一個 Servlet 請求時,服務器都會產(chǎn)生一個新的線程并調(diào)用服務瞧哟。

值得注意的是混巧,在 service() 方法被容器調(diào)用之前,必須確保 init() 方法正確完成勤揩。

service() 方法的定義如下:

public void service (ServletRequest request,ServletResponse response) throws ServletException,IOException{
     // 開發(fā)者自定義代碼
}

3咧党、doGet() / doPost() 等接口

doGet() 等方法需要根據(jù) HTTP 的不同請求調(diào)用不同的方法,如果 HTTP 得到一個來自 URL 的 GET 請求陨亡,就會調(diào)用 doGet() 方法傍衡,同樣的,如果得到 POST 請求负蠕,就會調(diào)用 doPost() 方法蛙埂。

這類方法的定義如下:

public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
    // 開發(fā)者自定義代碼
    // 如果是 POST 請求,則調(diào)用 public void doPost 方法
}

4遮糖、destroy() 接口

當容器檢測到一個 Servlet 對象應該從服務中被移除的時候绣的,容器會調(diào)用該對象的 destroy() 方法,以便讓 Servlet 對象可以釋放它所使用的資源,保存數(shù)據(jù)到持久存儲設備中被辑,例如將內(nèi)存中的數(shù)據(jù)保存到數(shù)據(jù)庫中燎悍,關(guān)閉數(shù)據(jù)庫的連接等。

destroy() 方法與 init() 方法相同盼理,都只會調(diào)用一次谈山。

destroy() 方法定義如下:

public void destroy(){
    // 開發(fā)者自定義代碼
}

5、getServletConfig() 接口

該方法返回容器調(diào)用 init() 方法時傳遞給 Servlet 對象的 ServletConfig 對象宏怔,ServletConfig 對象包含了 Servlet 的初始化參數(shù)奏路。

6、getServletInfo() 接口

該方法返回一個 String 類型的字符串臊诊,其中包括了關(guān)于 Servlet 的信息鸽粉,例如,作者抓艳、版本和版權(quán)等触机。

0x04 Servlet 的生命周期

Servlet 生命周期指的是 Servlet 從創(chuàng)建直到銷毀的整個過程。

在一個生命周期中玷或,Servlet 經(jīng)歷了被加載儡首、初始化、接收請求偏友、響應請求以及提供服務的過程蔬胯,具體如下圖所示。

image

參考鏈接:

https://tomcat.apache.org/whichversion.html

https://blog.csdn.net/bieleyang/article/details/76696131

https://blog.csdn.net/qq_45017999/article/details/106696148

原文鏈接:

https://www.teamssix.com/211115-165745.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末位他,一起剝皮案震驚了整個濱河市氛濒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鹅髓,老刑警劉巖舞竿,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異窿冯,居然都是意外死亡炬灭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門靡菇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來重归,“玉大人,你說我怎么就攤上這事厦凤”撬保” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵较鼓,是天一觀的道長椎木。 經(jīng)常有香客問我违柏,道長,這世上最難降的妖魔是什么香椎? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任漱竖,我火速辦了婚禮,結(jié)果婚禮上畜伐,老公的妹妹穿的比我還像新娘馍惹。我一直安慰自己,他們只是感情好玛界,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布万矾。 她就那樣靜靜地躺著,像睡著了一般慎框。 火紅的嫁衣襯著肌膚如雪良狈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天笨枯,我揣著相機與錄音薪丁,去河邊找鬼。 笑死馅精,一個胖子當著我的面吹牛窥突,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硫嘶,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼梧税!你這毒婦竟也來了沦疾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤第队,失蹤者是張志新(化名)和其女友劉穎哮塞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凳谦,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡忆畅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了尸执。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片家凯。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖如失,靈堂內(nèi)的尸體忽然破棺而出绊诲,到底是詐尸還是另有隱情,我是刑警寧澤褪贵,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布掂之,位于F島的核電站抗俄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏世舰。R本人自食惡果不足惜动雹,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跟压。 院中可真熱鬧胰蝠,春花似錦、人聲如沸裆馒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喷好。三九已至翔横,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間梗搅,已是汗流浹背禾唁。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留无切,地道東北人荡短。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像哆键,于是被迫代替她去往敵國和親掘托。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容