Tomcat 8.0 使用 Jasper 2 JSP 引擎去實(shí)現(xiàn) JavaServer Pages 2.3 規(guī)范。
Jasper 2 經(jīng)過了重新設(shè)計(jì),極大改善了上一版 Jasper 的性能。除了一般性的代碼改進(jìn)之外,還做出了以下改變:
Jasper 默認(rèn)就是用于開發(fā) Web 應(yīng)用的。關(guān)于如何在 Tomcat 生產(chǎn)服務(wù)器中配置并使用 Jasper,可參考生產(chǎn)環(huán)境配置一節(jié)內(nèi)容。
在全局性的 $CATALINA_BASE/conf/web.xml 中使用如下初始參數(shù),來配置實(shí)現(xiàn) Jasper 的 servlet。
checkInterval 如果 development 為 false,并且checkInterval 大于 0,則開啟后臺(tái)編譯。checkInterval 參數(shù)的含義就是在檢查某個(gè) JSP 頁面(以及從屬文件)是否需要重新編譯時(shí),幾次檢查的間隔時(shí)間(以秒計(jì))。默認(rèn)為 0 秒。
Eclipse JDT 的 Java 編譯器被指定為默認(rèn)的編譯器。它非常先進(jìn),能夠從 Tomcat 類加載器中加載所有的依賴關(guān)系。這將非常有助于編譯帶有幾十個(gè) JAR 文件的大型安裝。在較快的服務(wù)器上,還可能實(shí)現(xiàn)以次秒級(jí)周期對(duì)大型 JSP 頁面進(jìn)行重新編譯。
通過配置上述編譯器屬性,之前版本 Tomcat 所用的 Apache Ant 可以替代新的編譯器。
bug 39089報(bào)告指出,在編譯非常大的 JSP 時(shí),已知的 JVM 問題 bug 6294277 可能會(huì)導(dǎo)致出現(xiàn) java.lang.InternalError: name is too long to represent 異常。如果出現(xiàn)這一問題,可以采用下列辦法來解決:
能做的最重要的 JSP 優(yōu)化就是對(duì) JSP 進(jìn)行預(yù)編譯。但這通常不太可能(比如說,使用 jsp-property-group 功能時(shí))或者說不太實(shí)際,這種情況下,如何配置Jasper Servlet 就變得很關(guān)鍵了。
在生產(chǎn)級(jí) Tomcat 服務(wù)器上使用 Jasper 2 時(shí),應(yīng)該考慮將默認(rèn)配置進(jìn)行如下這番修改:
使用 Ant 是利用 JSPC 編譯 Web 應(yīng)用的首選方式。注意在預(yù)編譯 JSP 頁面時(shí),如果 suppressSmap 為 false,而 compile 為 true,則 SMAP 信息只能包含在最后的類中。使用下面的腳本來預(yù)編譯 Web 應(yīng)用(在 deployer 下載中也包含類似的腳本)。
<project name="Webapp Precompilation" default="all" basedir=".">
<import file="${tomcat.home}/bin/catalina-tasks.xml"/>
<target name="jspc">
<jasper
validateXml="false"
uriroot="${webapp.path}"
webXmlFragment="${webapp.path}/WEB-INF/generated_web.xml"
outputDir="${webapp.path}/WEB-INF/src" />
</target>
<target name="compile">
<mkdir dir="${webapp.path}/WEB-INF/classes"/>
<mkdir dir="${webapp.path}/WEB-INF/lib"/>
<javac destdir="${webapp.path}/WEB-INF/classes"
optimize="off"
debug="on" failonerror="false"
srcdir="${webapp.path}/WEB-INF/src"
excludes="**/*.smap">
<classpath>
<pathelement location="${webapp.path}/WEB-INF/classes"/>
<fileset dir="${webapp.path}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
<pathelement location="${tomcat.home}/lib"/>
<fileset dir="${tomcat.home}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${tomcat.home}/bin">
<include name="*.jar"/>
</fileset>
</classpath>
<include name="**" />
<exclude name="tags/**" />
</javac>
</target>
<target name="all" depends="jspc,compile">
</target>
<target name="cleanup">
<delete>
<fileset dir="${webapp.path}/WEB-INF/src"/>
<fileset dir="${webapp.path}/WEB-INF/classes/org/apache/jsp"/>
</delete>
</target>
</project>
下面的代碼可以用來運(yùn)行該腳本(利用 Tomcat 基本路徑與指向應(yīng)被預(yù)編譯 Web 應(yīng)用的路徑來取代令牌)
$ANT_HOME/bin/ant -Dtomcat.home=<$TOMCAT_HOME> -Dwebapp.path=<$WEBAPP_PATH>
然后,必須在 Web 應(yīng)用部署描述符文件中添加預(yù)編譯過程中生成的 servlet 的聲明與映射。將 ${webapp.path}/WEB-INF/generated_web.xml 插入 ${webapp.path}/WEB-INF/web.xml 文件中合適的位置。使用 Manager 重啟 Web 應(yīng)用,測(cè)試應(yīng)用,以便驗(yàn)證應(yīng)用能正常使用預(yù)編譯 servlet。利用Web 應(yīng)用部署描述符文件中的一個(gè)適當(dāng)?shù)牧钆?,也能使?Ant 過濾功能自動(dòng)插入生成的 servlet 聲明與映射。這實(shí)際上就是 Tomcat 所分配的所有 Web 應(yīng)用能作為構(gòu)建進(jìn)程中的一部分而自動(dòng)編譯的原理。
在 Jasper 任務(wù)中,還可以使用選項(xiàng) addWebXmlMappings,它可以將 ${webapp.path}/WEB-INF/web.xml 中的當(dāng)前 Web 應(yīng)用部署描述符文件自動(dòng)與 ${webapp.path}/WEB-INF/generated_web.xml 進(jìn)行合并。當(dāng)你想在 JSP 頁面中使用 Java 6 功能時(shí),添加下列 javac 編譯器任務(wù)屬性:source="1.6" target="1.6"。對(duì)于動(dòng)態(tài)應(yīng)用而言,還可以使用 optimize="on" 進(jìn)行編譯,注意,不用帶調(diào)試信息:debug="off"。
當(dāng)首次出現(xiàn) jsp 語法錯(cuò)誤時(shí),假如你不想停止 jsp 生成,可以使用 failOnError="false" 和 showSuccess="true",將所有成功生成的 jsp to java 打印出來。這種做法有時(shí)非常有用,比如當(dāng)你想要在 ${webapp.path}/WEB-INF/src 中清除生成的 java 源文件以及 ${webapp.path}/WEB-INF/classes/org/apache/jsp 中的編譯 jsp 的 servlet 類時(shí)。
提示:
Jasper 還提供了很多擴(kuò)展點(diǎn),能讓用戶針對(duì)具體的環(huán)境而優(yōu)化行為。
標(biāo)簽插件機(jī)制就是首先要談到的一個(gè)擴(kuò)展點(diǎn)。對(duì)于提供給 Web 應(yīng)用使用的標(biāo)簽處理器而言,它能提供多種替代實(shí)現(xiàn)。標(biāo)簽插件 通過位于 WEB-INF 的 tagPlugins.xml 進(jìn)行注冊(cè)。Jasper 本身還包含了一個(gè) JSTL 的范例插件。
表達(dá)式語言(EL,Expression Language)解釋器則是另外一個(gè)擴(kuò)展點(diǎn)。通過 ServletContext 可以配置替代的 EL 解釋器??梢詤⒖?ELInterpreterFactory Java 文檔來了解如何配置替代的 EL 解釋器。