XML解析接続タイムアウト
3482 ワード
この記事は以下のとおりです. http://blog.csdn.net/chjttony/article/details/7720873
前を言う
XMLを読み取るとき、なぜ接続がタイムアウトしたのか、XML解析がどのようにネットワークにアクセスするのか分からない人が多いが、実はXML解析の前に、XMLがDTDファイルを指定すると、JavaはDTDファイルの経路に基づいてローカル検索やリモートダウンロードを行い、ダウンロードすると接続タイムアウトが発生する!だから接続のタイムアウトを避けるために、DTDのダウンロードを避けることができて、以下は2つの方式を通じてDTDのダウンロードを避けることができて、本人は自分で測って、確かに1篇の良い文章で、作者に感謝します!
次は本文です.
Javaプログラムはxmlファイルを解析する際、xmlファイルにdtdが指定されている場合、デフォルトでは指定されたurlからdtdファイルがダウンロードされますが、ネットワーク接続ができない場合やファイアウォールの原因でdtdファイルがダウンロードできない場合、プログラムが接続タイムアウト異常を報告し、xmlの解析に失敗することが多いです.このクラスの問題を解決するには、次の2つの方法があります.
1.dtdファイルをローカルから読み込むことを指定
解析するxmlファイルに次のdtd宣言があります.
publicId:参照される外部エンティティの共通識別子で、指定されていない場合nullです.
上記dtd宣言でpublicIdは-//OASIS//TD DITA Concept/EN
SystemId:参照される外部エンティティのシステム識別子.
上記dtd宣言でsystemIdはhttp://docs.oasis-open.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd
再SAXのEntityResolverクラスのresolveEntity(String) publicId, String systemId) throws SAXException, IOExceptionメソッドは、XML解析器がxmlを解析する前に呼び出され、指定したdtdファイルをロードするためにローカルのdtdファイルを読み込むことを指定します.
SAXでxmlファイルを解析する前に、カスタムClasspathEntityResolverを使用することを指定します.
注意:
試験により、この方法はSYSTEM(ローカルdtd)にのみ有効であることが分かった.
PUBLIC方式のdtdは依然として外部からdtdをダウンロードしており、第2の方式でdtdチェックを無視するしかない.
2.xmlファイルを解析するときにdtdを完全に無視する:
SAX解析器は指定できますhttp://apache.org/xml/features/nonvalidating/load-external-dtdプロパティを使用してdtdを無視するかどうかを決定します.例は次のとおりです.
前を言う
XMLを読み取るとき、なぜ接続がタイムアウトしたのか、XML解析がどのようにネットワークにアクセスするのか分からない人が多いが、実はXML解析の前に、XMLがDTDファイルを指定すると、JavaはDTDファイルの経路に基づいてローカル検索やリモートダウンロードを行い、ダウンロードすると接続タイムアウトが発生する!だから接続のタイムアウトを避けるために、DTDのダウンロードを避けることができて、以下は2つの方式を通じてDTDのダウンロードを避けることができて、本人は自分で測って、確かに1篇の良い文章で、作者に感謝します!
次は本文です.
Javaプログラムはxmlファイルを解析する際、xmlファイルにdtdが指定されている場合、デフォルトでは指定されたurlからdtdファイルがダウンロードされますが、ネットワーク接続ができない場合やファイアウォールの原因でdtdファイルがダウンロードできない場合、プログラムが接続タイムアウト異常を報告し、xmlの解析に失敗することが多いです.このクラスの問題を解決するには、次の2つの方法があります.
1.dtdファイルをローカルから読み込むことを指定
解析するxmlファイルに次のdtd宣言があります.
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "
http://docs.oasisopen.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd
">
publicId:参照される外部エンティティの共通識別子で、指定されていない場合nullです.
上記dtd宣言でpublicIdは-//OASIS//TD DITA Concept/EN
SystemId:参照される外部エンティティのシステム識別子.
上記dtd宣言でsystemIdはhttp://docs.oasis-open.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd
再SAXのEntityResolverクラスのresolveEntity(String) publicId, String systemId) throws SAXException, IOExceptionメソッドは、XML解析器がxmlを解析する前に呼び出され、指定したdtdファイルをロードするためにローカルのdtdファイルを読み込むことを指定します.
/**
* Implementation of <code>org.xml.sax.EntityResolver</code> 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)にのみ有効であることが分かった.
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "
http://docs.oasisopen.org/dita/v1.2/os/dtd1.2/technicalContent/dtd/concept.dtd
">
PUBLIC方式のdtdは依然として外部からdtdをダウンロードしており、第2の方式で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();
}