【问题标题】:JAXB unmarshal: unexpected elementJAXB 解组:意外元素
【发布时间】:2019-05-15 20:22:57
【问题描述】:

背景:

我正在使用 JAXB 将 XML 解组为 Java 对象。最初,我只使用 JAXB 来执行解组。然后对代码进行了静态分析,并针对 XML 外部实体注入提出了一个高危问题。经过一番研究,我发现了一个建议 (https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_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);

我并没有完全按照显示的那样做,但我相信我已经做了同样的事情:

XMLReader reader = getXMLReader();

if (reader == null) {
  logger.warn("Unable to create XML reader");
  return;
}

JAXBContext context = JAXBContext.newInstance(messageClass);
Unmarshaller unmarshaller = context.createUnmarshaller();

for (File file : files) {
  try {
    InputSource source = new InputSource(new FileReader(file));
    Source xmlSource = new SAXSource(reader, source);
    JAXBElement<? extends BaseType> object =
        (JAXBElement<? extends BaseType>) unmarshaller.unmarshal(xmlSource);
    messages.add(object.getValue());
  } catch (FileNotFoundException e) {
    logger.error("Exception", e);
  }
}

...

private XMLReader getXMLReader() {
    SAXParserFactory factory = SAXParserFactory.newInstance();

    try {
      factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
      factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
      factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    } catch (SAXNotRecognizedException | SAXNotSupportedException
        | ParserConfigurationException e) {
      logger.error("Exception", e);
    }

    XMLReader reader = null;

    try {
      reader = factory.newSAXParser().getXMLReader();
    } catch (SAXException | ParserConfigurationException e) {
      logger.error("Exception", e);
    }

    return reader;
}

问题:

实施更正后,当程序尝试读取 XML 时,我现在收到一个解组异常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"ns1:TypeXYZ"). Expected elements are <{protected namespace URI}TypeABC>,...<{protected namespace URI}TypeXYZ>,...

在上述修复之前,我只是使用 JAXB 解组,它能够正确解析提供的 XML,没有问题。

我假设 SAX 解析器期望 XML 提供丢失的额外信息,或者需要将其配置为忽略它所抱怨的任何内容。我尝试了其他一些“功能”(http://xml.org/sax/features/namespace-prefixes=true 和 http://xml.org/sax/features/validation=false),但并没有解决问题。

我无法控制定义 XML 类型的 XML 模式,也无法控制如何生成相应的 Java 类。

任何帮助我了解正在发生的事情并帮助我解决此问题的信息,我们将不胜感激。

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    经过一些实验,我能够通过设置以下功能来解决错误:

    factory.setFeature("http://xml.org/sax/features/validation", false);
    factory.setFeature("http://xml.org/sax/features/namespaces", true);
    factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
    

    【讨论】:

      猜你喜欢
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2012-03-20
      • 1970-01-01
      相关资源
      最近更新 更多