一、写在所有之前:
因为dom4j和jdom在这个问题上处理的方法是一模一样的,只是一个是SAXBuilder 一个SAXReader,这里以jdom距离,至于dom4j只需要同理替换一下就可以了。
二、问题发生的情况
当你用jdom读取一个有dtd验证的xml文件,同时你的网络是不通的情况下。会出现以下错误:
1,代码如下
2,xml文件
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
<?xml version="1.0" encoding="GBK"?>
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.8//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd">
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
<workflow>
...............
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
</workflow>
3,错误如下
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
java.net.SocketException: Permission denied: connect
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at java.net.PlainSocketImpl.socketConnect(Native Method)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at java.net.Socket.connect(Socket.java:507)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at java.net.Socket.connect(Socket.java:457)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.http.HttpClient.New(HttpClient.java:287)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.http.HttpClient.New(HttpClient.java:299)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:792)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:744)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:669)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:913)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:973)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:905)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:872)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:282)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDispatcher.dispatch(XMLDocumentScannerImpl.java:1021)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:368)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:834)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:148)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1242)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:453)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:810)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:789)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
at dom.TestJdom.main(TestJdom.java:26)
![](http://www.blogjava.net/Images/OutliningIndicators/None.gif)
三、分析原因
当执行build的时候jdom分析到
DOCTYPE workflow PUBLIC "-/OpenSymphony Group//DTD OSWorkflow 2.8//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd
就会去读取http://www.opensymphony.com/osworkflow/workflow_2_8.dtd 这里的dtd文件来验证,但是因为网络是不通的所以就会报socket错误。
四、解决办法
1,最开始查看jdom api发现了这样一个方法
builder.setValidation(false);
这样可以让jdom不做验证,但是结果依然出问题,查了一下原因,说虽然不验证但是还是会下载
2,参照jdom网站的FAQ http://www.jdom.org/docs/faq.html#a0100
这是原文内容
里边教我们定义个类
通过builder.setEntityResolver(new NoOpEntityResolver())方法来隐蔽起dtd验证器。这样就不会出错了。试了一下确实没问题了。但要知道xml没有dtd验证是不好的,我们是否能让它使用本地dtd验证呢。例如本文的oswork
我把验证文件workflow_2_8.dtd拷贝到本地,能否验证的时候用本地的呢?
3,用本地dtd验证
方法有两种
方法一、更改xml中的doctype声明,但是一般情况下更改这个是不好的。更改后就不是标准的了。
方法二、验证期替换
public Document load(String file) throws JDOMException, IOException {
try {
SAXBuilder sax = new SAXBuilder();
sax.setValidation(false);
sax.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId,String systemId) throws SAXException, IOException {
/*InputSource is = new InputSource(new FileInputStream(System.getProperty("user.dir")+"//web-app_2_3.dtd"));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
*/
return new InputSource(new FileInputStream(""));
}
});
return sax.build(file);
} catch ( Exception e ) {
e.printStackTrace();
return null;
}
}
http://blog.csdn.net/youlianying/article/details/5908335