博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XML 解析 连接超时
阅读量:6119 次
发布时间:2019-06-21

本文共 2449 字,大约阅读时间需要 8 分钟。

hot3.png

本文转载自:

    

说在前面

    读取XML的时候,很多人总是不明白为什么会连接超时,XML解析怎么还会访问网络,其实在XML解析之前,如果XML指定了DTD文件,那么Java会根据DTD文件的路径去本地寻找或远程下载,下载的时候就会出现连接超时!所以想要避免连接超时这个问题,就可以采用避免DTD下载,下面通过两种方式避免DTD下载,本人亲测,确实是一篇好文章,谢谢作者!

    

下面是正文:

Java程序在解析xml文件时,如果xml文件中指定了dtd,在默认会从指定的url下载dtd文件,但是很多情况下如果网络连接不上,或者防火墙原因,dtd文件无法下载下来导致程序报连接超时异常,解析xml失败。有两种方法解决该类问题:

1.指定从本地读取dtd文件

若要解析的xml文件中有如下的dtd声明:

 

publicId:被引用的外部实体的公共标识符,如果未提供,则为 null。

                上述的dtd声明中publicId为-//OASIS//DTD DITA Concept//EN

systemId:被引用的外部实体的系统标识符。

                 上述的dtd声明中systemId为http://docs.oasis-open.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd

可以通过重新SAX的EntityResolver类的resolveEntity( publicId,  systemId) throws , 方法指定读取本地的dtd文件,该放在在XML解析器解析xml之前调用,用于加载指定的dtd文件:

/** * Implementation of org.xml.sax.EntityResolver that loads * entitities (for example dtd files) from the classpath. */public class ClasspathEntityResolver    implements EntityResolver{    public InputSource resolveEntity(String publicId, String systemId)        throws SAXException, IOException    {             if (systemId != null)        {                       int index = systemId.lastIndexOf('/');            if (index != -1)            {             systemId = systemId.substring(index + 1);            }            systemId = "/" + systemId;            InputStream istr = Thread.currentThread().getContextClassLoader().getResourceAsStream(systemId);            if (istr != null)            {                return new InputSource(istr);            }        }        return null;    }}

在SAX解析xml文件之前,指定使用自定义的ClasspathEntityResolver:

SAXParserFactory spf = SAXParserFactory.newInstance();SAXParser saxParser = spf.newSAXParser(); xmlReader = saxParser.getXMLReader();xmlReader.setEntityResolver(new ClasspathEntityResolver());xmlReader.setContentHandler(handler);try { xmlReader.parse(new InputSource(inputFilePath)); } catch (Exception e) {  e.printStackTrace(); }

注意:

  经测试发现,这种方法只对SYSTEM(本地dtd)有效,如:

 

  PUBLIC方式的dtd依然从外部下载dtd,只能通过第二种方式忽略dtd校验。

2.解析xml文件时彻底忽略dtd:

SAX解析器可以通过指定http://apache.org/xml/features/nonvalidating/load-external-dtd属性来确定是否忽略dtd,例子如下:

SAXParserFactory spf = SAXParserFactory.newInstance();SAXParser saxParser = spf.newSAXParser();    xmlReader = saxParser.getXMLReader();xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);xmlReader.setContentHandler(handler);try {xmlReader.parse(new InputSource(inputFilePath));} catch (Exception e) {e.printStackTrace();}

转载于:https://my.oschina.net/heweipo/blog/412800

你可能感兴趣的文章
Tyvj 1728 普通平衡树
查看>>
[Usaco2015 dec]Max Flow
查看>>
javascript性能优化
查看>>
多路归并排序之败者树
查看>>
java连接MySql数据库
查看>>
转:Vue keep-alive实践总结
查看>>
android studio修改新项目package名称
查看>>
深入python的set和dict
查看>>
C++ 11 lambda
查看>>
Hadoop2.5.0 搭建实录
查看>>
实验吧 recursive write up
查看>>
High-speed Charting Control--MFC绘制图表(折线图、饼图、柱形图)控件
查看>>
go test命令參数问题
查看>>
linux 搜索文本
查看>>
超实用Mac软件分享(二)
查看>>
Android JSON数据解析
查看>>
DEV实现日期时间效果
查看>>
java注解【转】
查看>>
Oracle表分区
查看>>
centos 下安装g++
查看>>