`
sw1982
  • 浏览: 511363 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

诡异的jdom出现网络访问

阅读更多

一段用jdom解析struts2 Action配置文件的代码,最近莫名其妙抛异常了。

看一下异常完全是八竿子打不上的,ConnectException, 莫不成解析XML还需要联网?

java.net.ConnectException: Connection timed out: connect
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(Unknown Source)
	at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
	at java.net.PlainSocketImpl.connect(Unknown Source)
	at java.net.SocksSocketImpl.connect(Unknown Source)
	at java.net.Socket.connect(Unknown Source)
	at java.net.Socket.connect(Unknown Source)
	at sun.net.NetworkClient.doConnect(Unknown Source)
	at sun.net.www.http.HttpClient.openServer(Unknown Source)
	at sun.net.www.http.HttpClient.openServer(Unknown Source)
	at sun.net.www.http.HttpClient.<init>(Unknown Source)
	at sun.net.www.http.HttpClient.New(Unknown Source)
	at sun.net.www.http.HttpClient.New(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:489)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:847)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:826)
	at xml.UrlFetcher.main(UrlFetcher.java:34)

 

随后猜测问题可能出在这里,xml有引用一个外部dtd定义,

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

jdom在解析的过程中默认会读取xml文件中的dtd,所以如果是url格式的就会产生外网访问。

而最近除了国内的gfw喜欢和谐网站之外,公司也上了gfw,所有外网请求都是悲剧。。这里程序是无法连接到http://struts.apache.org的,所以也就抛出ConnectException

 

上网找了一圈,最终得到真传:(就是下面被我注释掉的这么一行,加上去就ok,无需访问外网)

 

			Document doc;
			Element root; 
			SAXBuilder builder = new SAXBuilder();
			//builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
			try {
				doc = builder.build(new File(filename));
				root = doc.getRootElement();

				Element packageN = (Element) XPath.selectSingleNode(root, "//package");
				System.out.println("packageN:"+packageN);
				
				String namespace = packageN.getAttribute("namespace").getValue();
				System.out.println("   namespace:"+namespace);
				
				List actions = XPath.selectNodes(root, "//action");
				Iterator iter = actions.iterator();
				while (iter.hasNext()) {
					Element rule = (Element) iter.next();
					String action = rule.getAttribute("name").getValue();
					//System.out.println("     actionName:"+action);
					
					System.out.println(namespace+"/"+action);
					//所有的url列表,哈哈
					//System.out.println(namespace+"/"+action+".xhtml");
				}
				
			} catch (JDOMException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

 

为什么这么神奇呢?填入http://apache.org/xml/features/nonvalidating/load-external-dtd 就不会有问题了。

 

1.根据上面长长的错误堆栈,定位到问题出在com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl这里。

 

2.先在类里面搜一下nonvalidating,发现是

    /** Feature identifier: XInclude processing */
    private static final String XINCLUDE_FEATURE = 
        Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;

 3.然后找一下上面这个字段的引用:发现了这个方法:

    /**
     * Gets the XInclude processing mode for this parser
     * @return the state of XInclude processing mode
     */
    public boolean isXIncludeAware() {
        try {
            return xmlReader.getFeature(XINCLUDE_FEATURE);
        }
        catch (SAXException exc) {
            return false;
        }
    }
 

4.然后查看这个方法的引用,发现就是在parser的实现里面!也就是说给出的这个既定uri,会禁用到dtd下载

   SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing)
        throws SAXException
    {
        // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
        xmlReader = new JAXPSAXParser(this);
 
        // JAXP default is false while SAX 2 default is true!
        xmlReader.setFeature0(NAMESPACES_FEATURE, spf.isNamespaceAware());
        // SAX "namespaces" and "namespace-prefixes" features should not
        // both be false.  We make them opposite for backward compatibility
        // since JAXP 1.0 apps may want to receive xmlns* attributes.
        xmlReader.setFeature0(NAMESPACE_PREFIXES_FEATURE, !spf.isNamespaceAware());
        
        // Avoid setting the XInclude processing feature if the value is false.
        // This will keep the configuration from throwing an exception if it
        // does not support XInclude.
        if (spf.isXIncludeAware()) {
            xmlReader.setFeature0(XINCLUDE_FEATURE, true);
        }
 

 

原文解答:

==============================

How do I keep the DTD from loading? Even when I turn off validation the parser tries to load the DTD file.

Even when validation is turned off, an XML parser will by default load the external DTD file in order to parse the DTD for external entity declarations. Xerces has a feature to turn off this behavior named "http://apache.org/xml/features/nonvalidating/load-external-dtd" and if you know you're using Xerces you can set this feature on the builder.

builder.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

If you're using another parser like Crimson, your best bet is to set up an EntityResolver that resolves the DTD without actually reading the separate file.

import org.xml.sax.*;
import java.io.*;

public class NoOpEntityResolver implements EntityResolver {
       public InputSource resolveEntity(String publicId, String systemId) {
              return new InputSource(new StringBufferInputStream(""));
       }
}

Then in the builder


builder.setEntityResolver(new NoOpEntityResolver());

There is a downside to this approach. Any entities in the document will be resolved to the empty string, and will effectively disappear. If your document has entities, you need to setExpandEntities(false) code and ensure the EntityResolver only suppresses the DocType.

分享到:
评论

相关推荐

    jdom 下载 jdom 下载

    对于手动下载,可以访问[JDOM官方网站](http://jdom.org/),选择合适的版本下载JDOM的jar文件,并将其添加到项目的类路径中。 **4. 使用JDOM解析XML** 以下是一个简单的例子,演示如何使用JDOM解析XML文件: ```...

    jdom-1.1.1包

    XML(eXtensible Markup Language)是一种用于存储和传输结构化数据的标准,广泛应用于网络通信、数据存储和配置文件等领域。JDOM设计的目标是成为Java平台上的首选XML解析库,它提供了一个纯Java的DOM(Document ...

    JDOM对XML文件的读取

    XML(eXtensible Markup Language)是一种用于存储和交换数据的标记语言,广泛应用于软件开发、数据存储和网络通信等领域。在Java编程中,JDOM(Java Document Object Model)是处理XML的一种流行库,它提供了方便的...

    解析XML所需的jar jdom.jar

    XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于网络服务、配置文件以及数据...同时,对于网络服务(如webservice)中的数据交换,JDOM也是一个可靠的工具,能帮助你有效地处理XML格式的数据。

    jdom-2.0.3.rar

    6. **错误处理**:JDOM提供了详细的异常处理机制,当XML文档结构不合法或解析过程中出现问题时,会抛出相应的异常,帮助开发者定位并解决问题。 在实际应用中,JDOM可以用于各种场景,如配置文件的读写、Web服务的...

    jdom.jar解析xml

    XML(Extensible Markup Language)作为一种通用的数据交换格式,在IT行业中被广泛应用,尤其在数据存储、配置文件、网络通信等领域。为了方便开发者处理XML文档,各种解析库应运而生,其中JDOM是Java平台上的一个...

    Dom JDom 解析xml 文件

    XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于网络数据交换、配置文件存储等场景。在Java中,解析XML文件是常见的任务,其中DOM(Document Object Model)和JDOM是两种常用的方法。 DOM...

    JDom.rar_jason

    2. **内存模型**:JDOM在内存中构建完整的XML文档结构,这使得对XML文档的访问和修改变得非常方便。用户可以通过Element、Attribute、Text等对象直接操作XML结构。 3. **性能优化**:虽然早期版本的JDOM在性能上...

    IO流及JDOM操作

    JDOM提供了一种高效、方便的方式来创建、修改和访问XML文档。与DOM(Document Object Model)相比,JDOM更适应Java环境,因为它避免了DOM与Java类型之间的转换,提高了性能。使用JDOM,你可以直接通过Java对象来构建...

    jdom和dom4j的jar包

    XML(eXtensible Markup Language)是一种用于存储和交换数据的标记语言,广泛应用于软件开发、数据存储和网络通信等领域。在Java编程中,解析XML文档通常需要借助于特定的库,如JDOM和DOM4J。这两个库都是Java中...

    jdom.jar;javax.servlet.jar;mx4j.jar

    MX4J提供了远程管理功能,允许通过网络访问和控制Java应用。这个库通常用于调试、性能优化和故障排除,特别是在生产环境中。mx4j.jar包含MX4J的核心组件和服务,使得开发者可以通过HTTP、RMI、JMX协议来暴露和操作...

    JAR包+sql+oracle+dwr+jdom+ibatis+struts2

    JAR文件有助于减少网络传输时间,实现代码封装,并可以使用数字签名进行安全验证。 2. **SQL**:Structured Query Language,结构化查询语言,是用于管理关系数据库系统(如MySQL、Oracle等)的标准语言。它用于...

    XML_XSL_DTD_SCHEMA_SAX_DOM_JDOM_WEBSERVICE简介.pdf

    - **易于使用**:提供了丰富的API来访问和修改文档中的各个部分。 - **功能强大**:支持文档的创建、查询、更新和删除操作。 - **良好的互操作性**:DOM标准被广泛支持,可以跨语言和平台使用。 #### 验证文档 ...

    springboot配置

    - **server.address**: 绑定到特定的网络接口地址(如 IP 地址)。 - **server.session-timeout**: 会话超时时间,单位是秒。 - **server.context-parameters.***: 定义 Servlet 上下文的初始化参数。 - **server....

    基于J2EE的掌上商店的设计与实现

    - **网络的连接**:使用 J2ME 的网络连接 API 实现客户端与服务器之间的通信。 - **数据存储方式和数据的交换**:使用 SQL Server 作为后台数据库,并采用 XML 格式进行数据交换。 ##### 3.4 业务数据流分析 - 用户...

    Android RSS阅读器的源码.rar

    8. **权限管理**:Android 6.0及以上版本需要动态请求网络访问权限,使用` ActivityCompat.checkSelfPermission()` 和 `ActivityCompat.requestPermissions()`。 9. **测试与调试**:使用JUnit进行单元测试,...

    XML解析 很全 一看就懂的东东

    XML(eXtensible Markup Language)是一种用于存储和传输数据的通用格式,尤其适用于网络通信和数据存储。在Java中,XML解析有四种主要的方法:DOM、SAX、JDOM和DOM4J。 1. DOM(文档对象模型)是W3C推荐的标准,它...

    Java+XML写的RSS阅读器

    Java的异常处理机制(try-catch-finally)可以帮助捕获和处理可能出现的问题,如网络连接失败、XML解析错误等。 9. **RSS标准兼容性**:RSS有多个版本,如RSS 0.91、RSS 1.0、RSS 2.0和Atom等。一个健壮的RSS阅读器...

Global site tag (gtag.js) - Google Analytics