Java 带有名称空间和前缀的JAXB解组器

Java 带有名称空间和前缀的JAXB解组器,java,soap,namespaces,jaxb,Java,Soap,Namespaces,Jaxb,我正在使用JAXB解析SOAP响应中的xml元素。我已经为xml元素定义了POJO类。我已经测试了没有名称空间和前缀的pojo类,它工作正常。但是当我尝试使用名称空间和前缀进行解析时,遇到以下异常。要求是解析来自SOAPMessage对象的输入 javax.xml.bind.UnmarshaleException:意外元素(uri:http://schemas.xmlsoap.org/soap/envelope/,本地:“信封”)。预期元素为 试图通过在package-info.java中为包创

我正在使用JAXB解析SOAP响应中的xml元素。我已经为xml元素定义了POJO类。我已经测试了没有名称空间和前缀的pojo类,它工作正常。但是当我尝试使用名称空间和前缀进行解析时,遇到以下异常。要求是解析来自SOAPMessage对象的输入

javax.xml.bind.UnmarshaleException:意外元素(uri:http://schemas.xmlsoap.org/soap/envelope/,本地:“信封”)。预期元素为

试图通过在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;

提前感谢

以下是您如何使用cae:

如果需要映射
信封
元素 套餐信息

通常使用
@XmlSchema
如下。像我这样使用
名称空间
elementFormDefault
属性意味着所有映射到XML元素的数据都将属于
http://www.xxxx.com/ncp/oomr/dto/
名称空间。
xmlns
中指定的信息用于生成XML模式,尽管一些JAXB实现在编组时使用此信息来确定名称空间的首选前缀(请参阅:)

信封

如果在
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<Customer> jb = unmarshaller.unmarshal(xsr, Customer.class);
        xsr.close();
    }

}
import javax.xml.bind.*;
导入javax.xml.stream.*;
导入javax.xml.transform.stream.StreamSource;
公共类解组器{
公共静态void main(字符串[]args)引发异常{
XMLInputFactory xif=XMLInputFactory.newFactory();
streamsourcexml=newstreamsource(“src/blog/stax/middle/input.xml”);
XMLStreamReader xsr=xif.createXMLStreamReader(xml);
xsr.nextTag();
而(!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();
}
}
了解更多信息


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

如果需要映射
信封
元素 套餐信息

通常使用
@XmlSchema
如下。像我这样使用
名称空间
elementFormDefault
属性意味着所有映射到XML元素的数据都将属于
http://www.xxxx.com/ncp/oomr/dto/
名称空间。
xmlns
中指定的信息用于生成XML模式,尽管一些JAXB实现在编组时使用此信息来确定名称空间的首选前缀(请参阅:)

信封

如果在
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<Customer> jb = unmarshaller.unmarshal(xsr, Customer.class);
        xsr.close();
    }

}
import javax.xml.bind.*;
导入javax.xml.stream.*;
导入javax.xml.transform.stream.StreamSource;
公共类解组器{
公共静态void main(字符串[]args)引发异常{
XMLInputFactory xif=XMLInputFactory.newFactory();
streamsourcexml=newstreamsource(“src/blog/stax/middle/input.xml”);
XMLStreamReader xsr=xif.createXMLStreamReader(xml);
xsr.nextTag();
而(!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();
}
}
了解更多信息


这可以在不使用标准SOAPMessage类修改生成的JAXB代码的情况下完成。我写了这篇文章

它有点复杂,但工作正常

编组 解组
字符串示例=
"";
SOAPMessage message=MessageFactory.newInstance().createMessage(null,
新的ByteArrayInputStream(例如.getBytes());
Unmarshaller Unmarshaller=JAXBContext.newInstance(Farm.class).createUnmarshaller();
Farm Farm=(Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());

这可以在不使用标准SOAPMessage类修改生成的JAXB代码的情况下完成。我写了这篇文章

它有点复杂,但工作正常

编组 解组
字符串示例=
"";
SOAPMessage message=MessageFactory.newInstance().createMessage(null,
新的ByteArrayInputStream(例如.getBytes());
Unmarshaller Unmarshaller=JAXBContext.newInstance(Farm.class).createUnmarshaller();
Farm Farm=(Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());

只是想添加到现有答案上——在解组时,如果XML文档不知道名称空间,您可能会收到一个错误:javax.XML.bind.unmarshaleException
String example =
        "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header /><soapenv:Body><ns2:farm xmlns:ns2=\"http://adamish.com/example/farm\"><horse height=\"123\" name=\"glue factory\"/></ns2:farm></soapenv:Body></soapenv:Envelope>";
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());
Unmarshaller unmarshaller = JAXBContext.newInstance(YourObject.class).createUnmarshaller();
JAXBElement<YourObject> element = unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument(), YourObject.class);
YourObject yo = element.getValue();