Customizations for WCF Service WSDL
When developing either a Java web service or a Java client from a WCF service WSDL generated using
DataContractSerializer, the following JAXB 2.0 customizations are useful and/or required.The following sections explain the use and rationale of these customizations.
generateElementProperty
WCF service WSDL generated from a programming language such as C# using
DataContractSerializermay contain XML Schema constructs which result inJAXBElement<T>in generated code. AJAXBElement<T>type can also sometimes be generated when a WSDL contains advanced XML schema features such as substitution groups or elements that are both optional and nillable. In all such cases,JAXBElement<T>provides roundtripping support of values in XML instances. However,JAXBElement<T>is not natural to a Java developer. So thegenerateElementPropertycustomization can be used to generate an alternate developer friendly but lossy binding. The different bindings along with the trade-offs are discussed below.Default Binding
The following is the default binding of an optional
(minOccurs="0")andnillable(nillable="true")element:<!-- XML schema fragment <xs:element name="person" type="Person" <xs:complexType name="Person"> <xs:sequence> <xs:element name="name" type="xs:string" nillable="true"minOccurs="0"/> </xs:sequence> </xs:complexType> // Binding public class Person { JAXBElement<String> getName() {...}; public void setName(JAXBElement<String> value) {...} }Since the XML element "name" is both optional and nillable, it can be represented in an XML instance in one of following ways:
<!-- Absence of element name--> <person> <-- element name is absent --> </person> <!-- Presence of an element name --> <person> <name xsi:nil="true"/> </person>The
JAXBElement<String> type roundtrips the XML representation of "name" element across an unmarshal/marshal operation.Customized Binding
When
generateElementPropertyisfalse, the binding is changed as follows:// set JAXB customization generateElementProperty="false"/> public class Person { String getName() {...} public void setName(String value) {...} }The above binding is more natural to Java developer than
JAXBElement<String>. However, it does not roundtrip the value of<name>.JAXB 2.0 allows
generateElementPropertyto be set:When processing a WCF service WSDL, it is recommended that the
generateElementPropertycustomization be set in<jaxb:globalBindings>:<jaxb:bindings version="2.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jaxb:bindings schemaLocation="schema-importedby-wcfsvcwsdl" node="/xs:schema"> <jaxb:globalBindings generateElementProperty="false"/> </jxb:bindings>
Note: The
generateElementPropertyattribute was introduced in JAXB 2.1.
mapSimpleTypeDef
XML Schema Part 2: Datatype defines facilities for defining datatypes for use in XML Schemas. .NET platform introduced the CLR types for some of the XML schema datatypes as described in Table 10-1.
Table 10-1 CLR to XML Schema Type Mapping CLR Type XML Schema Typebytexs:unsignedByteuintxs:unsignedIntushortxs:unsignedShorulongxs:unsignedLong
However, there are no corresponding Java types that map to the XML Schema types listed in Table 10-1. Furthermore, JAXB 2.0 maps these XML schema types to Java types that are natural to Java developer. However, this results in a mapping that is not one-to-one. For example:
The lack of a one-to-one mapping means that when XML Schema types shown in Table 10-1 are used in an
xsi:typeconstruct, they won't be preserved by default across an unmarshal followed by marshal operation. For example:// C# web method public Object retObject(Object objvalue); // Java web method generated from WCF service WSDL public Object retObject( Object objvalue); }The following illustrates why
xsi:typeis not preserved across an unmarshal/marshal operation.
- A value of type
uintis marshalled by WCF serialization mechanism as:
<objvalue xsi:type="xs:unsignedShort"/>- JAXB 2.0 unmarshaller unmarshals the value as an instance of
intand assigns it to parameterobjvalue.- The
objvalueis marshalled back by JAXB 2.0 marshaller with anxsi:typeofxs:int.
<objvalue xsi:type="xs:int"/>One way to preserve and roundtrip the
xsi:typeis to use themapSimpleTypeDefcustomization. The customization makes the mapping of XML Schema Part 2 datatypes one--to-one by generating additional Java classes. Thus,xs:unsignedShortwill be bound to its own class rather thanint, as shown:The following illustrates how the
xsi:typeis preserved across an unmarshal/marshal operation:
- A value of type
uintis marshalled by WCF serialization mechanism as:
<objvalue xsi:type="xs:unsignedShort"/>- JAXB 2.0 unmarshaller unmarshals the value as an instance of
UnsignedShortand assigns it to parameterobjvalue.- The
objvalueis marshalled back by JAXB 2.0 marshaller with anxsi:typeofxs:int.
<objvalue xsi:type="xs:unsignedShort"/>Guideline: Use
mapSimpleTypedefcustomization where roundtripping of XML Schema types in Table 10-1 are used inxsi:type. However, it is preferable to avoid the use of CLR types listed in Table 10-1 since they are specific to .NET platform.The syntax of the
mapSimpleTypeDefcustomization is shown below.