Tomcat之Jasper

Jasper簡介

對於基於Jsp的web應用來說,我們可以直接在Jsp頁面中編寫Java代碼,添加第三方的標籤庫,以及使用EL表達式。但是無論經過何種形式的處理,最終輸出到客戶端的都是標準的HTML頁面(包含js,css..),並不包含任何的java相關的語法。也就是說,我們可以把Jsp看做是一種運行在服務端的腳本。那麼服務器是如何將Jsp頁面轉換爲HTML頁面的呢?

Jasper模塊是 Tomcat的Jsp核心引擎,我們知道jsp本質上是一個servlet。 Tomcat使用 jasper對Jsp語法進行解析,生成servlet並生成class字節碼,用戶在進行訪問jsp時,會訪問servlet,最終將訪問的結果直接響應在瀏覽器端。另外,在運行的時候, Jasper還會檢測Jsp文件是否修改,如果修改,則會重新編譯Jsp文件。

JSP編譯方式

運行時編譯

Tomcat並不會在啓動web應用的時候自動編譯jsp文件,而是在客戶端第一次請求時,才編譯需要訪問的jsp文件。

編譯過程

Tomcat在默認的web.xml中配置了一個org.apache.jasper.servlet.JspServlet,用於處理所有的.jsp或.jspx結尾的請求,該servlet實現的即是運行時編譯的入口。

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

 JspServlet處理流程圖:

編譯結果

  • 如果在tomcat/conf/web.xml中配置了參數scratchdir,則編譯後的結果,就會存儲在該目錄下。
<init-param>
    <param-name>scratchdir</param-name>
    <param-value>D:/tem/jsp/</param-name>
</init-param>
  •  如果沒有配置該選項,則會將編譯後的結果,存儲在tomcat安裝目錄下的work/Catalina/localhost/Context。假設項目名稱爲jsp_demo_01,默認的目錄爲:work/Catalina/localhost/jsp_demo_01
  • 如果使用的是idea開發工具集成tomcat訪問web工程中的jsp,編譯後的結果,存放在:
C:\Users\Administartor\.IntelliJIdea2019.1\system\tomcat\_project_tomcat\work\Catalina\localhost\jsp_demo_01_war_exploder\org\apache\jsp

預編譯

除了運行時編譯,我們還可以直接在web應用啓動時,一次性將web應用中的所有的Jsp頁面一次性編譯完成。在這種情況下,Web應用運行過程中,便可以不必再進行實時編譯,而是直接調用Jsp頁面對應的sexvlet完成請求處理,從而提升系統性能。

Tomcat提供了一個shell程序Jspc,用於支持Jsp預編譯,而且在 Tomcat的安裝目錄下提供了一個catalina- tasks.xml文件聲明瞭

Tomcat支持的Ant任務,因此,我們很容易使用ant來執行Jsp預編譯。(要想使用這種方式,必須得確保在此之前已經下載並安裝了

(Apache Ant)

JSP編譯原理

  • 其類名爲 index_jsp,繼承自org.apache.Jasper.runtime.HttpjspBase,該類是HttpServlet的子類,所以jsp本質就是一個servlet。
  • 通過屬性_ jspx_dependants保存了當前Jsp頁面依賴的資源,包含引入的外部的Jsp頁面、導入的標籤、標籤所在的jar包等,便於後續處理過程中使用(如重新編譯檢測,因此它以Map形式保存了每個資源的上次修改時間)。
  • 通過屬性_jsp_import_packages存放導入的java包,默認導入javax.servlet,javax.servlet.http,Javax.servletJsp
  • 通過屬性 _jspx_imports_classes存放導入的類,通過 import指令導入的 Dateformat、 SimpleDateFormat、Date都會包含在該集合中。 _jspx_imports_packages和 _jspx_imports_classes屬性主要用於配置EL引擎上下文。
  • 請求處理由方法_ JspService完成,而在父類HttpJspBase中的 service方法通過模板方法模式,調用了子類的_jspService方法
  • _jspService方法中定義了幾個重要的局部變量: page、context、 Session、application、 config、out、page。由於整個頁面的輸出有 Jspservice方法完成,因此這些變量和參數會對整個Jsp頁面生效。這也是我們爲什麼可以在JsP頁面使用這些變量的原因
  • 指定文檔類型的指令(page)最終轉換爲response.setContentType()方法調用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章