JEditorPaneHTMLEditorKitParserMethodIndexOutOfBounds索引越界

wen java案例 2

这个错误通常出现在使用 JEditorPaneHTMLEditorKit 解析 HTML 内容时,解析器遇到格式不正确的 HTML 或特殊字符导致的索引越界问题。

JEditorPaneHTMLEditorKitParserMethodIndexOutOfBounds索引越界

常见原因和解决方案

HTML 格式不完整或损坏

// 问题代码
String badHtml = "<html><body><p>Unclosed tag";
editorPane.setText(badHtml); // 可能触发 IndexOutOfBoundsException
// 解决方案:确保 HTML 格式完整
String goodHtml = "<html><body><p>Properly closed</p></body></html>";
editorPane.setText(goodHtml);

特殊字符或转义序列问题

// 问题:未转义的 & 字符
String html = "<html><body>AT&T</body></html>"; // & 需要转义
// 解决方案:使用 HTML 编码
String escaped = "<html><body>AT&amp;T</body></html>";

使用 Jsoup 预处理 HTML

最可靠的解决方案是使用 Jsoup 库先清理 HTML:

import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;
public class SafeHtmlEditor {
    private JEditorPane editorPane;
    public void setSafeHtml(String html) {
        // 使用 Jsoup 清理和标准化 HTML
        String safeHtml = Jsoup.clean(html, Safelist.basic());
        // 确保有完整的 HTML 结构
        safeHtml = "<html><body>" + safeHtml + "</body></html>";
        editorPane.setText(safeHtml);
    }
}

自定义异常处理

editorPane.addPropertyChangeListener("page", evt -> {
    try {
        // 尝试设置文本
        editorPane.setText(htmlContent);
    } catch (IndexOutOfBoundsException e) {
        System.err.println("HTML 解析异常: " + e.getMessage());
        // 降级处理 - 显示纯文本
        editorPane.setContentType("text/plain");
        editorPane.setText(stripHtml(htmlContent));
    }
});
// HTML 转纯文本方法
private String stripHtml(String html) {
    return html.replaceAll("<[^>]*>", "")
               .replaceAll("&amp;", "&")
               .replaceAll("&lt;", "<")
               .replaceAll("&gt;", ">");
}

完整的解决方案示例

import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;
public class SafeHtmlViewer extends JFrame {
    private JEditorPane editorPane;
    public SafeHtmlViewer() {
        editorPane = new JEditorPane();
        editorPane.setEditorKit(new HTMLEditorKit());
        editorPane.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(editorPane);
        add(scrollPane);
        setSize(600, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public void displayHtml(String rawHtml) {
        SwingWorker<Void, Void> worker = new SwingWorker<>() {
            @Override
            protected Void doInBackground() {
                String cleanHtml = preprocessHtml(rawHtml);
                SwingUtilities.invokeLater(() -> {
                    try {
                        editorPane.setText(cleanHtml);
                    } catch (Exception e) {
                        // 最后降级方案
                        editorPane.setContentType("text/plain");
                        editorPane.setText(extractText(rawHtml));
                    }
                });
                return null;
            }
        };
        worker.execute();
    }
    private String preprocessHtml(String html) {
        if (html == null || html.isEmpty()) {
            return "<html><body></body></html>";
        }
        // 第一步:使用 Jsoup 清理
        String cleaned = Jsoup.clean(html, Safelist.basic());
        // 第二步:确保基础结构
        if (!cleaned.toLowerCase().startsWith("<html")) {
            cleaned = "<html><body>" + cleaned + "</body></html>";
        }
        return cleaned;
    }
    private String extractText(String html) {
        return Jsoup.parse(html).text();
    }
}

添加依赖

如果使用 Maven,添加 Jsoup 依赖:

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.17.2</version>
</dependency>

建议的排查步骤:

  1. 先确认 HTML 内容格式是否正确
  2. 使用 Jsoup 进行预处理
  3. 捕获异常并优雅降级
  4. 考虑使用纯文本作为后备方案

如果问题持续存在,可能需要检查具体的 HTML 内容,看看是否有特定的标签或字符导致了解析器崩溃。

抱歉,评论功能暂时关闭!