因此,在我当前的项目中,我使用 JAXB RI 和 Sun 的 JRE(我相信是 Xerces)中的默认 Java 解析器来解组任意 XML。
首先我使用 XJC 编译一个如下形式的 XSD:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="foobar">
...
</xs:element>
</xs:schema>
在“好案例”中,一切都按设计进行。也就是说,如果我传递了符合此模式的 XML,那么 JAXB 会正确地将其解组为对象树。
当我通过外部 DTD 引用传递 XML 时,问题就出现了,例如
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foobar SYSTEM "http://blahblahblah/foobar.dtd">
<foobar></foobar>
在解组这样的事情时,SAX 解析器尝试加载远程实体(“ http://somehost/foobar.dtd ”),尽管这个片段显然不符合我之前用 XJC 编译的模式。
为了规避这种行为,因为我知道任何符合标准的 XML(根据我编译的 XSD)都不需要加载远程实体,所以我必须定义一个自定义 EntityResolver 来缩短所有远程实体的加载。所以不要做类似的事情:
MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(myReader);
我被迫这样做:
XMLReader myXMLReader = mySAXParser.getXMLReader();
myXMLReader.setEntityResolver(myCustomEntityResolver);
SAXSource mySAXSource = new SAXSource(myXMLReader, new InputSource(myReader));
MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(mySAXSource);
所以我的最终问题是:
当使用 JAXB 解组时,如果在没有加载这些远程实体的情况下可以将相关 XML 识别为无效时,底层 SAX 解析器加载远程实体是否应该自动短路?
另外,这似乎不是一个安全问题吗?鉴于 JAX-WS 在底层依赖 JAXB,似乎我可以将特制的 XML 传递给任何基于 JAX-WS 的 Web 服务,并导致 WS 主机加载任意 URL。
我是一个相对新手,所以我可能缺少一些东西。如果是这样,请告诉我!