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 DataContractSerializer may contain XML Schema constructs which result in JAXBElement<T> in generated code. A JAXBElement<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 the generateElementProperty customization 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") and nillable(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 generateElementProperty is false, 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 generateElementProperty to be set:

When processing a WCF service WSDL, it is recommended that the generateElementProperty customization 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 generateElementProperty attribute 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 Type
byte
xs:unsignedByte
uint
xs:unsignedInt
ushort
xs:unsignedShor
ulong
xs: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:type construct, 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:type is not preserved across an unmarshal/marshal operation.

One way to preserve and roundtrip the xsi:type is to use the mapSimpleTypeDef customization. The customization makes the mapping of XML Schema Part 2 datatypes one--to-one by generating additional Java classes. Thus, xs:unsignedShort will be bound to its own class rather than int, as shown:

//Java class to which xs:unsignedShort is bound
public class UnsignedShort { ... } 

The following illustrates how the xsi:type is preserved across an unmarshal/marshal operation:

Guideline: Use mapSimpleTypedef customization where roundtripping of XML Schema types in Table 10-1 are used in xsi: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 mapSimpleTypeDef customization is shown below.

<jxb: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 mapSimpleTypeDef="true"/>
  </jaxb:bindings>