本文目录导读:

这是一个关于 JEditorPane、HTMLEditorKit 和 HTML 解析时出现未捕获异常的问题,这类问题通常与 Swing 的 HTML 渲染引擎在处理特定 HTML 内容时崩溃有关。
常见原因
- 无效的 HTML 结构 - 某些标签或属性不符合预期格式
- 特殊的 Unicode 字符 - 某些字符集无法被解析器正确处理
- 过大的 HTML 内容 - 超出解析器的处理能力
- 线程安全问题 - 在非 EDT(事件调度线程)上修改组件内容
- 已知的 JDK bug - 某些 Java 版本存在特定的 HTML 解析错误
解决方案
全局异常捕获
// 设置未捕获异常处理器
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("未捕获异常: " + throwable.getMessage());
throwable.printStackTrace();
// 可以在这里设置恢复逻辑
});
安全的 HTML 设置
// 使用 try-catch 包裹
try {
jEditorPane.setContentType("text/html");
jEditorPane.setText(htmlContent);
} catch (Exception e) {
System.err.println("HTML 设置失败: " + e.getMessage());
// 使用纯文本作为后备
jEditorPane.setContentType("text/plain");
jEditorPane.setText("无法显示 HTML 内容");
}
自定义 HTMLEditorKit
class SafeHTMLEditorKit extends HTMLEditorKit {
@Override
public Document createDefaultDocument() {
HTMLDocument doc = (HTMLDocument) super.createDefaultDocument();
doc.setAsynchronousLoadPriority(-1); // 禁用异步加载
return doc;
}
@Override
public ViewFactory getViewFactory() {
return new SafeViewFactory(super.getViewFactory());
}
}
// 使用自定义的 EditorKit
jEditorPane.setEditorKit(new SafeHTMLEditorKit());
预验证 HTML 内容
public static String sanitizeHTML(String html) {
if (html == null || html.isEmpty()) {
return "";
}
// 移除可能导致问题的元素
html = html.replaceAll("<!\\[CDATA\\[.*?\\]\\]>", "");
html = html.replaceAll("<script[^>]*>.*?</script>", "");
html = html.replaceAll("onerror|onclick|onload", "");
return html;
}
使用 SwingWorker 在后台处理
SwingWorker<Void, Void> worker = new SwingWorker<>() {
@Override
protected Void doInBackground() {
// 在后台线程中处理 HTML
return null;
}
@Override
protected void done() {
try {
get(); // 获取可能的异常
// 在 EDT 中更新 UI
jEditorPane.setText(processedHTML);
} catch (Exception e) {
System.err.println("HTML 处理异常: " + e.getMessage());
jEditorPane.setText("加载失败");
}
}
};
worker.execute();
完整的异常处理示例
import javax.swing.*;
import javax.swing.text.html.*;
import java.awt.*;
public class SafeHTMLEditor {
private JEditorPane editorPane;
public SafeHTMLEditor() {
editorPane = new JEditorPane();
editorPane.setEditable(false);
// 设置自定义异常处理器
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
if (throwable instanceof RuntimeException) {
// 尝试恢复
SwingUtilities.invokeLater(() -> {
editorPane.setText("<html><body>内容加载错误</body></html>");
});
}
});
}
public void setHTML(String html) {
SwingUtilities.invokeLater(() -> {
try {
String safeHTML = sanitizeHTML(html);
editorPane.setText(safeHTML);
editorPane.revalidate();
} catch (Exception e) {
System.err.println("HTML 设置失败: " + e.getMessage());
editorPane.setContentType("text/plain");
editorPane.setText("HTML 渲染失败");
}
});
}
private String sanitizeHTML(String html) {
// 实现 HTML 清理逻辑
return html;
}
}
调试建议
-
添加详细的日志记录
System.setProperty("sun.awt.exception.handler", "com.example.MyExceptionHandler"); -
使用 JVM 参数捕获更多信息
java -Xcheck:jni -Dswing.debug=true -jar yourapp.jar
-
检查 Java 版本,某些版本存在已知的 HTML 解析 bug
如果问题持续存在,考虑使用替代方案:
- JEditorPane 替代:
JTextPane或第三方 HTML 渲染器(如 Flying Saucer) - 使用 WebView(JavaFX)替代 Swing 组件
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播