JavaWeb--深入Servlet與JSP(運行原理)

來源:互聯網
上載者:User

標籤:優先   要求   title   記憶體回收   tar   runnable   erro   讀取   檔案的   

JavaWeb--深入Servlet與JSP(運行原理)複習複習!!!搞起來!!Servlet和JSP是Java EE規範最基本成員,他們是Java Web開發的重點知識,即使我們經常使用架構開發後端,但是我們還是很必要去理解他們的原理的。文章結構:(1)剖析Servlet;(2)剖析JSP;一、剖析Servlet:(1)概述:Servlet是一種獨立於平台和協議的伺服器端的Java應用程式,可以產生動態web頁面。它擔當Web瀏覽器或其他http客戶程式發出請求、與http伺服器上的資料庫或應用程式之間互動的中介層。Servlet是用Java編寫的Server端程式,它與協議和平台無關。Servlet運行於Java伺服器中。Java Servlet可以動態地擴充伺服器的能力,並採用要求-回應模式提供Web服務。Servlet是使用Java Servlet應用程式設計介面及相關類和方法的Java程式。它在Web伺服器上或應用伺服器上運行並擴充了該伺服器的能力。Servlet裝入Web伺服器並在Web伺服器內執行。Servlet是以Java技術為基礎的伺服器端應用程式組件,Servlet的用戶端可以提出請求並獲得該請求的響應,它可以是任何Java程式、瀏覽器或任何裝置。(2)基本知識:1.配置:編輯好的servlet源檔案並不能響應使用者請求,還必須將其編譯成class檔案,將編譯好的class檔案放到WEB-INF/classes路徑下,如果servlet有包,則還需要將class檔案放到包路徑下。2.生命週期:

編寫的JSP頁面最終將由web容器編譯成對應的servlet,當servlet在容器中運行時,其執行個體的建立及銷毀等都不是有程式猿決定的,而是由web容器進行控制的。servlet容器負責載入和執行個體化Servlet,在容器啟動時根據設定決定是在啟動時初始化(loadOnStartup大於等於0在容器啟動時進行初始化,值越小優先順序越高),還是延遲初始化直到第一次請求前;初始化:init(),執行一些一次性的動作,可以通過ServletConfig設定物件,擷取初始化參數,訪問ServletContext上下文環境;請求處理:servlet容器封裝Request和Response對象傳給對應的servlet的service方法,對於HttpServlet,就是HttpServletRequest和HttpServletResponse; HttpServlet中使用模板方法模式,service方法根據HTTP要求方法進一步指派到doGet,doPost等不同的方法來進行處理;對於HTTP請求的處理,只有重寫了支援HTTP方法的對應HTTP servlet方法(doGet),才可以支援,否則放回405(Method Not Allowed)。3.訪問servlet的配置參數:配置servlet時,還可以增加額外的配置參數,通過使用配置參數,可以實現提供更好的可移植性,避免將參數以編碼方式寫在程式碼中。配置參數有兩種方式:(1)通過@WebServlet的initParams屬性來指定。(2)通過在web.xml檔案的4.Servlet的數量:Servlet預設是線程不安全的,一個容器中只有每個servlet一個執行個體。StandardWrapper源碼中寫明,這個類負責Servlet的建立,其中SingleThreadModule模式下建立的執行個體數不能超過20個,也就是同時只能支援20個線程訪問這個Serlvet,因此,這種對象池的設計會進一步限制並發能力和延展性。5.缺點:開發效率低、 程式可移植性差、 程式可維護性差6.標準mvc模式中的servlet:僅作為控制器使用,JavaEE應用架構正是遵循mvc模式的,其中JSP僅作為表現層技術,其作用有兩點:1.負責收集使用者請求參數;2. 將應用的處理結果、狀態、資料呈現給使用者。7.線程不安全 :servlet中預設線程不安全,單例多線程,因此對於共用的資料(靜態變數,堆中的對象執行個體等)自己維護進行同步控制,不要在service方法或doGet等由service指派出去的方法,直接使用synchronized方法,很顯然要根據業務控制同步控制塊的大小進行細粒度的控制,將不影響安全執行緒的耗時操作移出同步控制塊;Servlet多線程機制背後有一個線程池在支援,線程池在初始化初期就建立了一定數量的線程對象,通過提高對這些對象的利用率,避免高頻率地建立對象,從而達到提高程式的效率的目的。(由線程來執行Servlet的service方法,servlet在Tomcat中是以單例模式存在的, Servlet的安全執行緒問題只有在大量的並發訪問時才會顯現出來,並且很難發現,因此在編寫Servlet程式時要特別注意。安全執行緒問題主要是由執行個體變數造成的,因此在Servlet中應避免使用執行個體變數。如果應用程設計無法避免使用執行個體變數,那麼使用同步來保護要使用的執行個體變數,但為保證系統的最佳效能,應該同步可用性最小的代碼路徑)8.非同步處理:在Servlet中等待是一個低效的操作,因為這是阻塞操作。非同步處理請求能力,使線程可以返回到容器,從而執行更多的任務。當開始非同步處理請求時,另一個線程或回調可以:(1)產生響應;或者,(2)請求指派;或者,(3)調用完成;關鍵方法:啟用:讓servlet支援非同步支援:asyncSupported=true;啟動AsyncContextasyncContext=req.startAsyncContext();或startAsyncContext(req,resp);完成:asyncContext.complete();必須在startAsync調用之後,指派進行之前調用;同一個AsyncContext不能同時調用dispatch和complete指派:asyncContext.dispatch();dispatch(Stringpath);dispatch(ServletContextcontext,Stringpath); 不能在complete之後調用; 從一個同步servlet指派到非同步servlet是非法的;逾時:asyncContext.setTimeout(millis); 逾時之後,將不能通過asyncContext進行操作,但是可以執行其他耗時操作;在非同步周期開始後,容器啟動的指派已經返回後,調用該方法拋出IllegalStateException;如果設定成0或小於0就表示notimeout; 逾時表示HTTP串連已經結束,HTTP已經關閉,請求已經結束了。啟動新線程 :通過AsyncCOntext.start(Runnable)方法,向線程池提交一個任務,其中可以使用AsyncContext(未逾時前);事件監聽:addListener(newAsyncListener{…});onComplete:完成時回調,如果進行了指派,onComplete方法將延遲到指派返回容器後進行調用;onError:可以通過AsyncEvent.getThrowable擷取異常;onTimeout:逾時進行回調;onStartAsync:在該AsyncContext中啟動一個新的非同步周期(調用startAsyncContext)時,進行回調;逾時和異常處理,步驟:(1)調用所有註冊的AsyncListener執行個體的onTimeout/onError;(2)如果沒有任何AsyncListener調用AsyncContext.complete()或AsyncContext.dispatch(),執行一個狀態代碼為HttpServletResponse .SC_INTERNAL_SERVER_ERROR出錯指派;(3)如果沒有找到錯誤頁面或者錯誤頁面沒有調用AsyncContext.complete()/dispatch(),容器要調用complete方法;servlet生命終止:servlet容器確定從服務中移除servlet時,可以通過調用destroy()方法將釋放servlet佔用的任何資源和儲存的持久化狀態等。調用destroy方法之前必須保證當前所有正在執行service方法的線程執行完成或者逾時;之後servlet執行個體可以被記憶體回收,當然什麼時候回收並不確定,因此destroy方法是是否必要的。(3)運行原理:當Web伺服器接收到一個HTTP請求時,它會先判斷請求內容——如果是靜態網頁資料,Web伺服器將會自行處理,然後產生響應資訊;如果牽涉到動態資料,Web伺服器會將請求轉交給Servlet容器。此時Servlet容器會找到對應的處理該請求的Servlet執行個體來處理,結果會送回Web伺服器,再由Web伺服器傳回使用者端。針對同一個Servlet,Servlet容器會在第一次收到http請求時建立一個Servlet執行個體,然後啟動一個線程。第二次收到http請求時,Servlet容器無須建立相同的Servlet執行個體,而是啟動第二個線程來服務用戶端請求。所以多線程方式不但可以提高Web應用程式的執行效率,也可以降低Web伺服器的系統負擔。粗暴解釋了請求到容器流程

解釋了請求到容器到servlet周期流程

文字解說:1.客戶發出請求—>Web 服務器轉寄到Web容器Tomcat;2.Tomcat主線程對轉寄來使用者的請求做出響應建立兩個對象:HttpServletRequest和HttpServletResponse;3.從請求中的URL中找到正確Servlet,Tomcat為其建立或者分配一個線程,同時把步驟2建立的兩個對象傳遞給該線程;4.Tomcat調用Servlet的servic()方法,根據請求參數的不同調用doGet()或者doPost()方法;5.假設是HTTP GET請求,doGet()方法產生靜態頁面,並組合到響應對象裡;Servlet線程結束時:Tomcat將響應對象轉換為HTTP響應發回給客戶,同時刪除請求和響應對象。可以理解Servlet的生命週期:Servlet類載入(對應3步);Servlet執行個體化(對應3步);調用init方法(對應3步);調用service()方法(對應4、5步);;調用destroy()方法(對應6步)。注意:1.建立Servlet對象的時機:Servlet容器啟動時:讀取web.xml設定檔中的資訊,構造指定的Servlet對象,建立ServletConfig對象,同時將ServletConfig對象作為參數來調用Servlet對象的init方法。在Servlet容器啟動後:客戶首次向Servlet發出請求,Servlet容器會判斷記憶體中是否存在指定的Servlet對象,如果沒有則建立它,然後根據客戶的請求建立HttpRequest、HttpResponse對象,從而調用Servlet 對象的service方法。Servlet Servlet容器在啟動時自動建立Servlet,這是由在web.xml檔案中為Servlet設定的屬性決定的。從中我們也能看到同一個類型的Servlet對象在Servlet容器中以單例的形式存在。2.在Servlet介面和GenericServlet中是沒有doGet()、doPost()等等這些方法的,HttpServlet中定義了這些方法,但是都是返回error資訊,所以,我們每次定義一個Servlet的時候,都必須實現doGet或doPost等這些方法。我們經常使用的httpServlet是繼承於GenericServlet實現的。二、剖析JSP(1)概述:JSP和Servlet的本質是一樣的,因為JSP最終需要編譯成Servlet才能運行,換句話說JSP是產生Servler的草稿檔案。JSP就是在HTML中嵌入Java代碼,或者使用JSP標籤,包括使用使用者自訂標籤,從而可以動態提供內容。早起JSP應用比較廣泛,一個web應用可以全部由JSP頁面組成,只需要少量的JavaBean即可,但是這樣導致了JSP職責過於複雜,這是Java EE標準的出現無疑是雪中送炭,因此JSP慢慢發展成單一的表現技術,不再承擔商務邏輯組件以及持久層組件的責任。原理概述:(一會詳解)JSP的本質是servlet,當使用者指定servlet發送請求時,servlet利用輸出資料流動態產生HTML頁面。由於包含大量的HTML標籤。靜態文本等格式導致servlet的開發效率極低,所有的表現邏輯,包括布局、色彩及映像等,都必須耦合在Java代碼中,起靜態部分無需Java程式控制,只有那些需要從資料庫讀取或者需要動態產生的頁面內容才使用Java指令碼控制。因此,JSP頁面內容有以下兩部分組成:靜態部分:HTML標籤動態部分:Java指令碼(2)基本知識:指令就省略了吧,隨便查都有一堆。重點講講它的內建對象:首先,我們可以自己去一個目錄去看看jsp編譯成servlet的代碼。目錄是:你的eclipse的工作目錄下:比如:E:\eclipse\workplace.metadata.plugins\org.eclipse.wst.server.core\tmp0\work\從中,我們可以看到有九個隱藏對象,一些就final了,一些沒有。1.request(使用最多):HttpServletRequest的一個對象(在JSP頁面可能會用到)。Request範圍只針對伺服器端跳轉。用於接收用戶端發送而來的請求資訊。注意:單一的參數可以使用getParameter()接收,而一組參數要用getParameterValues()接收。但要小心,如果getParameter和getParameterValues接收參數時,返回內容是null,就可能產生NullPointerException,所以最好判斷接收來的參數是否為null。擷取頭資訊的名稱,可使用request的getHeaderNames()方法;而要想取出每個頭資訊的內容則需使用getHeader()方法。比如:語言、主機、Cookie等。2.Response:HttpServletResponse的一個對象(在JSP頁面中幾乎不會調用response的任何方法)主要作用:對用戶端的請求進行回應,將Web伺服器處理後的結果發回給用戶端。設定頭資訊:用戶端與伺服器端經常需要發送許多額外資訊。伺服器端可通過setHeader方法,將頭資訊設定為refresh,並指定重新整理時間,還有跳轉的路徑URL。如:例子就是那些頁面經常提示的“3秒後跳轉到首頁”這樣的操作。如果定時為0,則為無條件跳轉。注意:定時跳轉屬於用戶端跳轉。而且這種設定跳轉頭資訊的方式,單純html也可以做,所以要結合實際考慮,如需請求的是動態網頁則需JSP進行編寫3.pageContext:頁面的上下文,表示當前頁面,是一個PageContext的一個對象,可以從該對象中擷取到其他8個隱含對象,也可以從中擷取到當前頁面的其他資訊。(學習自訂標籤時使用它,JSP頁面上很少直接使用,1`但很重要)。作用範圍僅在當前頁面。實際上pageContext可以設定任意範圍的屬性,而其他動作也是對這一功能的再度封裝而已。但一般習慣於使用pageContext對象設定儲存在一頁範圍的屬性。很少使用他進行設定其他範圍的屬性。4.session:代表瀏覽器和伺服器的一次會話,是HttpSession的一個對象,後面詳細學習。這個session屬性設定後,可在任何一個與設定頁面相關的頁面中擷取。也就是不管是用戶端跳轉還是伺服器端跳轉都可以取得屬性。但是如果再開啟一個新的瀏覽器訪問該jsp頁面,則無法取得session屬性。因為每個新的瀏覽器串連上伺服器後就是一個新的session。5.application:代表當前web應用。是ServletContext對象。這個設定的屬性可讓所有使用者(session)都看得見。這樣的屬性儲存在伺服器上。6.config:前JSP對應的Servlet的ServletConfig對象(開發的時候幾乎不用)。若需要訪問當前JSP配置的初始化參數,需要通過映射的地址才可以。映射JSP方式:

7.out:作用:完成頁面的輸出操作。但在開發中,一般是使用運算式完成輸出的。JspWriter對象,經常調用out.println() 可以直接把字串列印到瀏覽器上。8.page指向當前JSP對應的Servlet對象的引用,但為Object類型,只能調用Object類的方法(幾乎不使用)。就是當前JSP對象。9.exception:在聲明了page 指令的isErrorPage=”true”時,才可以使用。<%@ page isErrorPage=”true”%>大致使用頻率:pageContext,request,session,application;(對屬性的範圍的範圍從小到大)out,response,config,page,exception(3)JSP運行原理:

 

1.WEB容器(Servlet引擎)接收到以.jsp為副檔名的URL的訪問請求時,容器會把訪問請求交給JSP引擎去處理2.每個JSP頁面在第一次被訪問時,JSP引擎將它翻譯成一個Servlet來源程式,接著再把這個Servlet來源程式編譯成Servlet的.class類檔案,然後再由WEB容器(Servlet引擎)像調用普通Servlet程式一樣的方式來裝載和解釋執行這個由JSP頁面翻譯成的Servlet程式,並執行該servlet執行個體的jspInit()方法(jspInit()方法在Servlet的生命週期中只被執行一次)。。3.然後建立並啟動一個新的線程,新線程調用執行個體的jspService()方法。(對於每一個請求,JSP引擎會建立一個新的線程來處理該請求。如果有多個用戶端同時請求該JSP檔案,則JSP引擎會建立多個線程,每個用戶端請求對應一個線程)。4.瀏覽器在調用JSP檔案時,Servlet容器會把瀏覽器的請求和對瀏覽器的回應封裝成HttpServletRequest和HttpServletResponse對象,同時調用對應的Servlet執行個體中的jspService()方法,把這兩個對象作為參數傳遞到jspService()方法中。5.jspService()方法執行後會將HTML內容返回給用戶端。如果JSP檔案被修改了,伺服器將根據設定決定是否對該檔案進行重新編譯。如果需要重新編譯,則將編譯結果取代記憶體中的Servlet,並繼續上述處理過程。 如果在任何時候由於系統資源不足,JSP引擎將以某種不確定的方式將Servlet從記憶體中移去。當這種情況發生時,jspDestroy()方法首先被調用, 然後Servlet執行個體便被標記加入“垃圾收集”處理。補充:1.JSP規範也沒有明確要求JSP中的指令碼程式碼必須採用Java語言,JSP中的指令碼程式碼可以採用Java語言之外的其他指令碼語言來編寫,但是JSP頁面最終必須轉換成JavaServlet程式。2.可以在WEB應用程式正式發布之前,將其中的所有JSP頁面預先編譯成Servlet程式。3.以多線程方式執行可大大降低對系統的資源需求,提高系統的並發量及回應時間,但應該注意多線程的編程限制,由於該Servlet始終駐於記憶體,所以響應是非常快的。4.雖然JSP效率很高,但在第一次調用時由於需要轉換和編譯而有一些輕微的延遲。在jspInit()中可以進行一些初始化工作,如建立與資料庫的串連、建立網路連接、從設定檔中擷取一些參數等,而在jspDestory()中釋放相應的資源。參考部落格:http://blog.csdn.net/fengdongkun/article/details/8159381http://www.cnblogs.com/mlloc-clove/p/3549777.html好了,JavaWeb–深入Servlet與JSP(運行原理)講完了。本部落格是我複習階段的一些筆記,拿來分享經驗給大家。歡迎在下面指出錯誤,共同學習!!你的點贊是對我最好的支援!!轉載:JackFrost的部落格

JavaWeb--深入Servlet與JSP(運行原理)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.