本文目录导读:

这个错误是因为 JEditorPane 在使用 HTMLEditorKit 解析 HTML 时遇到了无法转换为数字的字符串,导致 NumberFormatException。
常见原因
-
HTML 中包含非标准或损坏的数值属性
<font size="large">或<table width="auto">
-
CSS 中使用非法数值
style="font-size:normal"或style="margin:auto"
-
HTML 版本不兼容
使用了 HTML 5 中新的或废弃的属性格式
-
特殊字符或编码问题
数字周围有不可见字符(如零宽度空格)
解决方法和示例代码
方法 1:使用自定义解析器覆盖数字解析(推荐)
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
public class SafeHTMLEditorKit extends HTMLEditorKit {
@Override
public ViewFactory getViewFactory() {
return new SafeHTMLFactory();
}
private static class SafeHTMLFactory extends HTMLFactory {
@Override
public View create(Element elem) {
// 这里可以添加自定义的视图处理逻辑
try {
return super.create(elem);
} catch (NumberFormatException e) {
// 记录错误并返回一个简单的视图
System.err.println("NumberFormatException while creating view for element: " + elem.getName());
return new InlineView(elem);
}
}
}
}
// 使用自定义的 EditoKit
JEditorPane editor = new JEditorPane();
editor.setEditorKit(new SafeHTMLEditorKit());
方法 2:预处理 HTML 内容(更简单)
public class HTMLPreprocessor {
public static String fixNumericAttributes(String html) {
// 修复常见的非数字属性值
html = html.replaceAll("size=\"[a-zA-Z]+\"", "size=\"3\""); // 默认字号
html = html.replaceAll("width=\"[a-zA-Z]+\"", "width=\"100%\"");
html = html.replaceAll("height=\"[a-zA-Z]+\"", "height=\"auto\"");
html = html.replaceAll("border=\"[a-zA-Z]+\"", "border=\"0\"");
html = html.replaceAll("cellpadding=\"[a-zA-Z]+\"", "cellpadding=\"0\"");
html = html.replaceAll("cellspacing=\"[a-zA-Z]+\"", "cellspacing=\"0\"");
// 修复 CSS 中的非数字值
html = html.replaceAll("font-size:\\s*[a-zA-Z]+", "font-size:14px");
html = html.replaceAll("margin:\\s*[a-zA-Z]+", "margin:0");
html = html.replaceAll("padding:\\s*[a-zA-Z]+", "padding:0");
return html;
}
}
// 使用预处理器
String dirtyHTML = "<font size='large'>Hello</font>";
String cleanHTML = HTMLPreprocessor.fixNumericAttributes(dirtyHTML);
JEditorPane editor = new JEditorPane();
editor.setContentType("text/html");
editor.setText(cleanHTML);
方法 3:完整的异常处理包装器
import javax.swing.*;
import javax.swing.text.html.*;
public class SafeHTMLViewer extends JEditorPane {
public SafeHTMLViewer() {
super();
setEditorKit(new SafeHTMLEditorKit());
}
@Override
public void setText(String t) {
try {
super.setText(t);
} catch (NumberFormatException e) {
// 记录详细错误信息
System.err.println("HTML parse error at position: " + getCaretPosition());
System.err.println("Error: " + e.getMessage());
// 尝试清理 HTML 后重新设置
String cleanedHTML = HTMLPreprocessor.fixNumericAttributes(t);
super.setText(cleanedHTML);
}
}
}
方法 4:使用 JLabel 代替(极简解决方案)
// HTML 非常简单,可以考虑使用 JLabel
JLabel label = new JLabel("<html><font size='5'>Simple Text</font></html>");
调试技巧
要找到具体哪个属性导致问题,可以添加调试信息:
import java.awt.Toolkit;
import java.awt.datatransfer.*;
public class DebugHTMLParser {
public static void debugParse(String html) {
// 逐行解析 HTML 检查
String[] lines = html.split("\n");
for (int i = 0; i < lines.length; i++) {
try {
JEditorPane temp = new JEditorPane();
temp.setContentType("text/html");
temp.setText(lines[i]);
} catch (NumberFormatException e) {
System.err.println("Problem line " + (i + 1) + ": " + lines[i]);
System.err.println("Error: " + e.getMessage());
}
}
}
}
最佳实践建议
-
始终保持 HTML 属性值符合规范 - 使用数值而不是关键词(如用
"3"而不是"medium") -
在使用前验证 HTML 内容 - 开发阶段使用单元测试检查 HTML
-
记录日志 - 在生产环境中记录异常以便后续排查
-
考虑使用更现代的组件 - 如果需要支持复杂 HTML,可以考虑 JavaFX 的 WebView 或第三方库
选择哪种解决方案取决于你的具体使用场景和 HTML 内容的复杂性,对于大多数简单的 HTML 显示需求,方法 2(预处理) 是最简单有效的。