简体   繁体   English

JAXB解组:意外元素

[英]JAXB unmarshal: unexpected element

Background : 背景

I am using JAXB to unmarshal XML into Java objects. 我正在使用JAXB将XML解组到Java对象中。 Originally, I was using just JAXB to perform the unmarshal. 最初,我只是使用JAXB来执行解组。 Then a static analysis was performed on the code and a high criticality issue was raised for XML External Entity Injection. 然后对代码进行了静态分析,并提出了XML外部实体注入的高关键性问题。 After a little research, I found a suggestion ( https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_Unmarshaller ) to use a parser configured to prevent external entities from being parsed. 经过一些研究,我发现了一个建议( https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_Unmarshaller ),该建议使用配置为防止外部实体被解析的解析器。 An example of what to do was provided: 提供了一个操作示例:

//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);

I have not done this exactly as shown, but I believe I have done the same in effect: 我没有按照显示的那样做,但是我相信我实际上做了同样的事情:

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;
}

Problem : 问题

After implementing the correction, I am now getting an unmarshal exception when the program attempts to read in XML: 实施更正之后,当程序尝试以XML读取时,我现在得到一个非编组异常:

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

Before the above fix where I was just using JAXB to unmarshal, it was able to properly parse the provided XML with no problem. 在上面仅使用JAXB解组的上述修复之前,它能够正确解析提供的XML。

I assume that the SAX parser expects the XML to provide extra information that's missing, or that it needs to be configured to ignore whatever it's complaining about. 我假设SAX解析器期望XML提供缺少的额外信息,或者需要对其进行配置以忽略它抱怨的内容。 I tried a few other "features" ( http://xml.org/sax/features/namespace-prefixes=true and http://xml.org/sax/features/validation=false ), but that did not resolve the problem. 我尝试了其他一些“功能”( http://xml.org/sax/features/namespace-prefixes=truehttp://xml.org/sax/features/validation=false ),但这无法解决问题。

I have no control over the XML schema that defines the XML types, nor do I have control over how the corresponding Java classes are generated. 我无法控制定义XML类型的XML模式,也无法控制如何生成相应的Java类。

Any information to help me understand what's going on and that helps me resolve this problem, would be very much appreciated. 我们将不胜感激任何能帮助我了解发生了什么并且能解决此问题的信息。

After a little experimentation I was able to resolve the error by setting the following features: 经过一些试验,我能够通过设置以下功能来解决该错误:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM