
簡介eWebEditor在線文本編輯器 v0.1.4 For JSP 是面向JSP開發(fā)者的富文本編輯組件主要解決網(wǎng)頁內(nèi)容錄入、排版與多媒體插入問題適合后臺管理、內(nèi)容發(fā)布等頁面集成可視化編輯能力。壓縮包共264個文件以186個gif界面素材、27個css樣式、21個htm示例頁為主輔以jsp、js、class、xml及jar等運行文件整體約796KB便于部署到現(xiàn)有JSP工程試用。已有173人學(xué)習(xí)說明其在傳統(tǒng)JSP項目中仍具參考價值。它提供字體字號、顏色、加粗斜體等格式化操作支持圖片上傳、多媒體鏈接、超鏈接與郵件鏈接并保留HTML源碼編輯入口呂海鵬修改版對性能與穩(wěn)定性有所優(yōu)化。通過API調(diào)整布局、擴展插件并處理XSS等安全問題適合理解老式JSP富文本編輯器集成與二次開發(fā)。1. 拿到 eWebEditor v0.1.4 For JSP 就先別急著解壓上個月幫人收拾一套老后臺需求只有一句新聞發(fā)布頁要能貼圖、能調(diào)字號。翻出來的是 eWebEditor在線文本編輯器 v0.1.4 For JSP 這個包ewebeditor014jsp.rar解壓出來一堆 jsp 文件。對方態(tài)度很輕松說扔進 Tomcat 就完事了結(jié)果訪問直接 404日志里干凈得像什么也沒發(fā)生。這套環(huán)境的坑就在這它不連數(shù)據(jù)庫、不需要編譯、配置散在幾個文件里任何一個路徑寫錯表現(xiàn)都是白屏或者 404特別容易讓人懷疑包本身是壞的。它適合還在維護 JSP 后臺、只想補一個輕量編輯入口的人如果你手上是前后端分離的項目硬塞進去會很別扭。2. 環(huán)境清單JDK、Tomcat 與 eWebEditor v0.1.4 的版本取舍2.1 JDK 先用 8別拿高版本硬頂老 JSP 組件第一道坎從來不是代碼寫得對不對而是運行時版本。eWebEditor v0.1.4 這個年代的包里面引用的還是javax.servlet.*這套命名空間很多輔助類也依賴 JDK 自帶的 XML、加密相關(guān) API。JDK 8 是最后一批把這些東西放在標(biāo)準(zhǔn)庫里的版本往上走就開始拆模塊常見的報錯是NoClassDefFoundError: javax/xml/bind/DatatypeConverter這種看著像包缺文件實際是運行時不給你了。我一般先確認(rèn)機器上裝了什么# 看當(dāng)前默認(rèn) JDK以及機器上還裝了哪些 java -version update-alternatives --list java 2/dev/null || ls /usr/lib/jvm第一條輸出里那行1.8.0_xxx就是我們要的。如果只有 11 或 17別急著卸裝一個 8 并存用update-alternatives --config java切過去就行。要注意 Tomcat 啟動腳本讀的是JAVA_HOME光切java命令不夠# 讓 Tomcat 明確用 JDK 8而不是跟著 shell 的默認(rèn)走 export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export JRE_HOME$JAVA_HOME/jre $CATALINA_HOME/bin/shutdown.sh $CATALINA_HOME/bin/startup.shJAVA_HOME指向 JDK 根目錄JRE_HOME指向它下面的 jre兩個都寫是為了兼容老版本的 catalina.sh有些發(fā)行版只認(rèn)JRE_HOME。改完別用service tomcat restart那個腳本未必繼承你當(dāng)前 shell 的環(huán)境變量直接用 Tomcat 自帶的 startup/shutdown 最穩(wěn)。還有一步值得做看看包里到底有沒有預(yù)編譯的 class。純 JSP 的包是沒有的有的話就要留意字節(jié)碼版本。# 解壓后統(tǒng)計 class 文件并看它們的字節(jié)碼主版本號 find ./ewebeditor -name *.class | wc -l find ./ewebeditor -name *.class -exec javap -verbose {} \; 2/dev/null \ | grep major version | sort -umajor version48 對應(yīng) JDK 1.449 是 550 是 651 是 752 是 8。如果輸出是 48 或 49JDK 8 跑起來沒問題高版本 JDK 也認(rèn)這些老字節(jié)碼所以字節(jié)碼本身很少是致命傷真正的雷是前面說的標(biāo)準(zhǔn)庫拆分和第三方 jar 缺失。這一步的價值在于當(dāng)你后面遇到UnsupportedClassVersionError能立刻判斷是版本不夠還是版本太高而不是盲目換 JDK 試。2.2 Tomcat 選 8.5 還是 9命名空間決定生死這一條幾乎每年都有人踩Tomcat 10 開始把javax.servlet整體換成了jakarta.servlet所有老 JSP 應(yīng)用的import全部失效部署上去就是一片 500。所以選型范圍很明確8.5 和 9 都能用10 及以上直接排除。兩者之間我偏向 8.5 的最后一個版本。原因不玄學(xué)8.5 對老 JSP 的容錯更好JSP 編譯器的默認(rèn)行為更接近這個包出生的年代而 9 在一些 EL 表達式和標(biāo)簽庫的解析上更嚴(yán)格老頁面里那種不規(guī)范的寫法容易被判死。當(dāng)然如果服務(wù)器上已經(jīng)有 9 在跑別的應(yīng)用也別為了它單獨降級先在 9 上試能起來就留著。判斷當(dāng)前 Tomcat 版本很簡單# 版本號在啟動腳本里不用啟動服務(wù)也能看 $CATALINA_HOME/bin/version.sh輸出里Server version和Servlet Spec兩行最關(guān)鍵Servlet 規(guī)范是 3.1 就說明是 8.5 或 9是 5.0/6.0 就是 10 以上那就得換。另外順手確認(rèn)conf/server.xml里沒有開啟allowLinking之類的特殊選項老應(yīng)用對這些很敏感。2.3 解壓前三件事編碼、目錄層級、只讀屬性rar 包在 Linux 上解壓最常見的翻車是文件名亂碼。這種包多半在 Windows 下用 GBK 打的包直接unrar x出來會看到一堆問號和方框JSP 文件名一旦變成亂碼Tomcat 就找不到入口頁表現(xiàn)同樣是 404。所以我一般不在 Linux 上直接解要么先用 7-Zip 在本地解開再傳上去要么解壓時把 locale 臨時指過去。# 先列目錄確認(rèn)壓縮包內(nèi)部的層級結(jié)構(gòu) unrar l ewebeditor014jsp.rar | head -40看輸出有幾個細節(jié)第一包內(nèi)是不是已經(jīng)有一層ewebeditor014jsp/頂層目錄如果有解壓后別再套一層同名目錄否則訪問路徑要多一級這是 404 的高發(fā)原因第二文件名里有沒有中文有的話優(yōu)先換平臺解壓第三注意有沒有.htaccess、Thumbs.db這類無關(guān)文件刪掉省得干擾。解壓本身# -o 覆蓋-x 后面可以跟排除規(guī)則這里先全解 mkdir -p /opt/apps cd /opt/apps unrar x -o /tmp/ewebeditor014jsp.rar-o表示無條件覆蓋同名文件重復(fù)解壓時不會卡在交互提示上。解壓完先ls -R | head -60掃一眼確認(rèn)入口 jsp、靜態(tài)資源目錄、上傳目錄都在再往下走。這個習(xí)慣救過我很多次包不完整的時候越早發(fā)現(xiàn)越省事。3. 部署落地把 eWebEditor 掛進 Tomcat 的完整步驟3.1 目錄歸位與權(quán)限預(yù)設(shè)部署位置只有兩種選擇塞進webapps讓 Tomcat 自動部署或者放在外部目錄用 Context 顯式掛載。前者省事后者便于升級和備份我個人傾向后者尤其這種老包哪天要換版本外部目錄換個軟鏈就行不用動 Tomcat 本體。# 統(tǒng)一放到 /opt/apps/ewebeditor屬主交給運行 Tomcat 的賬號 sudo mv /opt/apps/ewebeditor014jsp /opt/apps/ewebeditor sudo chown -R tomcat:tomcat /opt/apps/ewebeditor # 目錄 755、文件 644上傳目錄單獨放寬 sudo find /opt/apps/ewebeditor -type d -exec chmod 755 {} \; sudo find /opt/apps/ewebeditor -type f -exec chmod 644 {} \; sudo chmod 775 /opt/apps/ewebeditor/UploadFile 2/dev/null || true屬主必須和 Tomcat 進程的實際運行賬號一致很多人用 root 起 Tomcat那chown成 root 才對判斷方法是ps -ef | grep tomcat看第一列。權(quán)限給 777 是典型的圖省事做法能跑但不該做上傳目錄可執(zhí)行意味著別人傳個 jsp 上來就能被訪問到這是老編輯器最容易被盯上的地方后面 4.3 會給一個約束辦法。3.2 兩種 context 配置方式選一種就行外部目錄掛載的標(biāo)準(zhǔn)做法是在conf/Catalina/localhost/下建一個和應(yīng)用同名的 xml!-- 文件名必須是 ewebeditor.xml和訪問路徑保持一致 -- Context docBase/opt/apps/ewebeditor reloadablefalse crossContextfalse /docBase寫絕對路徑指向解壓后的根目錄reloadablefalse是刻意的老應(yīng)用的類加載器在熱重載時經(jīng)常出問題改配置就重啟別圖快。文件名ewebeditor.xml直接決定訪問前綴也就是http://ip:8080/ewebeditor/。另一種方式是把整個目錄拷進webapps/ewebeditorTomcat 啟動時自動掃描部署。這種方式的問題在于路徑和 Tomcat 安裝目錄綁死遷移機器要重新拷一遍而且webapps下東西多了以后啟動變慢。如果堅持用這種方式記得關(guān)掉自動部署的監(jiān)聽避免啟動時反復(fù)掃描!-- conf/server.xml 的 Host 節(jié)點里把 autoDeploy 關(guān)掉 -- Host namelocalhost appBasewebapps unpackWARstrue autoDeployfalse改完server.xml一定要重啟不是 reload。這一步之后如果訪問還是 404先看logs/catalina.out里有沒有Context [] startup failed有的話基本是docBase路徑寫錯或者目錄權(quán)限不對。3.3 入口頁與 web.xml 的注冊純 JSP 版本的 eWebEditor 通常不需要額外的 servlet 映射訪問入口 jsp 就能打開編輯頁面。但如果你拿到的包里有WEB-INF/web.xml里面可能已經(jīng)寫好了一些初始化參數(shù)這時候要做的是確認(rèn)它有沒有被正確讀取而不是另寫一份。!-- WEB-INF/web.xml 里通常只需要補一個歡迎頁讓根路徑能落到入口 -- web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee version3.1 display-nameewebeditor/display-name welcome-file-list welcome-fileewebeditor.jsp/welcome-file /welcome-file-list /web-appversion3.1對應(yīng) Servlet 3.1也就是 Tomcat 8.5/9 的規(guī)范寫高了容器可能拒絕加載。welcome-file里的文件名要和實際入口頁完全一致大小寫敏感Linux 上EWEBEDITOR.JSP和ewebeditor.jsp是兩個文件。改完 web.xml 之后重啟然后用 curl 探一下狀態(tài)碼比開瀏覽器快# 只看響應(yīng)頭確認(rèn) 200 還是 404/500 curl -I http://127.0.0.1:8080/ewebeditor/ewebeditor.jsp返回 200 說明路徑通了404 說明 context 沒起來或者文件名不對500 就要去logs/localhost.*.log里找堆棧了。這一步是分水嶺過了它剩下的都是配置細節(jié)。4. 配置參數(shù)上傳目錄、樣式與請求體大小4.1 上傳目錄的定位與寫入驗證老編輯器的上傳路徑經(jīng)常是寫死在配置里的相對路徑比如UploadFile相對于應(yīng)用根目錄。這意味著它跟著docBase走應(yīng)用搬到哪上傳文件就跟著到哪備份的時候別漏掉。先確認(rèn)配置里寫的是哪個目錄不同包的位置不一樣常見的是根目錄下一個配置文件或者入口 jsp 頂部的變量區(qū)。找到之后做一次寫入驗證不要等用戶上傳失敗才查# 用 Tomcat 的運行賬號試寫能寫才算配好 sudo -u tomcat touch /opt/apps/ewebeditor/UploadFile/.write_test sudo -u tomcat rm -f /opt/apps/ewebeditor/UploadFile/.write_test如果第二條命令報Permission denied說明前面的 chown 沒生效或者 SELinux 攔了。CentOS 系上還要看一眼上下文# 只讀排查用確認(rèn)目錄的安全上下文類型 ls -Zd /opt/apps/ewebeditor/UploadFile正常的應(yīng)該是httpd_sys_rw_content_t之類允許寫的類型如果是user_home_t那就是 SELinux 在攔用chcon -R -t httpd_sys_rw_content_t修一下別圖省事直接setenforce 0那等于把整臺機器的防護關(guān)了。4.2 請求體大小與連接器參數(shù)上傳失敗還有一種原因跟權(quán)限無關(guān)請求體超了 Tomcat 的默認(rèn)上限。老版本 Connector 上有maxPostSize默認(rèn) 2MB現(xiàn)在隨便一張手機照片就超。改在conf/server.xml的 Connector 節(jié)點Connector port8080 protocolHTTP/1.1 connectionTimeout20000 URIEncodingUTF-8 maxPostSize20971520 maxSwallowSize20971520 redirectPort8443 /maxPostSize是表單 POST 體的上限單位字節(jié)20971520 就是 20MBmaxSwallowSize控制的是超限之后容器還愿意吞掉多少數(shù)據(jù)不設(shè)的話客戶端可能收到連接重置而不是一個干凈的 413。URIEncodingUTF-8是給 GET 參數(shù)用的老包默認(rèn)可能按 ISO-8859-1 解中文標(biāo)題會變問號這一條改完能省掉后面一堆亂碼排查。順便把 JSP 頁面的編碼也對齊入口頁頂部那行page指令是關(guān)鍵% page contentTypetext/html; charsetUTF-8 pageEncodingUTF-8 %contentType管響應(yīng)頭pageEncoding管 JSP 源文件本身的讀取編碼兩個必須一致只改一個還是亂碼。如果源文件實際是 GBK 保存的你寫 UTF-8 會直接編譯報錯那就得先用編輯器轉(zhuǎn)碼再傳不要硬改指令。4.3 上傳目錄的訪問約束前面提過上傳目錄可執(zhí)行是這類編輯器的老毛病。約束辦法是在應(yīng)用的WEB-INF/web.xml里加一條安全約束禁止直接訪問上傳目錄下的腳本文件!-- 放在 web-app 節(jié)點內(nèi)禁止通過 URL 訪問上傳目錄里的 jsp -- security-constraint web-resource-collection web-resource-nameupload-script-deny/web-resource-name url-pattern/UploadFile/*.jsp/url-pattern url-pattern/UploadFile/*.jspx/url-pattern /web-resource-collection auth-constraint/ /security-constraint空的auth-constraint/表示不允許任何角色訪問效果是直接 403。注意url-pattern只匹配一層如果上傳目錄下面還有子目錄要么再補規(guī)則要么在應(yīng)用層限制上傳時的擴展名白名單。這條不是可選項尤其是這套環(huán)境掛在公網(wǎng)的時候。5. 避坑排查eWebEditor v0.1.4 部署里最常見的五個坑5.1 訪問 404日志里什么都沒有現(xiàn)象瀏覽器打開http://ip:8080/ewebeditor/返回 404catalina.out里看不到任何和應(yīng)用相關(guān)的記錄。原因九成是 context 根本沒加載??赡苁莄onf/Catalina/localhost/ewebeditor.xml文件名和訪問路徑不一致也可能是docBase指向的目錄里沒有入口頁Tomcat 加載了空 context 但不報錯。還有一種情況是包內(nèi)本身有一層同名目錄實際入口在/opt/apps/ewebeditor/ewebeditor014jsp/ewebeditor.jsp。解決先ls /opt/apps/ewebeditor確認(rèn)入口頁在不在第一層不在就把內(nèi)容上提一層。再確認(rèn) xml 文件名然后重啟看日志里有沒有Deploying context字樣。這一步用curl -I看狀態(tài)碼比開瀏覽器快得多。5.2 500 報 UnsupportedClassVersionError現(xiàn)象頁面直接 500日志里是java.lang.UnsupportedClassVersionError: xxx has been compiled by a more recent version of the Java Runtime。原因包里的 class 是用更高版本 JDK 編的而當(dāng)前運行時是 JDK 8?;蛘叻催^來包是老的但跑在 JDK 17 上報的是另一類NoClassDefFoundError。前者是版本不夠后者是標(biāo)準(zhǔn)庫被拆走。解決用 2.1 里的javap -verbose看主版本號52 就必須 JDK 8 以上48 就 JDK 8 足夠。確認(rèn)是標(biāo)準(zhǔn)庫缺失的把對應(yīng)模塊的 jar 補進WEB-INF/lib別去改 Tomcat 的啟動參數(shù)加--add-opens那是給新應(yīng)用用的老包補 jar 更直接。5.3 上傳圖片成功但回顯是紅叉現(xiàn)象點上傳提示成功磁盤上也能看到文件但編輯器里顯示不出來。原因編輯器回填的 URL 用的是絕對路徑或者寫死的 context 名應(yīng)用部署前綴一變就對不上。也可能是上傳目錄被前面的安全約束一刀切禁掉了圖片請求返回 403。解決F12 看那個紅叉請求的實際 URL如果多了或少了一級前綴改配置文件里的路徑拼接部分如果是 403把 4.3 的規(guī)則收窄到只禁腳本擴展名別把圖片一起禁了。5.4 中文文件名變亂碼或上傳后文件名是一串?dāng)?shù)字現(xiàn)象上傳中文名文件落到磁盤上變成%E4%B8%AD%E6%96%87.jpg或者一串時間戳。原因前者是請求編碼沒對齊URIEncoding和 JSP 的pageEncoding有一處沒改后者是編輯器本身的命名策略很多老版本默認(rèn)按時間戳重命名屬于正常行為不是故障。解決編碼問題按 4.2 里兩處一起改改完必須重啟。命名策略要看配置里有沒有「保留原文件名」的開關(guān)沒有的話就接受時間戳命名反而避免了中文文件名在跨平臺遷移時的麻煩。5.5 部署到 Tomcat 10 直接一片 500現(xiàn)象換到新服務(wù)器Tomcat 是 10 或 11應(yīng)用一起來所有頁面都 500日志里是java.lang.NoClassDefFoundError: javax/servlet/Servlet。原因Tomcat 10 起全面切到j(luò)akarta.servlet命名空間老包的 import 全部失效這不是配置能解決的。解決把 Tomcat 降到 9 或 8.5別試圖改源碼里的 import改一處會牽出一串。如果這臺機器上還有別的應(yīng)用必須用 Tomcat 10那就裝兩個 Tomcat 實例用不同端口各自跑各自的這是最省事的隔離方式。6. 驗證跑通從入口頁到一次真實保存配置改完不等于裝好我習(xí)慣走一條固定鏈路驗證每一步都能定位到具體環(huán)節(jié)。# 第一步入口頁狀態(tài)碼 curl -s -o /dev/null -w %{http_code}\n http://127.0.0.1:8080/ewebeditor/ewebeditor.jsp # 第二步靜態(tài)資源能不能取到路徑按實際 js 目錄調(diào)整 curl -s -o /dev/null -w %{http_code}\n http://127.0.0.1:8080/ewebeditor/js/ewebeditor.js # 第三步模擬一次上傳目錄可寫性檢查不經(jīng)過編輯器 sudo -u tomcat test -w /opt/apps/ewebeditor/UploadFile echo writable三條都通再去瀏覽器里做真實操作打開入口頁輸入一段帶中文的正文插一張圖保存然后回到列表頁看內(nèi)容有沒有完整回顯。中間任何一步卡住對照下面這張表定位驗證項期望結(jié)果失敗時優(yōu)先看入口頁狀態(tài)碼200context 配置、文件名大小寫靜態(tài)資源200 且 Content-Type 正確目錄權(quán)限、context 前綴上傳目錄可寫輸出 writable屬主、SELinux 上下文中文正文保存回顯不亂碼pageEncoding、URIEncoding圖片回顯請求返回 200安全約束、URL 拼接還有一個容易被忽略的點驗證要在重啟之后做。很多配置項是啟動時讀取的改完不重啟你驗證的其實是舊配置白忙一場。從那以后我每次部署這類老 JSP 包都強制走一遍「先確認(rèn) JDK、再看 Tomcat 命名空間、最后跑三條 curl」不管對方說得多輕松。老包不難裝難的是它出問題的時候不給線索把驗證做在前面比事后翻日志省太多時間。希望幫到你。本文還有配套的精品資源點擊獲取