JEditorPaneHTMLEditorKitParserMethodNoConnectionPending无连接

wen java案例 2

本文目录导读:

JEditorPaneHTMLEditorKitParserMethodNoConnectionPending无连接

  1. 可能原因 1:HTML 内容包含外部资源引用,导致网络请求失败
  2. 可能原因 2:网络连接超时、中断或异常
  3. 可能原因 3:非标准或损坏的 HTML 内容
  4. 可能原因 4:多线程或并发问题
  5. 如何修复(推荐步骤)

这个错误信息看起来像是 JEditorPane 在使用 HTMLEditorKit 解析 HTML 时,内部调用了一个特定方法,但遇到了 “No Connection Pending”(无连接挂起) 的状态。

这通常是一个 底层网络连接或流读取异常 的标志,而不是一个标准的 Java Swing 异常,为了准确诊断,我需要你提供更具体的上下文:

  1. 异常堆栈跟踪: 完整的错误堆栈信息是什么?是哪一行代码触发的?
  2. 代码片段: 你是如何加载 HTML 内容的?(setPage(url), 还是 setText(htmlString)?)
  3. 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),先用 URLConnectionHttpURLConnection 下载完整的 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 从文件或网络读取时,始终先读取完整的字符串内容,然后设置文本。

可能原因 4:多线程或并发问题

如果你在非事件调度线程(非 EDT)上设置了 setPagesetText,或者同时有多个线程在操作同一个 JEditorPane 的文档模型,可能导致内部状态不一致,使得一个连接操作处于“无挂起”状态。

  • 解决方法:
    • 使用 SwingUtilities.invokeLater()invokeAndWait() 来确保所有 Swing 组件的修改都在 EDT 上执行。
    • 避免重复调用 setPagesetText 直到前一个调用完成。

如何修复(推荐步骤)

  1. 更改加载方式(最推荐): 避免直接调用 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
        }
    });
  2. HTML 来自字符串或文件且包含网络图片: 考虑剥离所有图片标签或替换为占位符。

    String cleanedHtml = htmlString.replaceAll("<img[^>]*>", "<p>[图片已屏蔽]</p>");
    editorPane.setText(cleanedHtml);
  3. 提供完整堆栈: 如果以上方法不行,请提供完整的异常堆栈和代码片段,我可以给出更精确的定位。

“NoConnectionPending” 几乎 100% 与 网络连接有关,最直接的解决方法是放弃使用 JEditorPane 自带的网络加载能力,而是自己先下载完整的 HTML 文本(不带外部网络资源依赖),再通过 setText 来显示。

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