如何使用 JAXB2.0 禁用 DTD 获取
Posted
技术标签:
【中文标题】如何使用 JAXB2.0 禁用 DTD 获取【英文标题】:How to disable DTD fetching using JAXB2.0 【发布时间】:2012-04-12 03:51:19 【问题描述】:我正在尝试使用 JAXB 来解组我最初使用 xjc 创建的一些 XML。我不想对解组进行任何验证,但是即使我根据 JAXB 文档使用 u.setSchema(null);
禁用了验证,但这并没有阻止 FileNotFoundException
在尝试运行时抛出并且可以'找不到架构。
JAXBContext jc = JAXBContext.newInstance("blast");
Unmarshaller u = jc.createUnmarshaller();
u.setSchema(null);
return u.unmarshal(blast)
我已经看到类似的问题,通过将 apache 属性 http://apache.org/xml/features/validation/schema
设置为 false
来从验证中禁用 SAX 解析,但我无法让 Unmarshaller 使用我自己的 sax 解析器。
【问题讨论】:
【参考方案1】:根据@blaise-doughan 和@aerobiotic 的回答,这里有一个对我有用的解决方案:
import java.io.FileReader;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class Demo2
public static void main(String[] args) throws Exception
JAXBContext jc = JAXBContext.newInstance(MyBean.class);
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
spf.setFeature("http://xml.org/sax/features/validation", false);
XMLReader xmlReader = spf.newSAXParser().getXMLReader();
InputSource inputSource = new InputSource(
new FileReader("myfile.xml"));
SAXSource source = new SAXSource(xmlReader, inputSource);
Unmarshaller unmarshaller = jc.createUnmarshaller();
MyBean foo = (MyBean) unmarshaller.unmarshal(source);
【讨论】:
这对我有用。另外还添加了spf.setValidating(false);
谢谢【参考方案2】:
下面的示例代码演示了如何获得 JAXB (JSR-222) 实现以使用您的 SAX 解析器:
import java.io.FileReader;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class Demo
public static void main(String[] args) throws Exception
JAXBContext jc = JAXBContext.newInstance(Foo.class);
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
XMLReader xmlReader = spf.newSAXParser().getXMLReader();
InputSource inputSource = new InputSource(new FileReader("input.xml"));
SAXSource source = new SAXSource(xmlReader, inputSource);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Foo foo = (Foo) unmarshaller.unmarshal(source);
System.out.println(foo.getValue());
【讨论】:
这对我不起作用,但这些对我有用:parser.setFeature("apache.org/xml/features/nonvalidating/load-external-dtd", false); parser.setFeature("xml.org/sax/features/validation", false); This 网站解释了如何在任何主要的 Java 框架上阻止它。 似乎 FEATURE_SECURE_PROCESSING 是关于 entityExpansionLimit 的。查看文档的最后一部分docs.oracle.com/javase/1.5.0/docs/guide/xml/jaxp/… 这回答了“如何让 Unmarshaller 使用我自己的 sax 解析器”的问题,但没有回答“如何使用 JAXB2.0 禁用 DTD 获取”的问题。【参考方案3】:回答“如何使用 JAXB2.0 禁用 DTD 获取”问题。
@sameer-puri 链接到https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#SAXTransformerFactory,它对问题的回答如下:
JAXB 解组器
由于 javax.xml.bind.Unmarshaller 解析 XML 并且不支持禁用 XXE 的任何标志,因此必须首先通过可配置的安全解析器解析不受信任的 XML,生成源对象作为结果,并传递源反对 Unmarshaller。例如:
//Disable XXE
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
//Do unmarshall operation
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(),
new InputSource(new StringReader(xml)));
JAXBContext jc = JAXBContext.newInstance(Object.class);
Unmarshaller um = jc.createUnmarshaller();
um.unmarshal(xmlSource);
【讨论】:
【参考方案4】:您可以直接从 javax.xml.transform.sax.SAXSource 创建 Unmarshaller。
查看此页面上的示例:http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/api/javax/xml/bind/Unmarshaller.html
比你“只”需要为那个 SAXSource 提供你自己的 URIResolver
【讨论】:
【参考方案5】:以上建议对我没有任何帮助... 我建议这段代码对我有用☺️ 从 xml 中删除 Dtd ...使用正则表达式 字符串 str = event.getData(); str= str.replaceAll("^](?:]>[^])>"," ");
【讨论】:
【参考方案6】:@doughan 和 @Renaud 的 SAXParserFactory
解决方案对我不起作用。由于错误
外部 DTD:无法读取外部 DTD“cXML.dtd”,因为 accessExternalDTD 属性设置的限制不允许“http”访问。
如果您使用公司代理,则以下解决方案有效。它基于XMLInputFactory
import java.io.FileReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import org.junit.Assert;
public class Demo3
public static void main(String[] args) throws Exception
JAXBContext jc = JAXBContext.newInstance(CXMLResponse.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
Unmarshaller unmarshaller = jc.createUnmarshaller();
CXMLResponse parsedResponse = (CXMLResponse) unmarshaller.unmarshal(xsr);
System.out.println(parsedResponse.toString());
灵感来自https://***.com/a/13069681/311420。再次感谢@bdoughan
【讨论】:
以上是关于如何使用 JAXB2.0 禁用 DTD 获取的主要内容,如果未能解决你的问题,请参考以下文章
添加文本和禁用滚动时如何使 UITextView 字段扩展?