微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

XML 解析 连接超时

本文转载自:

http://www.jb51.cc/article/p-tpkkxare-up.html

说在前面

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

下面是正文:

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

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

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

<!DOCTYPEconceptPUBLIC"-//oasis//DTDDitaconcept//EN""
http://docs.oasisopen.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.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(StringpublicId,StringsystemId) throwsSAXException,IOException方法指定读取本地的dtd文件,该放在在XML解析器解析xml之前调用,用于加载指定的dtd文件

/**
*Implementationof<code>org.xml.sax.EntityResolver</code>thatloads
*entitities(forexampledtdfiles)fromtheclasspath.
*/
publicclassClasspathEntityResolver
implementsEntityResolver
{
publicInputSourceresolveEntity(StringpublicId,StringsystemId)
throwsSAXException,IOException
{

if(systemId!=null)
{

intindex=systemId.lastIndexOf('/');
if(index!=-1)
{
systemId=systemId.substring(index+1);
}
systemId="/"+systemId;
InputStreamistr=Thread.currentThread().getContextClassLoader().getResourceAsstream(systemId);
if(istr!=null)
{
returnnewInputSource(istr);
}
}
returnnull;
}
}

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

SAXParserFactoryspf=SAXParserFactory.newInstance();
SAXParsersaxParser=spf.newSAXParser();
xmlReader=saxParser.getXMLReader();
xmlReader.setEntityResolver(newClasspathEntityResolver());
xmlReader.setContentHandler(handler);
try{
xmlReader.parse(newInputSource(inputFilePath));
}catch(Exceptione){
e.printstacktrace();
}

注意:

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

<!DOCTYPEconceptPUBLIC"-//oasis//DTDDitaconcept//EN""
http://docs.oasisopen.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd
">

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


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

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

SAXParserFactoryspf=SAXParserFactory.newInstance();
SAXParsersaxParser=spf.newSAXParser();

xmlReader=saxParser.getXMLReader();
xmlReader.setFeature("
http://apache.org/xml/features/nonvalidating/load-external-dtd
",false);
xmlReader.setContentHandler(handler);
try{
xmlReader.parse(newInputSource(inputFilePath));
}catch(Exceptione){
e.printstacktrace();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类