JAXB解组使用名称空间和前缀

我正在使用JAXB来解析SOAP响应中的xml元素。 我已经为xml元素定义了POJO类。 我已经测试了没有命名空间的pojo类,并且前缀工作正常。但是当我尝试使用命名空间解析并且前缀面向以下exception时。要求解析SOAPMessage对象的输入

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Envelope"). Expected elements are

试图通过在package-info.java中为包创建@XMLSchema来修复,并将此文件放在包文件夹中。任何人都可以指导我前进吗?

提到这篇文章,但没有帮助我。

编辑:XMLSchema

 @javax.xml.bind.annotation.XmlSchema ( xmlns = { @javax.xml.bind.annotation.XmlNs(prefix = "env", namespaceURI="http://schemas.xmlsoap.org/soap/envelope/"), @javax.xml.bind.annotation.XmlNs(prefix="ns3", namespaceURI="http://www.xxxx.com/ncp/oomr/dto/") } ) package com.one.two; 

提前致谢

这可以在不使用标准SOAPMessage类修改生成的JAXB代码的情况下完成。 我在这里和这里写过这个

它有点繁琐,但工作正常。

编组

 Farm farm = new Farm(); farm.getHorse().add(new Horse()); farm.getHorse().get(0).setName("glue factory"); farm.getHorse().get(0).setHeight(BigInteger.valueOf(123)); Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Marshaller marshaller = JAXBContext.newInstance(Farm.class).createMarshaller(); marshaller.marshal(farm, document); SOAPMessage soapMessage = MessageFactory.newInstance().createMessage(); soapMessage.getSOAPBody().addDocument(document); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); soapMessage.writeTo(outputStream); String output = new String(outputStream.toByteArray()); 

解组

 String example = ""; SOAPMessage message = MessageFactory.newInstance().createMessage(null, new ByteArrayInputStream(example.getBytes())); Unmarshaller unmarshaller = JAXBContext.newInstance(Farm.class).createUnmarshaller(); Farm farm = (Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument()); 

以下是如何处理您的使用cae:

如果您需要映射Envelope元素

包信息

通常,您将使用@XmlSchema ,如下所示。 像我所做的那样使用namespaceelementFormDefault属性意味着除非另有映射,否则映射到XML元素的所有数据都属于http://www.xxxx.com/ncp/oomr/dto/名称空间。 xmlns指定的信息用于生成XML模式,一些JAXB实现使用它来确定编组时命名空间的首选前缀(请参阅: http : //blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes .html )。

 @XmlSchema ( namespace="http://www.xxxx.com/ncp/oomr/dto/", elementFormDefault=XmlNsForm.QUALIFIED, xmlns = { @XmlNs(prefix = "env", namespaceURI="http://schemas.xmlsoap.org/soap/envelope/"), @XmlNs(prefix="whatever", namespaceURI="http://www.xxxx.com/ncp/oomr/dto/") } ) package com.one.two; import javax.xml.bind.annotation.*; 

信封

如果在com.one.two您需要映射到http://www.xxxx.com/ncp/oomr/dto/以外的命名空间中的元素,那么您需要在@XmlRootElement@XmlElement注释中指定它。

 package com.one.two; import javax.xml.bind.annotation.*; @XmlRootElement(name="Envelope", namespace="http://schemas.xmlsoap.org/soap/envelope/") @XmlAccessorType(XmlAccessType.FIELD) public class Envelope { @XmlElement(name="Body", namespace="http://schemas.xmlsoap.org/soap/envelope/") private Body body; } 

了解更多信息

如果你只是想映射身体

您可以使用StAX解析器来解析消息并前进到有效负载部分并从那里解组:

 import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class UnmarshalDemo { public static void main(String[] args) throws Exception { XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource xml = new StreamSource("src/blog/stax/middle/input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(xml); xsr.nextTag(); while(!xsr.getLocalName().equals("return")) { xsr.nextTag(); } JAXBContext jc = JAXBContext.newInstance(Customer.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement jb = unmarshaller.unmarshal(xsr, Customer.class); xsr.close(); } } 

了解更多信息

只是想添加到现有的答案 – 如果XML文档不能识别名称空间,则解组时可能会收到错误:javax.xml.bind.UnmarshalException:unexpected element(uri:“ http://some.url ” ;,本地: “someOperation”)

如果是这种情况,您可以在unmarshaller上使用不同的方法:

 Unmarshaller unmarshaller = JAXBContext.newInstance(YourObject.class).createUnmarshaller(); JAXBElement element = unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument(), YourObject.class); YourObject yo = element.getValue();