首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

HTTP Status 500 根因分析:JSP 頁面 StringIndexOutOfBoundsException 定位與修復

     編輯:程式設計綜合問答

Tomcat 運行 JSP 頁面拋出 HTTP Status 500,堆疊追蹤顯示 java.lang.StringIndexOutOfBoundsException: String index out of range: -1,發生在 FCKeditor.retrieveBrowserVersion 中。本文詳細解析異常堆疊、定位問題代碼行、修復方案與預防措施。

異常堆疊深度解讀


org.apache.jasper.JasperException: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:541)
    ...
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1938)
    at java.lang.String.substring(String.java:1905)
    at com.fredck.FCKeditor.FCKeditor.retrieveBrowserVersion(FCKeditor.java:263)  ← 關鍵行
    at com.fredck.FCKeditor.FCKeditor.isCompatible(FCKeditor.java:251)
    at com.fredck.FCKeditor.FCKeditor.create(FCKeditor.java:292)
    at com.fredck.FCKeditor.tags.FCKeditorTag.doAfterBody(FCKeditorTag.java:689)
    at org.apache.jsp.admin.news.edit_jsp._jspx_meth_FCK_005feditor_005f0(edit_jsp.java:322)  ← JSP 頁面行號
    ...

關鍵信息提取

根因代碼還原 (FCKeditor.java:263 邏輯推測)


// FCKeditor.retrieveBrowserVersion 典型邏輯
public String retrieveBrowserVersion(HttpServletRequest request) {
    String userAgent = request.getHeader("User-Agent");
    // 例如:尋找 "MSIE " 位置
    int msieIndex = userAgent.indexOf("MSIE ");  // 若非 IE 瀏覽器,返回 -1
    // 直接用 -1 作為 substring 起始索引 💥
    String version = userAgent.substring(msieIndex + 5);  // StringIndexOutOfBoundsException: -1
    return version;
}

核心缺陷:indexOf 未找到目標子串返回 -1,代碼未判斷直接用於 substring,導致越界。

修復方案

方案一:升級 CKEditor (根治)

FCKeditor 已停止維護超過 10 年,存在大量安全漏洞、瀏覽器兼容性問題。強烈建議遷移至 CKEditor 4/5 或 TinyMCE。

方案二:修補 FCKeditor 源碼 (臨時)

若必須繼續使用,需修改 FCKeditor.java 重新編譯打包:


// 修正 retrieveBrowserVersion
public String retrieveBrowserVersion(HttpServletRequest request) {
    String userAgent = request.getHeader("User-Agent");
    if (userAgent == null) return "Unknown";
    
    int msieIndex = userAgent.indexOf("MSIE ");
    if (msieIndex == -1) {
        // 非 IE 瀏覽器,嘗試其他標識
        if (userAgent.contains("Trident/")) return "IE11+"; // IE11 無 MSIE 標識
        if (userAgent.contains("Edge/")) return "Edge";
        if (userAgent.contains("Chrome/")) return "Chrome";
        if (userAgent.contains("Firefox/")) return "Firefox";
        if (userAgent.contains("Safari/")) return "Safari";
        return "Unknown";
    }
    // 找到 MSIE,安全提取版本號
    int start = msieIndex + 5;
    int end = userAgent.indexOf(";", start);
    if (end == -1) end = userAgent.length();
    return userAgent.substring(start, end).trim();
}

方案三:JSP 頁面繞過 (不改 Java 源碼)

在 edit.jsp 中添加瀏覽器檢查,僅在兼容瀏覽器下渲染編輯器:


<%@ page import="javax.servlet.http.HttpServletRequest" %>
<%
    String ua = request.getHeader("User-Agent");
    boolean compatible = ua != null && (ua.contains("MSIE") || ua.contains("Trident/") 
                          || ua.contains("Chrome") || ua.contains("Firefox") 
                          || ua.contains("Safari") || ua.contains("Edge"));
%>
<% if (compatible) { %>
    
<% } else { %>
    
    

您的瀏覽器不支持富文本編輯器,請使用 Chrome/Firefox/Edge

<% } %>

預防措施與最佳實踐

信息值含義
異常類型StringIndexOutOfBoundsException字符串索引越界,訪問負索引或超過長度
具體索引-1substring 參數為負數,通常是 indexOf 返回 -1 未檢查直接傳給 substring
觸發類com.fredck.FCKeditor.FCKeditorFCKeditor 編輯器組件 (舊版 CKEditor 前身)
觸發方法retrieveBrowserVersion解析 User-Agent 判斷瀏覽器版本兼容性
JSP 頁面admin/news/edit.jsp 第 322 行<FCK:editor ... /> 標籤位置
Tomcat 版本6.0.13極舊版本 (2007 年),建議升級
措施說明
升級編輯器組件FCKeditor → CKEditor 5 / TinyMCE 6,現代瀏覽器原生支持、安全維護
升級 Tomcat6.0.13 → 9.0.x / 10.1.x,安全漏洞修復、Servlet/JSP 規範更新
異常處理中間件配置 web.xml <error-page> 捕獲 500 錯誤頁面,避免暴露堆疊信息
輸入驗證習慣所有 indexOf/lastIndexOf 結果用於 substring 前必須判斷 != -1
日誌監控告警ELK/日誌服務監控 500 錯誤率,異常激增即時告警

總結

HTTP Status 500 配合 StringIndexOutOfBoundsException: -1,定位到 FCKeditor.retrieveBrowserVersion 中 indexOf 返回 -1 未檢查直接 substring。根因是舊版編輯器組件不兼容現代瀏覽器 User-Agent。徹底解決請升級編輯器組件,臨時可修補源碼或 JSP 層面繞過。同步升級 Tomcat 至維護版本,構建完整異常監控體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved