我们使用Jaxb(jaxb-api 2.2.5)从XSD生成Java类。 'someField'元素具有nillable ='true'属性和(隐式)minoccurs ='1'。还有一个可选的“订单”属性。
当我们在someField上设置order属性但没有值时,JAXB将在请求中生成XML元素而不使用nill ='true',这不会被XSD接受并导致SOAP错误。
该字段的XSD:
<xs:element name="someField" nillable="true">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="iata:AlphaNumericStringLength1to19">
<xs:attribute name="order" type="xs:integer" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Jaxb将其转换为Java类的以下字段:
@XmlElement(required = true, nillable = true)
protected SomeParentType.SomeField someField;
SomeField类如下所示:
public static class SomeField{
@XmlValue
protected String value;
@XmlAttribute
protected BigInteger order;
// getters + setters
}
当我们将ATTRIBUTE的顺序设置为2(例如),并且没有为该值设置任何内容时,JAXB将生成:
<pay1:someField order="2"/>
根据XSD,这是无效的,当我们发送它时会导致SOAP错误。
这确实有效:
<pay1:someField xsi:nil="true" order="2"/>
你知道我们如何让JAXB产生后者吗?并且JAXB在生成无零版本时实际上是错误的吗?
答案 0 :(得分:2)
JAXB在生成无零版本时实际上是错误的吗?
让我回答你。
你知道如何让JAXB产生后者吗?
以下是你可以做的事情
<强> SomeParentType 强>
要获得您正在寻找的现有JAXB库的行为,域模型需要具有以下形式:
import java.math.BigInteger;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class SomeParentType {
@XmlElementRef(name="someField")
protected JAXBElement<SomeParentType.SomeField> someField;
public static class SomeField{
@XmlValue
protected String value;
@XmlAttribute
protected BigInteger order;
// getters + setters
}
}
<强>注册表强>
要与@XmlElementRef
一起使用,我们需要在使用@XmlElementDecl
注释的班级上设置@XmlRegistry
。
import javax.xml.namespace.QName;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
@XmlRegistry
public class Registry {
@XmlElementDecl(name="someField")
public JAXBElement<SomeParentType.SomeField> createSomeField(SomeParentType.SomeField someField) {
return new JAXBElement(new QName("someField"), SomeParentType.SomeField.class, someField);
}
}
下面是一些练习您的用例的演示代码:
import javax.xml.bind.*;
import java.math.BigInteger;
public class Demo {
public static void main(String[] args) throws Exception {
// Create the JAXBContext to bring in the Registry
JAXBContext jc = JAXBContext.newInstance(SomeParentType.class, Registry.class);
// Create the instance of SomeField
SomeParentType.SomeField sf = new SomeParentType.SomeField();
sf.order = new BigInteger("1");
// Wrap the SomeField in a JAXBElement & specify the nil aspect
Registry registry = new Registry();
JAXBElement<SomeParentType.SomeField> jaxbElement = registry.createSomeField(sf);
jaxbElement.setNil(true);
SomeParentType spt = new SomeParentType();
spt.someField = jaxbElement;
// Marshal the domain model to XML
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(spt, System.out);
}
}
<强>输出强>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<someParentType>
<someField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" order="1" xsi:nil="true"/>
</someParentType>