1. 程式人生 > >Servlet如何處理請求及生命週期

Servlet如何處理請求及生命週期

一、servlet容器如何處理請求資源路徑?

    比如,在瀏覽器位址列輸入
    http://ip:port/web04_2/abc.html
    瀏覽器會將請求資源路徑("/web04_2/abc.html")放到請求資料包裡面,傳送給容器。容器收到之後,會依據應用名("/web04_2")找到應用所在的資料夾,然後,容器預設認為訪問的是一個servlet,會依據<url-pattern>來查詢有沒有對應的servlet:
        方式一: 精確匹配
            <url-pattern>的值是"/abc.html"。
        方式二:  萬用字元匹配
            即使用"*"來匹配任意的0個或者多個字元,比如
            <url-pattern>/*</url-pattern>
        方式三:  字尾匹配
            即使用"*."開頭,後接1個或者多個字元,比如
            <url-pattern>*.do</url-pattern>
            會匹配所有以".do"結尾的請求。
            http://ip:port/web04_2/aaaa.do  ok
            http://ip:port/web04_2/adfasdfa/asdfasfd.do ok
    如果容器找不到匹配的servlet,容器會認為訪問的是一個html檔案,然後查詢該檔案,找到了,就返回該檔案的內容,找不到,返回404。
    

二、讓一個servlet處理多個請求

    step1, 使用字尾匹配模式
            <url-pattern>*.do</url-pattern>
    step2,  分析請求資源路徑,依據請求的不同,呼叫不同的分支來處理。
            request.getRequestURI();
    

三、servlet的生命週期

    (1)生命週期的含義
        servlet容器建立servlet物件、分配相應的資源給servlet物件、呼叫servlet物件的方法處理請求,以及銷燬servlet物件的過程。
    (2)四個階段
        1)例項化
            a,什麼是例項化?
                容器呼叫servlet的構造器,建立servlet物件。
                注意:
                    容器只會建立一個servlet物件。
            b,什麼時候建立servlet物件?
                情況1:容器收到請求之後,才會建立。
                情況2:  容器在啟動的時候,會檢查servlet的配置,如果某個servlet配置了<load-on-startup>引數,則會馬上進行例項化操作。引數值是一個大於等於0的整數,越小,優先順序越高(即先被容器建立)。
        2)初始化
            a,什麼是初始化?
                容器在建立好servlet物件之後,會立即呼叫該物件的init方法。
            b,GenericServlet的init方法是如何實現的?
                將容器傳遞進來的ServletConfig物件儲存下來,並且,提供了getServletConfig方法來獲得ServletConfig物件。
            c,ServletConfig物件的作用
                訪問servlet的初始化引數:
                    step1, 配置初始化引數,比如
                    <init-param>
                        <param-name>company</param-name>
                        <param-value>IBM</param-value>
                    </init-param>    
                    step2,呼叫
                        config.getInitParameter("company");
            d,如果GenericServlet提供的init方法不滿足程式設計的要求,可以override init()方法。
            e,init方法只會執行一次。        
        3)就緒
            a,什麼是就緒?
                容器呼叫servlet物件的service方法來處理請求。
            b,HttpServlet的service方法是如何實現的?
                依據請求方式分別呼叫doGet或者doPost方法。
                 HttpServlet提供了doGet,doPost方法的實現,但是,只是丟擲了異常。
                 如果要實現業務處理,可以選擇兩個方式:
                     方式一:override HttpServlet的service方法。
                     方式二:override HttpServlet的doGet和doPost
                     方法。
        4)銷燬
            a,什麼是銷燬?
                容器在刪除servlet物件之前,會先呼叫該物件的destroy方法。
            b,容器會依據自身的演算法來決定什麼時候銷燬servlet。

            c,destroy方法只會執行一次。

如上圖所示,Servlet容器處理請求的步驟如下:

1、容器接收請求

2-3、依次建立request、response物件

4、建立Servlet物件,呼叫其init()方法

5、因為init()方法需要傳一個config物件作為引數,故還要建立ServletConfig物件

6、呼叫servlet的init()初始化方法完成初始化

7、呼叫servlet的service()方法,並將建立的request、response物件作為引數傳入,執行處理邏輯

8、呼叫servlet的destory()方法。

    (3)生命週期相關的幾個介面與類
        Servlet介面
            init(ServletConfig config)
            service(ServletRequest req,ServletResponse res)
            destroy()
        GenericServlet抽象類
            實現了Servlet介面中的部分方法(init,destroy)
        HttpServlet抽象類
            繼承GenericServlet,實現了service方法。
        ServletConfig介面
        ServletRequest介面是HttpServletRequest的父介面

        ServletResponse介面    是HttpServletResponse父介面