I have a WSDL spec, using wsimport
to generate client code. (as I've done numerous times before).
Now, one of types in xsd:
<xs:complexType name="Credential">
<xs:sequence>
<xs:element minOccurs="0" name="UID" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="UIDBranch" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="PWD" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Signature" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
And corresponding java binding:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Credential", namespace = "http://schemas.datacontract.org/2004/07/...", propOrder = {
"uid",
"uidBranch",
"pwd",
"signature"
})
public class Credential {
@XmlElementRef(name = "UID", namespace = "http://schemas.datacontract.org/2004/07/...", type = JAXBElement.class, required = false)
protected JAXBElement<String> uid;
@XmlElementRef(name = "UIDBranch", namespace = "http://schemas.datacontract.org/2004/07/...", type = JAXBElement.class, required = false)
protected JAXBElement<String> uidBranch;
@XmlElementRef(name = "PWD", namespace = "http://schemas.datacontract.org/2004/07/...", type = JAXBElement.class, required = false)
protected JAXBElement<String> pwd;
@XmlElementRef(name = "Signature", namespace = "http://schemas.datacontract.org/2004/07/...", type = JAXBElement.class, required = false)
protected JAXBElement<String> signature;
... the rest: getters/setters
When in a request an element of this type happens to look like:
<ns2:Credentials>
<ns4:string>login</ns4:string>
<ns4:string>password</ns4:string>
<ns4:string>signature</ns4:string>
</ns2:Credentials>
But it loses names of elements inside the type, the fragment above should look like this:
<ns2:Credentials>
<ns4:UID>login</ns4:UID>
<ns4:PWD>password</ns4:PWD>
<ns4:Signature>signature</ns4:Signature>
</ns2:Credentials>
Why can it be and how to force client to behave in the correct way?
Update
Credentials object is created like this (of
is ObjectFactory
):
Credential cr = of.createCredential()
cr.setUID(of.createString(login))
cr.setPWD(of.createString(password))
cr.setSignature(of.createString(sign))
You get
<ns4:string>login</ns4:string>
because you use of.createString(login)
. Use something like of.createUID(...)
if you want ns4:UID
.
The thing is, JAXBElement<String>
has a string value (ex. login) but also the name of the element (getValue()
and getName()
respectively). This name is what gives the XML element its name. The ObjectFactory
generated by wsimport
/xjc
usually contains methods to generate such JAXBElement
instances. These createFoo
-methods take value as input and wrap them in JAXBElement
s with the corresponding XML names. So when you use createString
, you actually say you want string
as element name. String
in createString
is for element name, not for the value type.
So your ObjectFactory
should also have methods like createUID
, createPWD
, createSignature
etc. Use those methods instead of createString
.
By the way, have you actually tried debugging it? The whole story would be pretty obvious if you've taken a look at the source code of ObjectFactory
, any reason to avoid that?