OpenCms 將所有資源(含 JSP)存儲於數據庫(VFS),而非真實文件系統 (RFS)。但 Servlet 容器只能編譯磁盤上的 .jsp 文件。OpenCms 通過「映射」機制橋接兩者:
OpenCmsServlet (映射 /opencms/opencms/*)。/WEB-INF/jsp/ 下。online (發布版) 與 offline (編輯版) 兩個子目錄,實現版本隔離。/index.jsp → 磁盤 /WEB-INF/jsp/online/index.jsp.jsp(雙重 .jsp 後綴)。<%@ include file="..."%>, <%@ page errorPage="..."%>) 中的引用路徑,同樣進行映射轉換。requestDispatcher.include() 交給容器標準編譯執行。為避免同名衝突並保留 VFS 路徑信息,映射規則:
VFS_PATH + ".jsp" → DISK_PATH
例:/sub/page.jsp → /WEB-INF/jsp/online/sub/page.jsp.jsp
/WEB-INF/jsp/offline/...,修改即時生效,不影響線上用戶。application 域屬性互通,需謹慎使用。<%@ include file="..." %>、<%@ page errorPage="..." %> → 自動映射被引用文件。<jsp:directive.include file="..." /> (XML 語法),無法解析路徑 → 被引用文件不會被映射 → 運行時報錯。必須使用標準指令語法。jsp:useBean, jsp:setProperty 等) 無路徑引用,正常工作。false(動態頁不適合靜態化)。CmsResource.setExported(true)。<cms:link> 標籤或 cms.link() 方法,確保導出後路徑正確。<%@ include ... %> 替代 XML 指令語法。application 域,防止 online/offline 交叉污染;改用 OpenCms API (CmsFlexController, CmsJspStandardContextBean) 獲取上下文信息。/modules/myModule/jsp/),利用模塊部署實現版本管理與熱部署。/WEB-INF/jsp/online/ 下生成的 .java/.class 文件排查編譯錯誤;啟用 OpenCms 調試日誌 (org.opencms.jsp)。| 現象 | 原因 | 解決 |
|---|---|---|
| JSP 修改不生效 | 訪問的是 online 版本,編輯在 offline | 切換到編輯模式或執行發布 |
| include 文件找不到 | 使用了 <jsp:directive.include> | 改為 <%@ include file="..." %> |
| 類衝突 / NoClassDefFoundError | 模塊類加載器隔離 | 調整模塊依賴順序,或將共享 Jar 放入 WEB-INF/lib |
| 靜態導出後鏈接 404 | 未使用 <cms:link> | 替換所有硬編碼鏈接 |
OpenCms 通過 VFS→RFS 映射、Online/Offline 雙目錄、指令預解析,實現了 JSP 在 CMS 環境下的版本控制、工作流發布與靜態導出。開發者只需遵循「標準指令語法、謹慎用 application 域、善用 cms:link」三原則,即可順暢開發。