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

常见原因和解决方案
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&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("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">");
}
完整的解决方案示例
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>
建议的排查步骤:
- 先确认 HTML 内容格式是否正确
- 使用 Jsoup 进行预处理
- 捕获异常并优雅降级
- 考虑使用纯文本作为后备方案
如果问题持续存在,可能需要检查具体的 HTML 内容,看看是否有特定的标签或字符导致了解析器崩溃。