今天才知道另一項好處,保護 Source code,也就是說不只 Java 檔,連 JSP 都可以只交付 class 檔,不用交付原始檔,雖然這需求不常見。
JSP Precompile 不是只有將 JSP 轉成 Java,再編譯成 class 檔就好,還得在 web.xml 加上 JSP 所產生的 Servlet 檔宣告,並加上對應的 url-pattern。
直接看程式。
<servlet> <servlet-name>jsp.WEB_002dINF.views.banner_jsp</servlet-name> <servlet-class>jsp.WEB_002dINF.views.banner_jsp</servlet-class> </servlet> <servlet-mapping> <servlet-name>jsp.WEB_002dINF.views.banner_jsp</servlet-name> <url-pattern>/WEB-INF/views/banner.jsp</url-pattern> </servlet-mapping>/WEB-INF/views/banner.jsp 先轉檔成 Java Servlet,然後編譯成 class 檔,也就是 jsp.WEB_002dINF.views.banner_jsp,為了能存取,所以得在 web.xml 加上 <servlet> 與 <servlet-mapping>,這樣才能從原來的 jsp 路徑找到產生的 Java Servlet。
因此,JSP Precompile 有兩件事要做:
- 將 JSP 轉成 Java Servlet,再編譯
- 登錄到 web.xml
會很麻煩嗎?一點也不會!
問過 Google 之後,Maven 有 plugin 可以辦到,雖然久未更新,但是還可以在 Maven 3 的環境使用。
<plugin> <groupId>org.codehaus.mojo.jspc</groupId> <artifactId>jspc-maven-plugin</artifactId> <version>2.0-alpha-3</version> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> <!-- Use the Tomcat 6 JSP compiler --> <dependencies> <dependency> <groupId>org.codehaus.mojo.jspc</groupId> <artifactId>jspc-compiler-tomcat6</artifactId> <version>2.0-alpha-3</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <webXml>${pom.basedir}/target/jspweb.xml</webXml> <warSourceExcludes>**/*.jsp</warSourceExcludes> </configuration> </plugin>只要在 pom.xml 加上這兩個 plugin 就可以用 mvn package 輕輕鬆鬆產生一個水水的 war 檔,不只 jsp 編譯成 class 放到 classes 裡,連 web.xml 都改好了。
雖然 M2Eclipse 對第一個 plugin 設定有意見,但還是可以執行。
不過事情總是不會那麼美好,JSP 要能 Precompile 有個前提,就是 include 這件事,被 included 的 jsp 檔不能用到 including jsp 的變數,也就是說每一隻 JSP 都要能獨立存在,不能依賴其他 JSP 的變數,否則就會編譯不過,畢竟每一隻 JSP 都是獨立編譯的,基本上只要沒用到 Scriptlet 大抵都不會出錯。
編譯過程中還發生一個有趣的事情,發生錯誤說找不到 JSTL,一開始還以為版本問題,後來才發現是 Maven Dependency 設定的問題。
[ERROR] The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application -> [Help 1] org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:51) at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409) at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:116) at org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:315) at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:148) at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:431) at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:494) at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1444) at org.apache.jasper.compiler.Parser.parse(Parser.java:138) at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:216) at org.apache.jasper.compiler.ParserController.parse(ParserController.java:103) at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:154) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:315) ...JSTL 因為只有在執行時才會用到,所以 scope 設為 runtime,導致編譯 JSP 時找不到,只要將 scope 拿掉用預設值或者明定為 compile 就可以了。
---
---
---
沒有留言:
張貼留言