熟悉JAVA web開發的朋友都知道JSP會被轉換成java檔案(預編譯),然後編譯成class使用,即按照JSP-->java-->class的過程進行編譯。
由於JVM只認識class檔案,它不知道什麼是JSP,因此在tomcat中 如何把JSP解析成java檔案 就是本文所要描述的問題。
其他翻譯內容參考:Tomcat官方文件翻譯
如有錯誤,請予指正。
什麼是Jasper
Jasper是tomcat中使用的JSP引擎,在Tomcat 6中使用的是Jasper 2,相對於原來的版本作了不少的改進,比如:JSP的標籤緩衝池、後臺編譯、頁面改變時自動重新編譯、Eclipse中JDT編譯等等。
那麼Jasper到底是做什麼的呢?
簡單的說,就是把JVM不認識的JSP檔案解析成java檔案,然後編譯成class檔案提供使用。目前有很多的JSP解析引擎,Tomcat中使用的是Jasper。
在Tomcat中可以通過配置 CATALINA_HOME/conf/web.xml 中的內容,配置Jasper的選項(web.xml中的內容很長,擷取其中的一部分):
<!-- The JSP page compiler and execution servlet, which is the mechanism --> <!-- used by Tomcat to support JSP pages. Traditionally, this servlet --> <!-- is mapped to the URL pattern "*.jsp". This servlet supports the --> <!-- following initialization parameters (default values are in square --> <!-- brackets): --> <!-- --> <!-- checkInterval If development is false and checkInterval is --> <!-- greater than zero, background compilations are --> <!-- enabled. checkInterval is the time in seconds --> <!-- between checks to see if a JSP page (and its --> <!-- dependent files) needs to be recompiled. [0] --> <!-- --> <!-- classdebuginfo Should the class file be compiled with --> <!-- debugging information? [true] --> <!-- --> <!-- classpath What class path should I use while compiling --> <!-- generated servlets? [Created dynamically --> <!-- based on the current web application] --> <!-- --> <!-- compiler Which compiler Ant should use to compile JSP --> <!-- pages. See the jasper documentation for more --> <!-- information. --> <!-- --> <!-- compilerSourceVM Compiler source VM. [1.5] --> <!-- --> <!-- compilerTargetVM Compiler target VM. [1.5] --> <!-- --> <!-- development Is Jasper used in development mode? If true, --> <!-- the frequency at which JSPs are checked for --> <!-- modification may be specified via the --> <!-- modificationTestInterval parameter. [true] --> <!-- --> <!-- displaySourceFragment --> <!-- Should a source fragment be included in --> <!-- exception messages? [true] --> <!-- --> <!-- dumpSmap Should the SMAP info for JSR45 debugging be --> <!-- dumped to a file? [false] --> <!-- False if suppressSmap is true --> <!-- --> <!-- enablePooling Determines whether tag handler pooling is --> <!-- enabled. This is a compilation option. It will --> <!-- not alter the behaviour of JSPs that have --> <!-- already been compiled. [true] --> <!-- --> <!-- engineOptionsClass Allows specifying the Options class used to --> <!-- configure Jasper. If not present, the default --> <!-- EmbeddedServletOptions will be used. --> <!-- --> <!-- errorOnUseBeanInvalidClassAttribute --> <!-- Should Jasper issue an error when the value of --> <!-- the class attribute in an useBean action is --> <!-- not a valid bean class? [true] --> <!-- --> <!-- fork Tell Ant to fork compiles of JSP pages so that --> <!-- a separate JVM is used for JSP page compiles --> <!-- from the one Tomcat is running in. [true] --> <!-- --> <!-- genStringAsCharArray --> <!-- Should text strings be generated as char --> <!-- arrays, to improve performance in some cases? --> <!-- [false] --> <!-- --> <!-- ieClassId The class-id value to be sent to Internet --> <!-- Explorer when using <jsp:plugin> tags. --> <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] --> <!-- --> <!-- javaEncoding Java file encoding to use for generating java --> <!-- source files. [UTF8] --> <!-- --> <!-- keepgenerated Should we keep the generated Java source code --> <!-- for each page instead of deleting it? [true] --> <!-- --> <!-- mappedfile Should we generate static content with one --> <!-- print statement per input line, to ease --> <!-- debugging? [true] --> <!-- --> <!-- modificationTestInterval --> <!-- Causes a JSP (and its dependent files) to not --> <!-- be checked for modification during the --> <!-- specified time interval (in seconds) from the --> <!-- last time the JSP was checked for --> <!-- modification. A value of 0 will cause the JSP --> <!-- to be checked on every access. --> <!-- Used in development mode only. [4] --> <!-- --> <!-- recompileOnFail If a JSP compilation fails should the --> <!-- modificationTestInterval be ignored and the --> <!-- next access trigger a re-compilation attempt? --> <!-- Used in development mode only and is disabled --> <!-- by default as compilation may be expensive and --> <!-- could lead to excessive resource usage. --> <!-- [false] --> <!-- --> <!-- scratchdir What scratch directory should we use when --> <!-- compiling JSP pages? [default work directory --> <!-- for the current web application] --> <!-- --> <!-- suppressSmap Should the generation of SMAP info for JSR45 --> <!-- debugging be suppressed? [false] --> <!-- --> <!-- trimSpaces Should white spaces in template text between --> <!-- actions or directives be trimmed? [false] --> <!-- --> <!-- xpoweredBy Determines whether X-Powered-By response --> <!-- header is added by generated servlet [false] --> <!-- --> <!-- If you wish to use Jikes to compile JSP pages: --> <!-- Please see the "Using Jikes" section of the Jasper-HowTo --> <!-- page in the Tomcat documentation. --> <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>
具體的引數,上面都有解釋,這裡就不多贅述了。
都是些調節JSP編譯的引數,比如多長時間檢測一次,debug的除錯資訊相關配置,編譯資訊等等。
如何利用Japser.Jspc自定義預編譯JSP
1 jasper相關jar包
在tomcat6中提供了幾個jasper的jar包,相對於之前版本,去掉了jasper-compiler.jar以及jasper-runtime.jar,合併為jasper.jar
另外如果開發者自己想要編譯JSP,還需要使用ant以及tomcat-juli.jar。
2 ant相關jar包
其中ant相關的jar包可以去官網下載ant.zip,然後解壓提取其中lib內的jar包。
3 tomcat-juli相關jar包
tomcat-juli.jar位於CATALINA_HOME/bin/目錄下。
在Eclipse的構建路徑下新增上述相關的jar包即可,然後建立測試類:
新增JAR包步驟:右鍵工程-->Properties-->Java Build Path-->Libraries-->Add External JARs-->選擇新增的JAR包-->OK
package com.test; import org.apache.jasper.JspC; public class testCompiler{ public String jspcTest(){ String error=""; try { JspC jspc = new JspC(); //第一種方式 String[] arg0 = {"-uriroot", "F:/apache-tomcat-6.0.43/webapps/ROOT", "-d", "F:/test", "index.jsp" }; jspc.setArgs(arg0); //第二種方式 /*jspc.setUriroot("F:/apache-tomcat-6.0.43/webapps/ROOT");//web應用的root目錄 jspc.setOutputDir("F:/test");//.java檔案和.class檔案的輸出目錄 jspc.setJspFiles("index.jsp");//要編譯的jsp */ jspc.setCompile(true);//是否編譯 false或不指定的話只生成.java檔案 jspc.execute(); }catch(Exception e){ error=e.toString(); } return error; } public static void main(String args[]){ testCompiler t=new testCompiler(); System.out.println(t.jspcTest()); } }
可以使用兩種方式進行自定義的JSP編譯。
測試後,可以在 F:/test 目錄下發現編譯出的index.jsp的java檔案以及class檔案。
參考
【1】Jasper2 JSP引擎:http://tomcat.apache.org/tomcat-6.0-doc/jasper-howto.html
【2】解讀JSP解析過程:http://www.cnblogs.com/zollty/p/3309310.html
【3】使用Jspc編譯JSP檔案:http://kjah.iteye.com/blog/625588