本文目录导读:

这个错误信息看起来像是 JEditorPane 在使用 HTMLEditorKit 解析 HTML 时,内部调用了一个特定方法,但遇到了 “No Connection Pending”(无连接挂起) 的状态。
这通常是一个 底层网络连接或流读取异常 的标志,而不是一个标准的 Java Swing 异常,为了准确诊断,我需要你提供更具体的上下文:
- 异常堆栈跟踪: 完整的错误堆栈信息是什么?是哪一行代码触发的?
- 代码片段: 你是如何加载 HTML 内容的?(
setPage(url), 还是setText(htmlString)?) - HTML 来源: 这个 HTML 是来自网络 URL,还是从一个字符串、文件或数据库读取的?
基于常见的场景,以下是几种可能的原因和解决方案:
可能原因 1:HTML 内容包含外部资源引用,导致网络请求失败
JEditorPane 的 HTMLEditorKit 在解析 HTML 时,会尝试加载引用的外部资源(如图片 <img src="...">、样式表 <link href="..."> 或框架 <iframe src="...">)。
- HTML 来自字符串/本地: 但内容里包含了对网络 URL 的引用(
<img src="http://example.com/image.jpg">),JEditorPane 会尝试在后台建立网络连接来获取这张图片,如果网络不可用、URL 地址无效或连接被拒绝,就可能抛出与连接相关的异常(如NoConnectionPending)。 - 解决方法:
- 禁用图片加载: 使用
HTMLEditorKit的一个子类,重写getImage等方法,或者使用一个EmptyIcon来避免实际加载网络图片。 - 使用本地或打包的资源: 确保 HTML 中引用的所有资源(图片、CSS)都在本地可用,或者使用嵌入的 Base64 数据 URI。
- 设置自定义
ImageObserver: 但通常这只能跟踪加载状态,不能直接阻止异常。
- 禁用图片加载: 使用
可能原因 2:网络连接超时、中断或异常
如果你使用 editorPane.setPage(url) 加载一个网络上的 HTML 页面:
- 底层 HTTP 连接可能因为超时、网络断开、服务器无响应或 SSL 证书问题而失败。
HTMLEditorKit在解析时尝试从已连接的网络流中读取数据,但发现连接已经关闭或从未成功建立(即 “没有挂起的连接”)。 - 解决方法:
- 使用
URLConnection先下载 HTML 字符串: 不要直接用setPage(URL),先用URLConnection或HttpURLConnection下载完整的 HTML 内容到一个字符串,然后再用setText(htmlString)。 - 添加超时和重试机制: 在下载 HTML 字符串时,自己处理连接超时和重试。
- 检查 URL 和网络权限: 确保 URL 是可访问的,并且在 Java 安全策略中允许该网络连接(如果运行在受限环境中)。
- 使用
可能原因 3:非标准或损坏的 HTML 内容
HTMLEditorKit 使用的是老旧的 HTML 3.2 解析器,HTML 内容中包含现代标准(HTML5、JavaScript、复杂 CSS 语法)、损坏的标签或不闭合的标签,解析器可能会在内部陷入奇怪的状态,错误地将内容解释为需要网络连接的资源。
- 解决方法:
- 清理/预处理 HTML: 使用高级 HTML 清理库(如 Jsoup)先对 HTML 进行解析、清理和格式化,然后再传给
JEditorPane.setContentType("text/html")和JEditorPane.setText(cleanedHtml)。 - 避免
setPage: 从文件或网络读取时,始终先读取完整的字符串内容,然后设置文本。
- 清理/预处理 HTML: 使用高级 HTML 清理库(如 Jsoup)先对 HTML 进行解析、清理和格式化,然后再传给
可能原因 4:多线程或并发问题
如果你在非事件调度线程(非 EDT)上设置了 setPage 或 setText,或者同时有多个线程在操作同一个 JEditorPane 的文档模型,可能导致内部状态不一致,使得一个连接操作处于“无挂起”状态。
- 解决方法:
- 使用
SwingUtilities.invokeLater()或invokeAndWait()来确保所有 Swing 组件的修改都在 EDT 上执行。 - 避免重复调用
setPage或setText直到前一个调用完成。
- 使用
如何修复(推荐步骤)
-
更改加载方式(最推荐): 避免直接调用
setPage(URL),改为先手动下载 HTML 字符串。import java.net.URL; import java.net.HttpURLConnection; import java.io.BufferedReader; import java.io.InputStreamReader; public static String downloadHtml(String urlString) throws Exception { URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); // 5秒连接超时 conn.setReadTimeout(5000); // 5秒读取超时 conn.setRequestProperty("User-Agent", "Mozilla/5.0"); // 模拟浏览器 BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream(), "UTF-8")); String inputLine; StringBuilder content = new StringBuilder(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); content.append("\n"); } in.close(); conn.disconnect(); return content.toString(); } // 然后在 Swing EDT 中: SwingUtilities.invokeLater(() -> { try { String html = downloadHtml("http://example.com"); editorPane.setContentType("text/html"); editorPane.setText(html); // 可选:设置基础 URL 以支持相对路径,但风险已降低 // editorPane.getDocument().setProperty("base", new URL(url)); } catch (Exception e) { e.printStackTrace(); // 在这里你的异常就变成了常见的 IOException } }); -
HTML 来自字符串或文件且包含网络图片: 考虑剥离所有图片标签或替换为占位符。
String cleanedHtml = htmlString.replaceAll("<img[^>]*>", "<p>[图片已屏蔽]</p>"); editorPane.setText(cleanedHtml); -
提供完整堆栈: 如果以上方法不行,请提供完整的异常堆栈和代码片段,我可以给出更精确的定位。
“NoConnectionPending” 几乎 100% 与 网络连接有关,最直接的解决方法是放弃使用 JEditorPane 自带的网络加载能力,而是自己先下载完整的 HTML 文本(不带外部网络资源依赖),再通过 setText 来显示。