OpenCms中所有的文件通常都保存在數據庫中,這也就是常說的OpenCms VFS(虛擬文件系統)。也就是說在OpenCms工作區中看到的文件結構在RFS(真實文件系統,也就是硬盤上)上並不存在(靜態導出操作除外),然而,為了JSP能夠正常工作,所有的OpenCms JSP文件都映射到真實文件系統中,也就是在硬盤上可以找到。
為了能夠理解這個過程,先讓我們看一下標准的JSP文件是怎麼被處理的:
JSP文件必須存放於Web應用程序的根目錄下;
JSP文件必須以“*.jsp”結尾(可以web.xml文件中進行配置);
servlet容器接受JSP文件的請求,被請求的文件首先被轉化成Java類源碼,擴展名為“.java”。
在這個處理過程中,JSP directives(如<%@ include file= "..." %>)也被轉化,轉換成Java源碼。
生成的“.java”源碼然後被編譯成實現Servlet接口的類。
最後,servlet調用service()方法。
為了使OpenCms能夠做到與servlet容器無關性,它使用了一個簡單的技巧:把JSP從虛擬文件系統映射到真實文件系統,如下:
所有的OpenCms資源請求都由OpenCms servlet控制,通常映射至/opencms/opencms;
一旦OpenCms接到一個JSP資源的請求,它就會把請求的JSP文件“存儲”到它自己的web應用程序根目錄下的“/WEB-INF/jsp/”下;
因為OpenCms中用online和offline區分一個資源的“發布”與“編輯”版本,所以在這個目錄(/WEB-INF/jsp/)下也生成online和offline兩個子目錄;
在這兩個目錄下,它把JSP文件存儲成帶有完整VFS路徑且以“.jsp”為後綴的文件;
例如:JSP文件是在VFS中是“/index.jsp”,它會被映射為真實文件系統中的“/WEB-INF/jsp/online/index.jsp.jsp”,這叫做“文件名轉換”的JSP。
當OpenCms存儲資源時,JSP directives(<%@ include file= "..." %>和 <%@ page errorPage= "..."%)所指向的JSP文件也同樣進行“文件名轉換”處理,即把它們映射到真實文件系統中;
假設我們在web應用目錄有一下文件叫作“file.jsp”;
OpenCms servlet調用requestDispatcher("{file.jsp}").include()並且把控制權傳遞到標准的servlet容器。剩下的步驟就和上面描述的標准的JSP處理一樣了。
如何區分online和offline JSP 版本?
其實很簡單:因為OpenCms為online和offline下的不同版本的JSP分別存儲到兩個目錄,這樣servlet容器就把它們當作不同的文件處理,也就做到了對offline下jsp的修改不會影響到online下的jsp。
注意:online和offline下的JSP有著同樣的web應用上下文,因為這一點,它們共用一個應用程序下下文對象,online和offline JSP頁面訪問的是同一組數據,不慎重使用會引起未預期的副作用,可以通過嚴格地控制訪問應用程序上下文對象來避免這些副作用。
在OpenCms靜態導出中如何使用JSP?
使用OpenCms靜態文件導出能夠提高網站的性能。OpenCms對JSP文件的管理也完全支持靜態導出。當然,JSP通常是使用在動態頁面中,因此,默認的生成的JSP文件的導出屬性默認為false,萬一想要導出JSP,必須要手動設置JSP的導出屬性為true。
為了支持到靜態導出資源的鏈接,OpenCms中使用了<cms:link>標簽或cms.link方法(<cms:link>用法)。
另外,JSP directives中包含有文件名時,不要使用類似“<jsp:directive.include file="..." />”的語法,而是要使用<%@ include file="..." %>的語法 ,因為OpenCms中不支持對類似“<jsp:directive.include file="..." />”的語法解析,也就是說不能處理這種語法中的JSP文件,不能夠把它映射到真實文件系統中。但對其它不包含文件名的這種語法是支持的,如: <jsp:useBean id="..." /> 或 <jsp:setProperty name="..." />,它們可以在OpenCms的JSP中正常使用。