jsp運行機制


一、JSP機制概述

可以把執行JSP頁面的執行分成兩個階段,一個是轉譯階段,一個是請求階段。
轉譯階段:JSP頁面轉換成Servlet類。
請求階段:Servlet類執行,將響應結果發送至客戶端。

1.用戶(客戶機)訪問響應的JSP頁面,如http://localhost:8080/Prj_test/ch02/HelloJSP.jsp
2.服務器找到相應的JSP頁面。
3.服務器將JSP轉譯成Servlet的源代碼。
4.服務器將Servlet源代碼編譯為class文件。
5.服務器將class文件加載到內存並執行。
6.服務器講class文件執行后生成HTML代碼發送給客戶機,客戶機瀏覽器根據響應的HTML代碼進行顯示。
如果該JSP頁面為第一次執行,那么會經過這兩個階段,而如果不是第一次執行,那么將只會執行請求階段。這也是為什么第二次執行JSP頁面時明顯比第一次執行要要快的原因。
如果修改了JSP頁面,那么服務器將發現到該修改,並重新執行轉譯階段和請求階段。這也是為什么修改頁面后訪問速度變慢的原因。

 
jsp執行過程流程圖: 


1、jsp引擎
JSP引擎實際上要把JSP標簽、JSP頁中的Java代碼甚至連同靜態HTML內容都轉換為大塊的Java代碼。這些代碼塊被JSP引擎組織到用戶看不到的Java servlet中去,然后servlet自動把JVM(java虛擬機)編譯成Java字節碼。這樣,當網站的訪問者請求一個JSP頁時,在他不知道的情況下,一個已經生成的、預編譯過的servlet實際上將完成所有的工作。非常隱蔽-而又高效。因為servlet是編譯過的,所以網頁中的JSP代碼不需要在每次請求該頁時被解釋一遍。JSP引擎只需在servlet代碼最后被修改后編譯一次,然后這個編譯過的servlet就可以被執行了。由於是JSP引擎自動生成並編譯servlet,不用程序員動手編譯代碼,所以JSP能帶給你高效的性能和快速開發所需的靈活性。
2、web容器和servlet容器
servlet容器的主要任務是管理servlet的生命周期。web容器更准確的說應該叫web服務器,它是來管理和部署web應用的。還有一種服務器叫做應用服務器,它的功能比web服務器要強大的多,因為它可以部署EJB應用,可以實現容器管理的事務,一般的應用服務器有weblogic和websphere等,它們都是商業服務器,功能強大但都是收費的。web容器最典型的就是tomcat了,Tomcat是web容器也是servlet容器

2、jsp工作原理當web容器(tomcat、jboss等等)接收到用戶的第一個jsp頁面請求時,jsp引擎將這個jsp頁面轉換為java源代碼(servlet類),在轉換過程中,如果發現jsp文件有任何的語法錯誤,轉換過程將終止,並向服務器和客戶端輸出錯誤信息,如果轉換成功,然后jsp引擎用javac編譯java源代碼生成class文件,然后web容器加載class文件並從此創建一個新的servlet對象進行實例化,當 Servlet 類實例化后,容器加載 jsinit,以通知 servlet 它已進入服務行列。init 方法必須被加載,Servelt 才能接收和請求。假如要載入數據庫驅動程序、初始化一些值等等,程序員可以重寫這個方法。在其他情況下,這個方法一般為空,jspInit()方法在servlet的生命周期中只被執行一次。然后jspService()方法被調用來處理客戶端的請求。容器創建一個響應文檔,次文檔發送給用戶,如干時間后,用戶再次訪問這個j請求這個jsp時,容器回再次創建響應一個文檔,直到容器卸載了這個class文件,當用戶卸載了這個class文件后,再次訪問時,jsp引擎並不重新轉換和編譯這個jsp文件,而是對它進行重新初始化,並創建一個響應文檔,返回給客戶端。對每一個請求,web容器創建一個新的線程來處理該請求。如果有多個客戶端同時請求該JSP文件,則JSP引擎會創建多個線程。每個客戶端請求對應一個線程。以多線程方式執行可大大降低對系統的資源需求,提高系統的並發量及響應時間.但應該注意多線程的編程限制,由於該servlet始終駐於內存,所以響應是非常快的。如果.jsp文件被修改了,服務器將根據設置決定是否對該文件重新編譯,如果需要重新編譯,則將編譯結果取代內存中的servlet,並繼續上述處理過程。如果在任何時候如果由於系統資源不足的原因,web容器將以某種不確定的方式將servlet從內存中移去。當這種情況發生時jspDestroy()方法首先被調用, 然后servlet實例便被標記加入"垃圾收集"處理。

3、jsp腳本與聲明的差異
Jsp代碼 復制代碼 收藏代碼
  1. <%!int count=100;%>--------jsp聲明   
  2. <%int count=100;%>---------jsp腳本  
<%!int count=100;%>--------jsp聲明
<%int count=100;%>---------jsp腳本

二者的差異在於作用域和生存期,
(1)、jsp聲明中創建的名字有類范圍的作用域和生存期
(2)、jsp腳本中創建的名字有局限於方法的作用域和生存期。
二者的作用域就像是java中在類中定義一個屬性A和在類的方法中定義一個屬性B,
類中不能引用屬性B,但是在方法中可以引用屬性A,
二者的生存期:
jsp聲明,例如:<%!int count=100;%><%=count++%>
腳本中的變量生存期存在於第一個用戶延續到第二個用戶。。。。,如果第一個用戶第一次訪問時100,第二個用戶訪問就101,第三個用戶訪問時102,以此類推。。。如果服務器停止而重新啟動后,則count值就返回到100,
jsp腳本,例如:<%int count=100;%><%=count++%>
腳本中的變量生存期存在於每個用戶的訪問期間,所以沒有用戶訪問都是100

無論聲明和腳本放置的位置不同,jsp容器都是首先進行初始化聲明,再執行腳本的。
總結:
(1)、不能在腳本中定義方法,但可以再jsp聲明中定義自己的方法,因為腳本程序是局限於jspService方法中的,如果在jspservice方法中再次定義方法是不允許的。
(2)、不能在jso聲明中使用out等隱藏對象,因為out等隱藏對象,是作用域jspservice方法中定義的。
(3)、腳本中定義變量,不能在jsp聲明中引用此變量。
(4)、如果變量定義在方法中,則不能在方法之前使用此變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM