You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免SAXBuilder验证文档类型DTD以解决离线时的UnknownHostException问题

如何避免SAXBuilder验证文档类型DTD以解决离线时的UnknownHostException问题

我太懂这个糟心的情况了!明明已经给SAXBuilder传了XMLReaders.NONVALIDATING,结果离线状态下还是会触发UnknownHostException——这是因为NONVALIDATING只是关闭了文档内容的合法性验证,但SAX解析器默认还是会尝试加载外部DTD来处理实体定义,哪怕你不需要验证内容。

给你两个比手动删DTD声明更优雅的解决方案:

方案一:通过EntityResolver拦截DTD加载请求

我们可以给SAXBuilder设置一个自定义的EntityResolver,当解析器尝试加载SVG对应的DTD时,直接返回一个空的输入源,彻底避免联网请求:

try {
    svgString = svgGraphics.getSVGDocument();
    SAXBuilder builder = new SAXBuilder(XMLReaders.NONVALIDATING);
    // 自定义EntityResolver拦截DTD加载
    builder.setEntityResolver((publicId, systemId) -> {
        // 匹配SVG的DTD地址,直接返回空输入源
        if (systemId != null && systemId.contains("w3.org/TR/SVG")) {
            return new InputSource(new StringReader(""));
        }
        // 其他外部资源按默认逻辑处理
        return null;
    });
    svgXMLDocument = builder.build(new ByteArrayInputStream(svgString.getBytes()));
} catch (IOException | JDOMException e) {
    // 异常处理逻辑
}

这个方法的好处是精准控制,只拦截SVG的DTD请求,不会影响其他正常的解析逻辑。

方案二:关闭SAX解析器的外部DTD加载特性

还有个更直接的方式:给SAXBuilder设置特定的XML特性,强制关闭非验证模式下的外部DTD加载:

try {
    svgString = svgGraphics.getSVGDocument();
    SAXBuilder builder = new SAXBuilder(XMLReaders.NONVALIDATING);
    // 关闭非验证模式下加载外部DTD的特性
    builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    svgXMLDocument = builder.build(new ByteArrayInputStream(svgString.getBytes()));
} catch (IOException | JDOMException e) {
    // 异常处理逻辑
}

这个特性是大部分Java环境默认使用的Apache Xerces解析器提供的,专门用来控制非验证模式下是否加载外部DTD,设置为false之后就彻底不会触发联网请求了。

这两个方案都比手动修改字符串删除DTD声明靠谱,不会因为SVG字符串格式变化(比如DTD声明的写法不一样)导致处理失败,代码也更健壮。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:05:30