回顧下Servlet(1) 2018-08-02

Servlet的核心是Servelt那么我們就以此展開進(jìn)回顧

Servlet接口定義如下:

package javax.servlet;
import java.io.IOException;

public interface Servlet {
  
   public void init(ServletConfig config) throws ServletException;
   public ServletConfig getServletConfig();
   public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;
    public String getServletInfo();
    public void destroy();
}

init雏搂、Service和destory是生命周期的方法:

(1) init()方法:當(dāng)?shù)谝淮握?qǐng)求Servlet時(shí),創(chuàng)建完servlet對(duì)象的時(shí)候調(diào)用拳氢。只會(huì)調(diào)用1次杭煎。說(shuō)明Servelt是單例哼拔,成員變量有線程安全的問(wèn)題概行。

(2) service()方法:每次發(fā)出請(qǐng)求時(shí)調(diào)用盖呼。調(diào)用n次儒鹿,也就是說(shuō)每發(fā)出一次請(qǐng)求都會(huì)調(diào)用一次service()。

(3) destroy()方法: 銷毀servlet對(duì)象的時(shí)候調(diào)用几晤。停止服務(wù)器或者重新部署web應(yīng)用時(shí)銷毀servlet對(duì)象约炎。只會(huì)調(diào)用1次。

其他兩個(gè)非生命周期的方法:

getServletInfo():獲取Servelt的描述信息

getServletConfig():獲取封裝Servelt配置的ServeltConfig

?由于Servlet不是線程安全的蟹瘾,一個(gè)應(yīng)用程序中所有的用戶公用一個(gè)Servlet實(shí)例圾浅,因此不建議使用類級(jí)別的變量(只使用局部變量最好),除非是只讀的或者java.utilconcurrent.atomic包中的成員憾朴。

其中涉及到的對(duì)象:
ServletRequest :

?對(duì)于每一個(gè)HTTP請(qǐng)求狸捕,servlet容器會(huì)創(chuàng)建一個(gè)封裝了HTTP請(qǐng)求的ServletRequest實(shí)例傳遞給servlet的service方法。

ServletResponse:

?ServletResponse則表示一個(gè)Servlet響應(yīng)众雷,在調(diào)用service方法前灸拍,servelt容器首先創(chuàng)建一個(gè)ServeltResponse,并 將它作為第二個(gè)參數(shù)傳給Service方法砾省。其影藏了將響應(yīng)發(fā)給瀏覽器的復(fù)雜性鸡岗。

ServletConfig:

?ServletConfig封裝可以通過(guò)@WebServlet或者web.xml傳給一個(gè)Servlet的配置信息,以這種方式傳遞的每一條信息都稱做初始化信息编兄,初始化信息就是一個(gè)個(gè)K-V鍵值對(duì)轩性。為了從一個(gè)Servlet內(nèi)部獲取某個(gè)初始參數(shù)的值,init方法中調(diào)用ServletConfig的getinitParameter方法或getinitParameterNames方法獲取狠鸳,除此之外揣苏,還可以通過(guò)getServletContext獲取ServletContext對(duì)象。

ServletContext:

?ServletContext是代表了Servlet應(yīng)用程序碰煌。每個(gè)Web應(yīng)用程序只有一個(gè)context舒岸。在分布式環(huán)境中,一個(gè)應(yīng)用程序同時(shí)部署到多個(gè)容器中芦圾,并且每臺(tái)Java虛擬機(jī)都有一個(gè)ServletContext對(duì)象蛾派。有了ServletContext對(duì)象后,就可以共享能通過(guò)應(yīng)用程序的所有資源訪問(wèn)的信息个少,促進(jìn)Web對(duì)象的動(dòng)態(tài)注冊(cè)洪乍,共享的信息通過(guò)一個(gè)內(nèi)部Map中的對(duì)象保存在ServiceContext中來(lái)實(shí)現(xiàn)。保存在ServletContext中的對(duì)象稱作屬性夜焦。

接著我們來(lái)看看Servlet的兩個(gè)子類:

GenericServlet:

GenericServlet抽象類就是為了為我們省略一些模板代碼壳澳,實(shí)現(xiàn)了Servlet和ServletConfig,完成了一下幾個(gè)工作:
1茫经、將init方法中的ServletConfig賦給一個(gè)類級(jí)變量巷波,使的可以通過(guò)getServletConfig來(lái)獲取萎津。
2、為Servlet接口中的所有方法提供默認(rèn)實(shí)現(xiàn)抹镊。
3锉屈、提供方法來(lái)包裝ServletConfig中的方法。

HttpServelt

?HttpServlet繼承了GenericServlet垮耳,HttpServletRequest/Response繼承了覆蓋了ServletRequest/Response颈渊,成為了新的Servlet請(qǐng)求和響應(yīng)的代表。在HttpServlet中覆蓋了GenericServlet的service方法终佛,并用新的Servlet請(qǐng)求和響應(yīng)代表作為參數(shù)添加了一個(gè)service方法:

//覆蓋GenereicServlet中的service

public void service(ServletRequest req, ServletResponse res)

       throws ServletException, IOException
   {
           HttpServletRequest  request;
           HttpServletResponse response;       
           if (!(req instanceof HttpServletRequest &&
                   res instanceof HttpServletResponse)) {
               throw new ServletException("non-HTTP request or response");
           }
           request = (HttpServletRequest) req;
           response = (HttpServletResponse) res;
           service(request, response);
       }
}

?原始的service方法將請(qǐng)求和響應(yīng)進(jìn)行向下轉(zhuǎn)換俊嗽,分別為HttpServletRequest和HttpServletResponse,HttpServletRequest,HttpServletResponse由于帶有了HTTP的特性铃彰,因此除了ServletRequest绍豁,ServletResponse中的方法之外還增加了幾個(gè)可以獲取HTTP特性信息的方法。

  protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    // Invalid date header - proceed as if none was set
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);

        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);

        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);

        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);

        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);

        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);

            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }

Service方法會(huì)通過(guò)httpServeltRequest.getMethod()檢查用來(lái)發(fā)送http請(qǐng)求的方法并調(diào)用doGet豌研、doPut妹田、doPost、doDelete鹃共、doHead鬼佣、doTrace、doOptions這7種方法霜浴。這7種方法每一種都代表著一個(gè)http方法晶衷。

HTTP請(qǐng)求的方法:

HTTP/1.1協(xié)議中共定義了八種方法(有時(shí)也叫“動(dòng)作”),來(lái)表明Request-URL指定的資源不同的操作方式

1阴孟、GET:請(qǐng)求指定的頁(yè)面信息晌纫,并返回實(shí)體主體。
2永丝、HEAD:類似于get請(qǐng)求锹漱,只不過(guò)返回的響應(yīng)中沒(méi)有響應(yīng)體,用于獲取消息頭中的元信息
3慕嚷、POST:向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(例如提交表單或者上傳文件)哥牍。數(shù)據(jù)被包含在請(qǐng)求體中。POST請(qǐng)求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改喝检。
4嗅辣、PUT:向指定資源位置上傳其最新內(nèi)容。
5挠说、DELETE:請(qǐng)求服務(wù)器刪除Request-URL所標(biāo)識(shí)的資源澡谭。
6、CONNECT:HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器损俭。
7蛙奖、OPTIONS:返回服務(wù)器針對(duì)特定資源所支持的HTTP請(qǐng)求方法潘酗,也可以利用向web服務(wù)器發(fā)送‘*’的請(qǐng)求來(lái)測(cè)試服務(wù)器的功能性
8、TRACE:回顯服務(wù)器收到的請(qǐng)求外永,主要用于測(cè)試或診斷崎脉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伯顶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骆膝,老刑警劉巖祭衩,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異阅签,居然都是意外死亡掐暮,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門政钟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)路克,“玉大人,你說(shuō)我怎么就攤上這事养交【悖” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵碎连,是天一觀的道長(zhǎng)灰羽。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鱼辙,這世上最難降的妖魔是什么廉嚼? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮倒戏,結(jié)果婚禮上怠噪,老公的妹妹穿的比我還像新娘。我一直安慰自己杜跷,他們只是感情好傍念,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葱椭,像睡著了一般捂寿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孵运,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天秦陋,我揣著相機(jī)與錄音,去河邊找鬼治笨。 笑死驳概,一個(gè)胖子當(dāng)著我的面吹牛赤嚼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播顺又,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼更卒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了稚照?” 一聲冷哼從身側(cè)響起蹂空,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎果录,沒(méi)想到半個(gè)月后上枕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弱恒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年辨萍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片返弹。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锈玉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出义起,到底是詐尸還是另有隱情拉背,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布并扇,位于F島的核電站去团,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏穷蛹。R本人自食惡果不足惜土陪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肴熏。 院中可真熱鬧鬼雀,春花似錦、人聲如沸蛙吏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鸦做。三九已至励烦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泼诱,已是汗流浹背坛掠。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屉栓。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓舷蒲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親友多。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牲平,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • Servlet Interface 是Java Servlet API的核心抽象。所有的servlets都直接或者...
    Lucky_Micky閱讀 1,699評(píng)論 2 2
  • 前言 這篇文章的出發(fā)點(diǎn)是為了整理Servlet相關(guān)知識(shí)點(diǎn)域滥,以免在相關(guān)概念混淆或分不清的時(shí)候到處查閱資料纵柿。 一、什么...
    maxwellyue閱讀 3,465評(píng)論 2 35
  • 目標(biāo) servlet的生命周期 servletConfig與ServletContext定義骗绕,及其二者的區(qū)別 監(jiān)聽(tīng)...
    arkulo閱讀 970評(píng)論 0 5
  • 這部分主要是與Java Web和Web Service相關(guān)的面試題藐窄。 96、闡述Servlet和CGI的區(qū)別? 答...
    雜貨鋪老板閱讀 1,408評(píng)論 0 10
  • "要不要吃雞翅酬土?”王小姐系好安全帶后,向旁邊的男士側(cè)頭發(fā)問(wèn)格带。那是個(gè)三十歲上下的男子撤缴,面容有些憔悴,此刻有些局促不安...
    單單閱讀 518評(píng)論 17 5