Java后臺開發(fā)——Servlet篇

參考資料

《JSP從零開始》—— 劉鑫
Servlet官方文檔
孤傲蒼狼 博客園

前言

本人菜鳥犬绒,入IT只為當鼓勵師。本編文章對 Servlet 作簡要介紹兑凿,其中包括講解:Servlet是什么凯力、Servlet的功能、Servlet的生命周期礼华、HttpServlet對象咐鹤。

一、Servlet是什么

  • 一門用于開發(fā)動態(tài)web資源的技術圣絮,由sun公司提供祈惶。
  • java類編寫的服務端應用程序
  • Servlet程序是由web服務器(tomcat等)調用的

說簡單點,就是Sun公司開發(fā)出了一套API(java.servlet扮匠、java.sevlet.http等)捧请,你可以用這些api開發(fā)Java程序,用來處理客戶端請求棒搜,并控制輸出的響應(向客戶端瀏覽器輸出的內容)疹蛉。

servlet api

總結起來,你只需要:
① 編寫一個實現(xiàn)了servlet接口的java類力麸;
② 把開發(fā)好的Java類部署到web服務器中可款。

所以,有時我們也稱實現(xiàn)了servlet接口的java程序為Servlet克蚂。

二闺鲸、Servlet的功能

  • 對客戶端發(fā)送的數(shù)據(jù)進行讀取和攔截
    客戶端發(fā)送一個請求會攜帶數(shù)據(jù)(url中的參數(shù),頁面表單提交埃叭,ajax請求)摸恍,當一個Servlet接收到請求,java Servlet中的類可以通過提供的方法獲得這些參數(shù)(request.getParameterName(name)等)赤屋。因此Servlet可以起攔截作用立镶,在請求前先判斷該客戶端能否做出這些請求 壁袄,若能再從服務器得到請求的資源。
    圖例
  • 讀取客戶端的請求的隱含數(shù)據(jù)
    客戶端請求的數(shù)據(jù)可分為:隱含數(shù)據(jù)谜慌,顯式數(shù)據(jù)。
    隱含數(shù)據(jù):不存在于URL中莺奔,而存在于請求的來源欣范,緩存數(shù)據(jù)(cookie)、客戶端類型(在header中)令哟。
    顯式數(shù)據(jù):用戶可見的恼琼,表單數(shù)據(jù)(來自于form)或URL參數(shù)。
    Servlet都可處理屏富。

  • 運行結果或者生成結果
    一個Web應用程序對客戶端發(fā)出的請求做出響應時晴竞,一般有很多中間過程才能得到結果,Servlet就擔起了這個中間角色功能狠半。(后面深入學習會知道噩死,javaweb開發(fā)中的控制層是由Servlet實現(xiàn)的,就是常說的MVC中的C)


    圖例
  • 發(fā)送響應的數(shù)據(jù)
    Servlet對客戶端做出響應并經(jīng)過處理得出結果后神年,會對客戶端發(fā)送響應的數(shù)據(jù)已维,讓客戶端獲取請求的結果數(shù)據(jù)。

三已日、Servlet的生命周期

Servlet的生命周期包含3個階段:

1. 初始化階段

當web服務器收到客戶端對某一url地址的訪問請求時垛耳,若該url配置了對應的Servlet程序,則開始該階段飘千。


檢查請求url是否有對應的Servlet程序
  • web服務器檢查是否已經(jīng)裝載并創(chuàng)建了該Servlet的實例對象堂鲜。如果是,則跳過初始化階段护奈,否則進入下一步缔莲。
  • 裝載(由Servlet容器裝載一個Servlet類,把它裝在到Java內存中)并創(chuàng)建該Servlet的一個實例對象霉旗,與 web.xml 中的配置對應起來酌予。
  • 調用Servlet實例對象的 init() 方法。在整個Servlet生命周期中奖慌,init() 方法只被調用一次抛虫。
    步驟圖示

    首次訪問的兩個注意點

2. 運行階段

該階段實際響應客戶端的請求。

  • Servlet創(chuàng)建 HttpServletRequestHttpServletResponse 對象简僧,前者與HTTP協(xié)議有關建椰,后者與協(xié)議無關。
  • 調用 service(HttpServletRequest request, HttpServletResponse response) 方法岛马,該方法通過request對象獲得請求對象的信息并加以處理棉姐,再由response對象給客戶端做出響應屠列。
每當有請求時,服務端的一系列動作
調用 service() 方法伞矩,可訪問請求和響應對象
運用request對象讀取請求信息笛洛,處理后運用response對象寫入響應信息
service() 方法返回
服務器讀取響應信息
服務器發(fā)出http響應,將數(shù)據(jù)返回到客戶端瀏覽器中

3. 消亡階段

  • web應用程序被停止或重新啟動之前乃坤,Servlet容器將調用 destroy() 方法苛让,對Servlet對象進行銷毀,釋放其所占資源湿诊。在整個Servlet生命周期中狱杰,destory() 方法只被調用一次。

四厅须、創(chuàng)建Servlet的步驟

  1. 引入相應的包仿畸,如:java.servletjava.servlet.http 包,兩個包的區(qū)別是前者與協(xié)議無關朗和,后者與HTTP協(xié)議相關错沽。
  2. 創(chuàng)建一個擴展類,如本例中的 HelloServlet眶拉,并繼承 HttpServlet 類甥捺。(一般的,HttpServlet 類封裝了很多基于HTTP協(xié)議下的Servlet功能镀层,基本夠用镰禾,若自己想開發(fā)一個協(xié)議可繼承 GenericServlet 類)
  3. override doGet()doPost() 方法,doGet() 響應get請求唱逢,doPost() 響應Post請求吴侦。或者可以override service()方法坞古,對所有請求統(tǒng)一處理备韧。欲詳細了解 service()doGet()痪枫,doPost()等方法织堂,請看:五、關于 Servlet奶陈、HttpServlet易阳、GenericServlet
代碼示例:
package com.javaweb.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/* 用注入聲明的方式表示這是一個 Servlet 類吃粒,不用在web.xml中配置 Servlet */
@WebServlet (
    urlPatterns = { "/HelloServlet" },
    name = " helloServlet "
)

// 繼承HttpServlet類
public class HelloServlet extends HttpServlet {

    // 序列化潦俺,可以自動生成或者自行定義
    private static final long serialVersionUID = 1L;

    // 一、初始化階段的 init() 方法
    public void init() throws ServletException {
    System.out.println("初始化 init 方法");
    }

    // 過程二執(zhí)行的方法有一定的順序與條件,詳細請看: 五事示、關于 Servlet早像、HttpServlet、GenericServlet
    // 二肖爵、調用 public service 方法
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        System.out.println("調用 public service 方法");

        // 設定頁面的MINE類型和字符集
        response.setContentType("text/html;charset=utf-8");
    
        // 輸出響應
        PrintWriter out = response.getWriter();
        out.println("收到 service 請求");
    }

    // 二卢鹦、調用 protected service 方法
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        System.out.println("調用 protected service 方法");
    }

    // 二、調用 doGet() 方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    // 二劝堪、調用 doPost() 方法
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("調用 doPost() 方法"); 
    
        // 設定頁面的MINE類型和字符集
        response.setContentType("text/html;charset=utf-8");
    
        // 輸出響應
        PrintWriter out = response.getWriter();
        out.println("收到 HelloServlet doPost() 請求");
    }

    // 三冀自、消亡階段的 destory() 方法
    public void destory() {
        System.out.println("調用 destory() 方法");
    }
 } 

五、關于 Servlet幅聘、HttpServlet凡纳、GenericServlet

Servlet 來自于 javax.servlet.Servlet
HttpServlet 來自于 javax.servlet.http.HttpServlet
GenericServlet 來自于 javax.servlet.GenericServlet

1. Servlet

servlet 是一個接口窃植,如果實現(xiàn)這個接口帝蒿,那么就必須實現(xiàn)接口里面定義的所有方法。一般開發(fā)不會去自己實現(xiàn)該接口巷怜,它只提供了一種規(guī)范葛超,供 開發(fā)者 自己來編寫相關的實現(xiàn)


api中對 Servlet 接口的說明
  • 可以看出,Servlet接口提供了5個必須實現(xiàn)的方法


    Servlet 接口中的方法

2. GenericServlet

  • GenericServlet 定義了一個通用的延塑,無關協(xié)議的Servlet绣张。如果要在Web應用中使用Http進行Servlet通信,請擴展 HttpServlet(即繼承 HttpServlet
  • 在《JSP從零開始》的第100—101頁有GenericServlet類的部分源代碼关带,讀者有興趣可研究一下


    api中對 GenericServlet 抽象類的說明
  • 下面是 GenericServlet中的方法
    GenericServlet 類中的方法

3. HttpServlet

HttpServlet 是一個抽象類侥涵,它繼承了 GenericServlet 抽象類,而 GenericServlet 類實現(xiàn)了 Servlet 接口宋雏,所以HttpServlet 類也就默認實現(xiàn)了 Servlet 接口芜飘。默認實現(xiàn)規(guī)范而實用,開發(fā)web端的servlet程序磨总,一般我們只需繼承 HttpServlet 類就可以了

api中對 HttpServlet 抽象類的說明

  • 創(chuàng)建 HttpServlet 的步驟:
    ①繼承 HttpServlet 抽象類嗦明;
    ②覆蓋 HttpServlet 的部分方法,如覆蓋 doGet()doPost() 方法蚪燕;
    ③獲取HTTP請求信息娶牌。通過 HttpServletRequest 對象來檢索HTML表單所提交的數(shù)據(jù)或URL上的查詢字符串;
    ④生成HTTP響應結果馆纳。通過 HttpServletResponse 對象生成響應結果诗良,它有個 getWriter() 方法,該方法返回一個 PrintWriter 對象鲁驶。

  • 它總共有10個方法累榜,其中實現(xiàn)了:


    HttpServlet 中的方法

① 2個重載的 service() 方法

  • 在servlet中默認情況下,無論是get還是post 提交過來 都會經(jīng)過service()方法來處理,然后轉向到doGet()doPost()方法壹罚,所以默認情況(沒有重寫service方法)下葛作,service()是用來轉向的。
  • 如果你在自己的servlet類中覆蓋了service()方法猖凛,那么service()就不是用來轉向了赂蠢,而是用來處理業(yè)務,這時不論客戶端是用post還是get來請求此servlet辨泳,都會執(zhí)行service()方法也只能執(zhí)行servlet()方法虱岂,不會去執(zhí)行doPost()doGet()方法。
    各個方法的執(zhí)行順序和條件

② doGet()菠红,doPost()第岖,doOptions(),doTrace()试溯,doDelete()蔑滓,doHead()投放, doPut() 這7個方法

  • 最常用的還是doGet()doPost()谜酒,但一般來說我們是用不到doGet()方法的堵第。doGet()方法提交表單時會在url后邊顯示提交內容辆苔,并不安全蛤肌。而且doGet()方法只能提交256個字符(1024字節(jié))懈玻,而doPost()沒有限制泽示,因為get方式數(shù)據(jù)的傳輸載體是URL(提交方式能form钳幅,也可以是任意的URL鏈接)付鹿,而POST是HTTP頭鍵值對(只能以form方式提交)澜汤。通常我們使用的都是doPost()方法,你只要在servlet中讓這兩個方法互相調用就行了舵匾。

③ getLastModified(HttpServletRequest req) 方法

  • 傳入?yún)?shù)為一個HttpServletRequest對象
  • 返回一個數(shù)值俊抵,該值為從 1970年1月1日HttpServletRequest對象最近一次修改的那個時刻 走過的毫秒數(shù)。

最后纽匙,分享我用PowerDesigner創(chuàng)建的面向對象模型的關系圖來說明三者的關聯(lián):


面向對象模型圖
  • 對PowerDesigner有興趣的讀者可以看該文集中的:PowerDesigner入門篇务蝠,可初步了解一下這個軟件的使用。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末烛缔,一起剝皮案震驚了整個濱河市馏段,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌践瓷,老刑警劉巖院喜,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異晕翠,居然都是意外死亡喷舀,警方通過查閱死者的電腦和手機砍濒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硫麻,“玉大人爸邢,你說我怎么就攤上這事∧美ⅲ” “怎么了杠河?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浇辜。 經(jīng)常有香客問我券敌,道長,這世上最難降的妖魔是什么柳洋? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任待诅,我火速辦了婚禮,結果婚禮上熊镣,老公的妹妹穿的比我還像新娘卑雁。我一直安慰自己,他們只是感情好轧钓,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布序厉。 她就那樣靜靜地躺著锐膜,像睡著了一般毕箍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上道盏,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天而柑,我揣著相機與錄音,去河邊找鬼荷逞。 笑死媒咳,一個胖子當著我的面吹牛,可吹牛的內容都是我干的种远。 我是一名探鬼主播涩澡,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坠敷!你這毒婦竟也來了妙同?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤膝迎,失蹤者是張志新(化名)和其女友劉穎粥帚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體限次,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡芒涡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片费尽。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡赠群,死狀恐怖,靈堂內的尸體忽然破棺而出旱幼,到底是詐尸還是另有隱情乎串,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布速警,位于F島的核電站叹誉,受9級特大地震影響,放射性物質發(fā)生泄漏闷旧。R本人自食惡果不足惜长豁,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忙灼。 院中可真熱鬧匠襟,春花似錦、人聲如沸该园。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽里初。三九已至啃勉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間双妨,已是汗流浹背淮阐。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刁品,地道東北人泣特。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像挑随,于是被迫代替她去往敵國和親状您。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容