Servlet面試總結

coding_1994發表於2018-07-14

最近面試,問了Servlet是什麼,當時也沒想那麼多,感覺知道怎麼用,用在那一層,用什麼語言實現,說下與JSP的區別就可以了,但是從面試的結果來看,面試官好像不是很認可,我們不能改變別人,只能讓自己無懈可擊,所以在網上書上找了些資料總結一下,感覺自己寫一下才是自己的東西。

一.什麼是Servlet

    簡單的說Servlet使用Java語言實現的程式,執行於支援Java語言的Web伺服器或者應用伺服器中。Servlet先於JSP出現,提供和客戶端動態互動的功能。Servlet可以處理來自客戶端的HTTP請求,並生成響應返回給客戶端。

    Servlet對於Web伺服器而言,就好像是Java Applet對於Web瀏覽器,Servlet需要加在到Web伺服器並在Web伺服器內執行。

    使用Servlet的基本流程如下:

    客戶端通過HTTP提出請求。

    Web伺服器接受改請求並將其發給servlet。如果這個servlet尚未被載入,Web伺服器將把它載入到Java虛擬機器並且執行它。

    Servlet將接收該HTTP請求執行某種處理。

    Servlet將向Web伺服器返回應答。

    Web伺服器將從servlet收到的應答傳送給客戶端。

    Java Servlet API 是Servlet容器(tomcat)和Servlet之間的介面,它定義了一個Servlet的各種方法,還定義了Servlet容器傳給Servlet的物件類,其中最重要的就是ServletRequest和ServletResponse。所以我們在編寫Servlet時,需要實現Servlet介面,按照其規定進行操作。

二.Servlet的優點:

    1.可以移植性:

    由於Servlet是用Java語言編寫的,因此它可以在不同的作業系統和伺服器上移植。

    2.安全:

    Servlet也具有型別檢查特徵,並利用Java的垃圾收集和沒有指標的設計,使得Servlet避免了記憶體管理等問題。

    3.高效:

    Servlet載入執行後會常駐伺服器記憶體中,當再次受到客戶端的請求時,伺服器會產生新的執行緒而不是程式為客戶端服務,這樣就提高了響應速度。

 

 

三.編寫Servlet    

    在前面,我們已經知道了Servlet是什麼,為什麼需要Servlet?(為了實現動態網頁,而不是顯示靜態網頁),tomcat和Servlet的關係?等問題。現在手動編寫一個Servlet。

  1.建立一個MyServlet繼承HttpServlet,重寫doGet和doPost方法,也就是看請求的方法是get還是post,然後不同的處理方式來處理請求:

            

    2.在Web.xml中配置MyServlet,為什麼需要配置?讓瀏覽器發出的請求知道到達那個servlet,也就是讓tomcat將封裝好的request找到對應的servlet讓其使用。

        配置四個東西:

       

                        配置之後,瀏覽器是如何通過我們配置的資訊來找到對應的servlet的。

                             

      

           按照步驟,首先瀏覽器通過http://localhost:8080/test01/MyServlet來找到web.xml中的url-parttern,這就是第一步,匹配到了url-parttern後,就會找到第二步servlet的名字MyServlet,知道了名字,就可以通過Servlet-name找到第三步,到了第三步,也就能夠知道Servlet的位置了。然後到其中找到對應的處理方式進行處理。

    3.實驗,驗證上面配置成功。

                                

    

            

 

    補充:

    利用Eclipse建立MyServlet

    1.右擊專案,在new選項中有直接新建servlet的選項。

    2.配置MyServlet類中的資訊

                    

 

 

    3.配置web.xml中的Servlet資訊

                

 

    4.檢視MyServlet01類中的程式碼和Web.xml,其中的配置跟手動的配置是一樣的,只是用圖形化介面,讓我們更方便的建立servlet而產生的。

    四.Servlet的生命週期:

    Servlet的生命週期可以概括為以下幾個階段:

    1)當客戶端第一次請求Servlet時,Servlet被載入到記憶體中,容器會建立Servlet例項,並呼叫其init()方法進行初始化工作。

    2)容器建立請求物件和響應物件,然後呼叫Servlet的service()方法為客戶端提供服務。

    3)當Servlet不再被需要時,容器呼叫Servlet的destory()方法將Servlet例項銷燬。

    當客戶端請求的Servlet已經存在於伺服器記憶體時,容器會建立信的執行緒呼叫service()方法響應客戶端請求。在Servlet的整個生命週期中,init()方法和destory()方法只會被呼叫一次。

 

    五.四個重點物件。ServletConfig;ServletContext;request;response

        講解四大類:Servlet物件,ServletContext物件,request物件,response物件

        ServletConfig物件

                獲取途徑:getServletConfig();

                功能:上面大概提及了下,能用到四個東西:

                         

                 

                getServletName();//獲取servlet的名稱,也就是我們在web.xml中配置的servlet-name

                getServletContext();//獲取ServletContext物件,該物件的作用看下面講解;

                getInitParameter(String);//獲取在servlet中初始化引數的值。這裡注意與全域性初始化引數的區分。這個獲取的知識在該servlet下的初始化引數。

                                    

                            

                  getInitParameterNames();//獲取在Servlet中所有初始化引數的名字,也就是key值,可以通過key值,來找到各個初始化引數的value值。注意發揮的是列舉型別。

                               

           

                

               

                

 

            注意:在上面我們所分析的原始碼過程中,我們就知道,其實可以不用先獲得ServletConfig,然後在獲取各個引數,可以直接使用其它方法,比如上面我們用的ServletConfig().getServletName();可以直接寫成getServletName();而不用在獲取ServletConfig();了,原因就是在GenericServlet中,已經幫我們獲取了這些資料,我哦們只需要直接拿就行了。

            

            ServletContext物件

                獲取途徑:

                    getServletContext();getServletConfig().getServletContext();//這兩種獲取方式的區別就跟上面的解釋一樣,第一種是直接拿,在GenericServlet中已經幫我們用getServletConfig.getServletContext();拿到了ServletContext。我們只需要直接獲取就行了,第二種就相當於我們自己在獲取一遍,兩種讀是一樣的。

                    功能:tomcat為每個web專案都建立一個ServletContext例項,tomcat在啟動時建立,伺服器關閉時銷燬,在一個web專案中共享資料,管理web專案資源,為整個web匹配公共資訊等,通俗點講,就是一個web專案,就存在一個ServletContext例項,每個Servlet讀可以訪問到它。

                    1.web專案中共享資料,getAttribute(String name),setAttribute(String name,Object obj),removeAttribute(String name)

                        setAttribute(String name,Object obj)在web專案範圍記憶體放內容,以便讓在web專案中所有的servlet讀能訪問到。

                        getAttribute(String name)通過制定名稱獲得內容

                        removeAttribute(String name)通過制定名稱移除內容

 

                                        

                  

                         

           

                                            

                         

                2.整個web專案初始化引數//這個就是全域性初始化引數,每個Servlet中都能獲取到該初始化值。

                    getInitParameter(String name)     //通過指定名稱獲取初始化值

                    getInitParameterNames()            //獲得列舉型別

                    web.xml配置  整個web專案的初始化

                                    

                     

         

        

                3.獲取web專案資源

                    1)獲取web專案下指定資源的路徑:

                        getServletContext().getRealPath("/WEB-INF/web.xml");

                                        

                         

        

                    2)獲取web專案下指定資源的內容,返回的是位元組輸入流。InputStream.getResourceAsStream(java.lang.String path)

                        前提知識:需要了解流。

 

                Request物件

                        request物件就是將請求文字封裝而成的物件,所以通過request能獲得請求文字中的宿友內容,請求頭,請求體,請求行。

                                    

                       

 

                        1.請求行內容的獲取:

                                            

                                           

             

                                                             

                                             

                        2.請求頭的獲取:

                                隨便百度一個東西,然後檢視的請求頭,包括下面這些內容,稍作了解。

                                                
                                         

                                String getHeader(java.lang.String  name)獲得指定頭內容String

                                System.out.println(req.getHeader("Accept-Language"));

                         3.請求體的獲取--請求引數的獲取

                                分為兩種,一種get請求,一種post請求

                                 get請求引數:http://localhost:8080/test01/MyServlet?username = jack & password = 1234

                                 post請求引數:<form  method = "post"><input type="text" name="username">

                                        String request.getParameter(String)獲得指定名稱,一個請求引數值。

                                        String[] request.getParameterValues(String)獲得指定名稱,一個請求引數值。

                          4.請求轉發

                                request.getRequestDispatcher(String path).forward(request,response);

                                //path:轉發後跳轉的頁面,這裡不管用不用“/”開頭,都是以web專案根開始,因為這是請求轉發,請求                                  //轉發只侷限與在同一個web專案下使用,所以這裡一直都是從web專案根下開始的。

                            web專案根就是從該web專案名開始,所以我們請求轉發時,只需接著專案名後面需要訪問的路徑寫就行了。

                             特點:瀏覽器中的URL不會改變,也就是瀏覽器不知道伺服器做了什麼,是伺服器幫我們跳轉頁面的,並且                                        在轉發後的頁面,能夠繼續使用原先的request,因為是原先的request,所以request域中的屬性都可                                         以繼續獲取到。

                              

                response物件

                                          

    

 

                常用的一個方法:response.setHeader(java.lang.String name,java.lang.String value)

                 設定指定的頭,一般常用。

                 例如:設定每隔3秒就自動重新整理一次,

                    response.setHeader("Refresh",3);

                                    

                         

          

 

                    這樣可以看到現在時間的秒數,會發現每隔三秒就會自動重新整理一次頁面。

                    這個最重要的一個就是重定向,其它的一些操作都被裝到response物件中了

                    重定向(頁面跳轉)

                    方式一:手動方案

                                response.setStatus(302);     //狀態碼302就代表重定向

                                response.setHeader("location","http://www.baidu.com");

                    方式二:使用封裝好的,通過response.sendRedirect("http://www.baidu.com");

                    特點:

                    伺服器告訴瀏覽器要跳轉的頁面,是瀏覽器主動跳轉的頁面,瀏覽器知道,瀏覽器中的位址列url也會改變,是瀏覽                       器重新發起一個請求到另外一個頁面,所以request是重新發起的,跟請求轉發不一樣。

                    注意:response.sendRendirect(path);

                    第一種:response.sendRedirect("/test01/MyServlet01");     //使用了“/”開頭,說明是從web站點根開始,所以需                                 要寫test01/MyServlet01 

                    第二種:response.sendRedirect("MyServlet01");     //沒有使用"/"開頭,說明從web專案開始,那麼就無需寫                                       test01了。

                    重定向沒有任何侷限,可以重定向web專案內的任何路徑,也可以訪問別的web專案中的路徑,並且這裡就用"/"區分開來,如果使用了"/"開頭,就說明我要重新開始定位了,不訪問剛才的web專案,自己寫專案名,如果沒有使用"/ "開始,那麼就知道是訪問剛才那個web專案 下的servlet,就可以省略專案名了。就是這樣來區別的。

 

Servlet處理請求的流程:

    1) 客戶端在瀏覽器的位址列中輸入一個請求的URL,按回車後就向伺服器端發起一個http request(由瀏覽器生成)。

    2) 伺服器端的Web Server首先接受到請求,並將請求轉交給容器,容器會根據請求的URL去呼叫客戶端要訪問的Servlet。

    3) 容器會根據web.xml中對Servlet的描述去查詢要訪問的Servlet,若找到,將此Servlet

裝載進虛擬機器並例項化(第一次訪問),然後呼叫Servlet例項中的service方法處理請求,並分配一個執行緒去執行。

注: 當第二次去訪問同一個Servlet時,若容器判斷到該Servlet已經被裝載並例項化,

那麼容器就不會再去建立一個新的Servlet例項,直接呼叫原來那個Servlet例項中的service方法

來處理請求。

    4) 若沒有查詢到,直接返回一個404的錯誤程式碼到客戶端,表示訪問的資源不存在。

 

 

 

Servlet處理響應:

設定HTTP狀態碼


 

設定HTTP響應頭

HttpServletResponse物件用於操縱響應的HTTP頭

目的用於告訴客戶端

–傳送回來的內容的型別

–有多少內容正被髮送

常用的方法:

setContentType(String mimetype);

addCookie(Cookie c);

傳送內容的伺服器的型別

設定HTTP訊息體

HttpServletResponse物件負責將資訊返回給客戶端

HttpServletResponse物件只產生一個空的HTTP響應

傳回自定義的內容需要使用getWriter()或者getOutputStream()方法

–傳送普通文字

–傳送二進位制內容 

 

請求重定向和自動重新整理頁面

重定向的原理:

         

            

          

使用sendRedirect(String URL)方法實現重定向,

 

在指定時間內自動重新整理當前頁或到一個新的頁面

根據時間來控制響應

想在響應中有一個短時間的暫停 

response.setHeader("Refresh", "time; URL=url" );

 總結:

請求URL時HTTP發出了多個請求

狀態碼告訴瀏覽器傳送的內容及格式狀態

Servlet API與容器進行通訊

HttpServletResponse定義的常量來避免直接使用整數

在通過PrintWriter物件傳送任何內容之前先呼叫 HttpServletResponse的setStatus()方法

為了讓Servlet發揮最大的效能,HttpServletResponse物件用於操縱響應的HTTP頭

getWrite()或者getOutputStream()方法傳送文字或者二進位制內容給客戶端

sendRedirect方法實現重定向

HTTP響應頭“Refresh”會根據時間來控制響應

 

 

        

 

 

 

    

    

                

相關文章