I want to deserialize the following XML using JAXB:
<testData>
<tx>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://my/namespace">
<soapenv:Header>
...
</soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
</tx>
<flag>true</flag>
<someObject>
...
</someObject>
</testData>
The problem is that I don't know how to represent a soap envelope in the Java model to deserialize it successfully. This is the input data of tool made for our testers and envelope is going to be copied from SOAP UI.
The only solution I came up with is to use @XmlAnyElement(lax = true)
and have the envelope as an object in the model, which eventually will be deserialized to ElementNSImpl
. But it doesn't look like the best solution.
How can I solve this problem? Suggestions to change format are welcome too, as long as they will allow to conveniently store(in one file) and deserialize copy-pasted soap envelope and additional objects I have added in the example XML.
This is my Java model at the moment:
@XmlRootElement(name = "testData")
public class XMLWrapper {
@XmlAnyElement(lax = true)
private Object tx;
private boolean flag;
private SomeObject SomeObject;
}
And unmarshalling:
JAXBContext jaxbContext = JAXBContext.newInstance(XMLWrapper.class);
jaxbContext.createUnmarshaller().unmarshal(new File("file.xml"));
答案 0 :(得分:1)
因为您为XML元素<tx>
声明了类型为Object
的属性,
JAXB没有足够的信息来创建比ElementNSImpl
更具体的内容。
<tx>
元素将需要一个更好的Java模型。
而不是将其声明为Object
@XmlAnyElement(lax = true)
private Object tx;
您需要使用功能齐全的Java类对其进行声明(我们将其称为Tx
):
private Tx tx;
类Tx
表示XML元素<tx>
以及嵌套在其中的所有内容。
看起来可能像这样:
@XmlAccessorType(XmlAccessType.FIELD)
public class Tx {
@XmlElement(name = "Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
private SoapEnvelope envelope;
}
要为XML元素<soapenv:Envelope ...>
建模,请声明一个属性
(我们将其称为SoapEnvelope envelope
)。该属性需要注释
用@XmlElement
告诉JAXB,它映射到XML元素名称Envelope
。
特别注意其namespace
参数,它对应于XML名称空间定义
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
。
然后对SoapEnvelope
类重复相同的过程
用于对XML元素<soapenv:Envelope>
中的内容进行建模:
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapEnvelope {
@XmlElement(name = "Header", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
private SoapHeader header;
@XmlElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
private SoapBody body;
}
然后对SoapHeader
和SoapBody
类重复相同的过程
用于对XML元素<soapenv:Header>
和<soapenv:Body>
中的内容进行建模:
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapHeader {
...
}
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapBody {
...
}