Web Service - Start from Java
This section provides guidelines for designing a XML schema exported by a Java web service designed starting from Java. JAXB 2.0 provides a rich set of annotations and types for mapping Java classes to different XML Schema constructs. The guidelines provide guidance on using JAXB 2.0 annotations and types so that developer friendly bindings may be generated by XML serialization mechanisms (svcutil) on WCF client.
Not all JAXB 2.0 annotations are included here; not all are relevant from an interoperability standpoint. For example, the annotation
@XmlAccessorType
provides control over default serialization of fields and properties in a Java class but otherwise has no effect on the on-the-wire XML representation or the XML schema generated from a Java class. Select JAXB 2.0 annotations are therefore not included here in the guidance.The guidance includes several examples, which use the following conventions:
DataTypes
Primitives and Wrappers
Guideline: Java primitive and wrapper classes map to slightly different XML schema representations. Therefore, .NET bindings will vary accordingly.
Example: A Java primitive type and its corresponding wrapper class
//-- Java code fragment public class StockItem{ public Double wholeSalePrice; public double retailPrice; } //--Schema fragment <xs:complexType name="stockItem"> <xs:sequence> <xs:element name="wholeSalePrice" type="xs:double" minOccurs="0"/> <xs:element name="retailPrice" type="xs:double"/> </xs:sequence> </xs:complexType> //-- .NET C# auto generated code from schema public partial class stockItem { private double wholeSalePrice; private bool wholeSalePriceFieldSpecified; private double retailPrice; public double wholeSalePrice { get{ return this.wholeSalePrice;} set{this.wholeSalePrice=value} } public bool wholeSalePriceSpecified { get{ return this.wholeSalePriceFieldSpecified;} set{this.wholeSalePriceFieldSpecified=value} } public double retailPrice { get{ return this.retailPrice;} set{this.retailPrice=value} } } //-- C# code fragment stockItem s = new stockItem(); s.wholeSalePrice = Double.parse("198.92"); s.wholeSalePriceSpecified = true s.retailPrice = Double.parse("300.25");BigDecimal
Guideline: Limit decimal values to the range and precision of .NET's
System.decimal
.
java.math.BigDecimal
maps toxs:decimal
. .NET mapsxs:decimal
toSystem.decimal
. These two data types support different range and precision.java.math.BigDecimal
supports arbitrary precision.System.decimal
does not. For interoperability use only values within the range and precision ofSystem.decimal
. (SeeSystem.decimal.Minvalue
andSystem.decimal.Maxvalue
.) Any values outside of this range require a customized .NET client.Example:
BigDecimal
usage//--- Java code fragment
public class RetBigDecimal {
private BigDecimal arg0;
public BigDecimal getArg0() { return this.arg0; }
public void setArg0(BigDecimal arg0) { this.arg0 = arg0; }
}//--- Schema fragment
<xs:complexType name="retBigDecimal">
<xs:sequence>
<xs:element name="arg0" type="xs:decimal" minOccurs="0"/>
</xs:sequence>
</xs:complexType>//--- .NET auto generated code from schema
public partial class retBigDecimal{
private decimal arg0Field;
private bool arg0FieldSpecified;
public decimal arg0 {
get { return this.arg0Field;}
set { this.arg0Field = value;}
}
public bool arg0Specified {
get { return this.arg0FieldSpecified;}
set { this.arg0FieldSpecified = value;}
}
}//--- C# code fragment
System.CultureInfo engCulture = new System.CultureInfo("en-US");
retBigDecimal bd = new retBigDecimal();
bd.arg0 = System.decimal.MinValue;
retBigDecimal negBd = new retBigDecimal();
negBd = System.decimal.Parse("-0.0", engCulture);java.net.URI
Guideline: Use the
@XmlSchemaType
annotation for a strongly typed binding to a .NET client generated with theDataContractSerializer
.
java.net.URI
maps toxs:string
. .NET mapsxs:string
toSystem.string
. Annotation@XmlSchemaType
can be used to define a more strongly typed binding to a .NET client generated with theDataContractSerializer
.@XmlSchemaType
can be used to mapjava.net.URI
toxs:anyURI
. .NET'sDataContractSerializer
andXmlSerializer
bindxs:anyURI
differently:Thus, the above technique only works if the WSDL is processed using
DataContractSerializer
.Example:
@XmlSchemaType
andDataContractSerializer
// Java code fragment public class PurchaseOrder { @XmlSchemaType(name="anyURI") public java.net.URI uri; } //-- Schema fragment <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="uri" type="xs:anyURI" minOccurs="0"/> </xs:sequence> </xs:complexType> //--- .NET auto generated code from schema //--- Using svcutil.exe /serializer:DataContractSerializer <wsdl file> public partial class purchaseOrder : object, System.Runtime.Serialization.IExtensibleDataObject { private System.Uri uriField; //-- ..... other gernerated code ........ public System.Uri uri { get { return this.uriField; } set { this.uriField = value; } } } //--- C# code fragment purchaseOrder tmpU = new purchaseOrder() tmpU.uri = new System.Uri("../Hello", System.UriKind.Relative);Example:
@XmlSchemaType
andXmlSerializer
// Java code fragment public class PurchaseOrder { @XmlSchemaType(name="anyURI") public java.net.URI uri; } //--- .NET auto generated code from schema //--- Using svcutil.exe /serializer:XmlSerializer <wsdl file> public partial class purchaseOrder { private string uriField; public string uri { get { return this.uriField; } set { this.uriField = value; } } } //--- C# code fragment purchaseOrder tmpU = new purchaseOrder() tmpU.uri = "mailto:mailto:mduerst@ifi.unizh.ch";Duration
Guideline: Use .NET's
System.Xml.XmlConvert
to generate a lexical representation ofxs:duration
when the binding is to a type ofSystem.string
.
javax.xml.datatype.Duration
maps toxs:duration
. .NET mapsxs:duration
to a different datatype forDataContractSerializer
andXmlSerializer
.When
xs:duration
is bound to .NETSystem.string
, thestring
value must be a lexical representation forxs:duration
. .NET provides utilitySystem.Xml.XmlConvert
for this purpose.Example: Mapping
xs:duration
usingDataContactSerializer
//-- Java code fragment public class PurchaseReport { public javax.xml.datatype.Duration period; } //-- Schema fragment <xs:complexType name="purchaseReport"> <xs:sequence> <xs:element name="period" type="xs:duration" minOccurs="0"/> </xs:sequence> </xs:complexType> //-- .NET auto generated code from schema //-- Using svcutil.exe /serializer:DataContractSerializer <wsdl file> public partial class purchaseReport: object, System.Runtime.Serialization.IExtensibleDataObject { private System.TimeSpan periodField; //-- ..... other gernerated code ........ public System.TimeSpan period { get { return this.periodField; } set { this.periodField = value; } } } //-- C# code fragment purchaseReport tmpR = new purchaseReport(); tmpR.period = new System.TimeSpan.MaxValue;Example: Mapping
xs:duration
usingXmlSerializer
//-- .NET auto generated code from schema //-- Using svcutil.exe /serializer:XmlSerializer <wsdl file> public partial class purchaseReport { private string periodField; public string period { get { return this.periodField; } set { this.periodField = value; } } } //-- C# code fragment purchaseReport tmpR = new purchaseReport(); tmpR.period = System.Xml.XmlConvert.ToString(new System.TimeSpan(23, 0,0));Binary Types
java.awt.Image
,javax.xml.transform.Source
, andjavax.activation.DataHandler
map toxs:base64Binary
. .NET mapsxs:base64Binary
tobyte[]
.JAXB 2.0 provides the annotation
@XmlMimeType
, which supports specifying the content type, but .NET ignores this information.Example: Mapping
java.awt.Image
without@XmlMimeType
//-- Java code fragment public class Claim{ public java.awt.Image photo; } //-- Schema fragment <xs:complexType name="claim"> <xs:sequence> <xs:element name="photo" type="xs:base64Binary" minOccurs="0"/> </xs:sequence> </xs:complexType> //-- .NET auto generated code from schema public partial class claim : object, System.Runtime.Serialization.IExtensibleDataObject { private byte[] photoField; //-- ..... other gernerated code ....... public byte[] photo { get { return this.photoField; } set { this.photoField = value; } } } //-- C# code fragment try { claim tmpC = new claim(); System.IO.FileStream f = new System.IO.FileStream( "C:\\icons\\circleIcon.gif", System.IO.FileMode.Open); int cnt = (int)f.Length; tmpC.photo = new byte[cnt]; int rCnt = f.Read(tmpC.photo, 0, cnt); } catch (Exception e) { Console.WriteLine(e.ToString()); }Example: Mapping
java.awt.Image
with@XmlMimeType
//-- Java code fragment public class Claim{ @XmlMimeType("image/gif") public java.awt.Image photo; } //-- Schema fragment <xs:complexType name="claim"> <xs:sequence> <xs:element name="photo" ns1:expectedContentTypes="image/ gif" type="xs:base64Binary" minOccurs="0" xmlns:ns1="http://www.w3.org/2005/05/xmlmime"/> </xs:sequence> </xs:complexType> //-- Using the @XmlMimeType annotation doesn't change .NET //--auto generated code public partial class claim : object, System.Runtime.Serialization.IExtensibleDataObject { private byte[] photoField; //-- ..... other gernerated code ....... public byte[] photo { get { return this.photoField; } set { this.photoField = value; } } } //-- This code is unchanged by the different schema //-- C# code fragment try { claim tmpC = new claim(); System.IO.FileStream f = new System.IO.FileStream( "C:\\icons\\circleIcon.gif", System.IO.FileMode.Open); int cnt = (int)f.Length; tmpC.photo = new byte[cnt]; int rCnt = f.Read(tmpC.photo, 0, cnt); } catch (Exception e) { Console.WriteLine(e.ToString()); }XMLGregorianCalendar
Guideline: Use
java.xml.datatype.XMLGregorianCalendar
instead ofjava.util.Date and java.util.Calendar
.
XMLGregorianCalendar
supports the following XML schema calendar types:xs:date
,xs:time
,xs:dateTime
,xs:gYearMonth
,xs:gMonthDay
,xs:gYear
,xs:gMonth
, andxs:gDay
. It is statically mapped toxs:anySimpleType,
the common schema type from which all the XML schema calendar types are dervived. .NET mapsxs:anySimpleType
toSystem.string
.
java.util.Date
andjava.util.Calendar
map toxs:dateTime
, but don't provide as complete XML support asXMLGregorianCalendar
does.Guideline: Use annotation
@XmlSchemaType
for a strongly typed binding ofXMLGregorianCalendar
to one of the XML schema calendar types.Example:
XmlGregorianCalendar
without@XmlSchemaType
//-- Java code fragment public class PurchaseOrder{ public javax.xml.datatype.XMLGregorianCalendar orderDate; } //-- Schema fragment <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="orderDate" type="xs:anySimpleType" minOccurs="0"/> </xs:sequence> </xs:complexType> //-- .NET auto generated code from schema public partial class purchaseOrder { private string orderDateField; public string orderDate { get { return this.orderDateField; } set { this.orderDateField = value; } } } //-- C# code fragment purchaseOrder tmpP = new purchaseOrder(); tmpP.orderDate = System.Xml.XmlConvert.ToString( System.DateTime.Now, System.Xml.XmlDateTimeSerializerMode.RoundtripKind);Example:
XMLGregorianCalendar
with@XmlSchemaType
//-- Java code fragment public class PurchaseOrder{ @XmlSchemaType(name="dateTime") public javax.xml.datatype.XMLGregorianCalendar orderDate; } //-- Schema fragment <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="orderDate" type="xs:dateTime" minOccurs="0"/> </xs:sequence> </xs:complexType> //-- .NET auto generated code from schema public partial class purchaseOrder : object, System.Runtime.Serialization.IExtensibleDataObject { private System.Runtime.Serialization.ExtensionDataObject extensionDataField; private System.DateTime orderDateField; public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } public System.DateTime orderDate { get { return this.orderDateField; } set { this.orderDateField = value; } } } //-- C# code fragment purchaseOrder tmpP = new purchaseOrder(); tmpP.orderDate = System.DateTime.Now;UUID
Guideline: Use Leach-Salz variant of UUID at runtime.
java.util.UUID
maps to schema typexs:string
. .NET mapsxs:string
toSystem.string
. The constructors injava.util.UUID
allow any variant of UUID to be created. Its methods are for manipulation of the Leach-Salz variant.Example: Mapping UUID
//-- Java code fragment public class ReportUid{ public java.util.UUID uuid; } //-- Schema fragment <xs:complexType name="reportUid"> <xs:sequence> <xs:element name="uuid" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> //-- .NET auto generated code from schema public partial class reportUid: object, System.Runtime.Serialization.IExtensibleDataObject { private System.Runtime.Serialization.ExtensionDataObject extensionDataField; private string uuidField; public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } public string uuid { get { return this.uuidField; } set { this.uuidField = value; } } } //-- C# code fragment reportUid tmpU = new reportUid(); System.Guid guid = new System.Guid("06b7857a-05d8-4c14-b7fa- 822e2aa6053f"); tmpU.uuid = guid.ToString();Type Variable
A typed variable maps to
xs:anyType
. .NET mapsxs:anyType
toSystem.Object
.Example: Using a typed variable
// Java class public class Shape <T> { private T xshape; public Shape() {}; public Shape(T f) { xshape = f; } } <xs:complexType name="shape"> <xs:sequence> <xs:element name="xshape" type="xs:anyType" minOccurs="0"/> </xs:sequence> </xs:complexType> // C# code generated by svcutil public partial class shape { private object xshapeField; public object xshape { get { return this.xshapeField; } set { this.xshapeField = value; } } }Collections
Java collections types -
java.util.Collection
and its subtypes, array, List, and parameterized collection types (e.g.List<Integer>
) can be mapped to XML schema in different ways and can be serialized in different ways. The following examples show .NET bindings.List of nillable elements
By default, a collection type such as
List<Integer>
maps to a XML schema construct that is a repeating unbounded occurrence of an optional and nillable element. .NET binds the XML schema construct toSystem.Nullable<int>[]
. The element is optional and nillable. However, when marshalling JAXB marshaller will always marshal a null value usingxsi:nil
.Example: Collection to a list of nillable elements
//-- Java code fragment @XmlRootElement(name="po") public PurchaseOrder { public List<Integer> items; } //-- Schema fragment <xs:element name="po" type="purchaseOrder"> <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="items" type="xs:int" nillable="true" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> //--- JAXB XML serialization <po> <items> 1 </items> <items> 2 </items> <items> 3 </items> </po> <po> <items> 1 </items> <items xsi:nil=true/> <items> 3 </items> </po> //-- .NET auto generated code from schema partial class purchaseOrder { private System.Nullable<int>[] itemsField; public System.Nullable<int>[] items { get { return this.itemsField; } set { this.itemsField = value; } } }List of optional elements
This is the same as above except that a collection type such as
List<Integer>
maps to a repeating unbounded occurrence of an optional (minOccurs="0"
) but not nillable element. This in turn binds to .NET typeint[]
. This is more developer friendly. However, when marshalling, JAXB will marshal a null value within theList<Integer>
as a value that is absent from the XML instance.Example: Collection to a list of optional elements
//-- Java code fragment @XmlRootElement(name="po") public PurchaseOrder { @XmlElement(nillable=false) public List<Integer> items; } //-- Schema fragment <xs:element name="po" type="purchaseOrder"> <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="items" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> // .NET auto generated code from schema partial class purchaseOrder { private int[] itemsField; public int[] items { get { return this.itemsField; } set { this.itemsField = value; } } }List of values
A collection such as
List<Integer>
can be mapped to a list of XML values (i.e. a XML schema list simple type) using annotation@XmlList
. .NET maps list simple type to a .NETSystem.string
.Example: Collection to a list of values using
@XmlList
//-- Java code fragment @XmlRootElement(name="po") public PurchaseOrder { @XmlList public List<Integer> items; } //-- Schema fragment <xs:element name="po" type="purchaseOrder"> <xs:complexType name="purchaseOrder"> <xs:element name="items" minOccurs="0"> <xs:simpleType> <xs:list itemType="xs:int"/> </xs:simpleType> </xs:element> </xs:complexType> //-- XML serialization <po> <items> 1 2 3 </items> </po> // .NET auto generated code from schema partial class purchaseOrder { private string itemsField; public string items { get { return this.itemsField; } set { this.itemsField = value; } }Arrays
Example: Single and multidimensional Arrays
//-- Java code fragment public class FamilyTree { public Person[] persons; public Person[][] family; } // .NET auto generated code from schema public partial class familyTree { private person[] persons; private person[][] families; public person[] persons { get { return this.membersField; } set { this.membersField = value; } } public person[][] families { get { return this.familiesField; } set { this.familiesField = value; } } }Fields/Properties
The following guidelines apply to mapping of Javabean properties and Java fields, but for brevity Java fields are used.
@XmlElement
The
@XmlElement
annotation maps a property/field to an XML element. This is also the default mapping in the absence of any other JAXB 2.0 annotations. The annotation parameters in@XmlElement
can be used to specify whether the element is optional or required, nillable or not. The following examples illustrate the corresponding bindings in the .NET client.Example: Map a field/property to a nillable element
//-- Java code fragment public class PurchaseOrder { // Map a field to a nillable XML element @javax.xml.bind.annotation.XmlElement(nillable=true) public java.math.BigDecimal price; } //-- Schema fragment <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="price" type="xs:decimal" nillable="true" minOccurs="0" /> </xs:sequence> </xs:complexType> // .NET auto generated code from schema public partial class purchaseOrder { private System.Nullable<decimal> priceField; private bool priceFieldSpecified; public decimal price { get { return this.priceField; } set { this.priceField = value; } } public bool priceSpecified { { get { return this.priceFieldSpecified; } set { this.priceFieldSpecified = value;} }Example: Map property/field to a nillable, required element
//-- Java code fragment public class PurchaseOrder { // Map a field to a nillable XML element @XmlElement(nillable=true, required=true) public java.math.BigDecimal price; } //-- Schema fragment <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="price" type="xs:decimal" nillable="true" minOccurs="1" /> </xs:sequence> </xs:complexType> // .NET auto generated code from schema public partial class purchaseOrder { private System.Nullable<decimal> priceField; public decimal price { get { return this.priceField; } set { this.priceField = value; } } }@XmlAttribute
A property/field can be mapped to an XML attribute using
@XmlAttribute
annotation. .NET binds an XML attribute to a property.Example: Mapping field/property to XML attribute
//-- Java code fragment public class UKAddress extends Address { @XmlAttribute public int exportCode; } //-- Schema fragment <! XML Schema fragment --> <xs:complexType name="ukAddress"> <xs:complexContent> <xs:extension base="tns:address"> <xs:sequence/> <xs:attribute name="exportCode" type="xs:int"/> </xs:extension> </xs:complexContent> </xs:complexType> // .NET auto generated code from schema public partial class ukAddress : address { private int exportCodeField; public int exportCode { get { return this.exportCodeField; } set { this.exportCodeField = value; } } }@XmlElementRefs
Guideline:
@XmlElementRefs
maps to axs:choice
. This binds to a property with name "item" in the C# class. If there is another field/property named "item" in the Java class, there will be a name clash that .NET will resolve by generatingname
. To avoid the nameclash, either change the name or use customization, for example@XmlElement(name="foo")
.Example: Mapping a field/property using @XmlElementRefs
//-- Java code fragment public class PurchaseOrder { @XmlElementRefs({ @XmlElementRef(name="plane", type=PlaneType.class), @XmlElementRef(name="auto", type=AutoType.class)}) public TransportType shipBy; } @XmlRootElement(name="plane") public class PlaneType extends TransportType {} @XmlRootElement(name="auto") public class AutoType extends TransportType { } @XmlRootElement public class TransportType { ... } //-- Schema fragment <!-- XML schema generated by wsgen --> <xs:complexType name="purchaseOrder"> <xs:choice> <xs:element ref="plane"/> <xs:element ref="auto"/> </xs:choice> </xs:complexType> <!-- XML global elements --> <xs:element name="plane" type="autoType" /> <xs:element name="auto" type="planeType" /> <xs:complexType name="autoType"> <!-- content omitted - details not relevant to example --> </xs:complexType> </xs:complexType name="planeType"> <!-- content omitted - details not relevant to example --> </xs:complexType> // .NET auto generated code from schema public partial class purchaseOrder { private transportType itemField; [System.Xml.Serialization.XmlElementAttribute("auto", typeof(autoType), Order=4)] [System.Xml.Serialization.XmlElementAttribute("plane", typeof(planeType), Order=4)] public transportType Item { get { return this.itemField; } set { this.itemField = value; } } public partial class planeType { ... } ; public partial class autoType { ... } ;Class
A Java class can be mapped to different XML schema type and/or an XML element. The following guidelines apply to the usage of annotations at the class level.
@XmlType - Anonymous type
Guideline: Prefer mapping class to named XML schema type rather than an anonymous type for a better .NET type binding.
The
@XmlType
annotation is used to customize the mapping of a Java class to an anonymous type. .NET binds an anonymous type to a .NET class - one per reference to the anonymous type. Thus, each Java class mapped to an anonymous type can generate multiple classes on the .NET client.Example: Mapping a Java class to an anonymous type using
@XmlType
//-- Java code fragment public class PurchaseOrder { public java.util.List<Item> item; } @XmlType(name="") public class Item { public String productName; ... } //-- Schema fragment <xs:complexType name="purchaseOrder"> <xs:sequence> <xs:element name="item"> <xs:complexType> <xs:sequence> <xs:element name="productName" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> // C# code generated by svcutil public partial class purchaseOrder { private purchaseOrderItem[] itemField; System.Xml.Serialization.XmlElementAttribute("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true, Order=0)] public purchaseOrderItem[] item { get { return this.itemField; } set { this.itemField = value; } } // .NET auto generated code from schema public partial class purchaseOrderItem { private string productNameField; public string productName { get { return this.productNameField; } set { this.productNameField = value; } } }@XmlType - xs:all
Guideline: Avoid using
XmlType(propOrder=:{})
.
@XmlType(propOrder={})
maps a Java class to a XML Schema complex type withxs:all
content model. Since XML Schema places severe restrictions onxs:all
, the use of@XmlType(propOrder={})
is therefore not recommended. So, the following example shows the mapping of a Java class toxs:all
, but the corresponding .NET code generated bysvcutil
is omitted.Example: Mapping a class to
xs:all
using@XmlType
//-- Java code fragment @XmlType(propOrder={}) public class USAddress { public String name; public String street; } //-- Schema fragment <xs:complexType name="USAddress"> <xs:all> <xs:element name="name" type="xs:string"/> <xs:element name="street" type="xs:string"/> ... </xs:all> </xs:complexType>@XmlType - simple content
Guideline: A class can be mapped to a
complexType
with asimpleContent
using@XmlValue
annotation. .NET binds the Java property annotated with@XmlValue
to a property with name "value".Example: Class to
complexType
withsimpleContent
//-- Java code fragment public class InternationalPrice { @XmlValue public java.math.BigDecimal price; @XmlAttribute public String currency; } //-- Schema fragment <xs:complexType name="internationalPrice"> <xs:simpleContent> <xs:extension base=xs:decimal"> xs:attribute name="currency" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> // .NET auto generated code from schema public partial class internationalPrice { private string currencyField; private decimal valueField; public string currency { get { return this.currencyField; } set { this.currencyField = value;} } public decimal Value { get { return this.valueField; } set { this.valueField = value;} } }Open Content
JAXB 2.0 supports the following annotations for defining open content. (Open content allows content not statically defined in XML schema to occur in an XML instance):
Example: Using
@XmlAnyElement
for open content//-- Java code fragment @XmlType(propOrder={"name", "age", "oc"}) public class OcPerson { @XmlElement(required=true) public String name; public int age; // Define open content @XmlAnyElement public List<Object> oc; } //-- Schema fragment <xs:complexType name="ocPerson"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="age" type="xs:int"/> <xs:any minOccurs="0" maxOccurs="unbounded"> </xs:sequence> </xs:complexType> // .NET auto generated code from schema public class ocPerson { private String name; private int age; private System.Xml.XmlElement[] anyField;< public String name { ... } public int age { ... } public System.Xml.XmlElement[] Any { { get { return this.anyField; } set { this.anyField = value; } } }Example: Open content using
@XmlAnyAttribute
//-- Java code fragment @XmlType(propOrder={"name", "age"} public class OcPerson { public String name; public int age; // Define open content @XmlAnyAttribute public java.util.Map oc; } //-- Schema fragment <xs:complexType name="ocPerson"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="age" type="xs:int"/> </xs:sequence> <xs:anyAttribute/> </xs:complexType> // .NET auto generated code from schema public class ocPerson { private String name; private double age; private System.Xml.XmlAttribute[] anyAttrField;< public String name { ... } public double age { ... } public System.Xml.XmlElement[] anyAttr { { get { return this.anyAttrField; } set { this.anyAttrField = value; } } }Enum Type
A Java
enum
type maps to an XML schema type constrained by enumeration facets. This, in turn, binds to .NET typeenum
type.Example: Java
enum
->xs:simpleType
(withenum
facets) -> .NETenum
//-- Java code fragment public enum USState {MA, NH} //-- Schema fragment <xs:simpleType name="usState"> <xs:restriction base="xs:string"> <xs:enumeration value="NH" /> <xs:enumeration value="MA" /> </xs:restriction> </xs:simpleType> // .NET auto generated code from schema public enum usState { NH, MA }Package
The following package level JAXB annotations are relevant from an interoperability standpoint:
@XmlSchema
- customizes the mapping of package to XML namespace.@XmlSchemaType
- customizes the mapping of XML schema built-in type. The@XmlSchemaType
annotation can also be used at the property/field level, as was seen in the previous example XMLGregorianCalendar.@XmlSchema
A package is mapped to an XML namespace. The following attributes of the XML namespace can be customized using the
@XmlSchema
annotation parameters:These XML namespace attributes are bound to .NET serialization attributes (for example,
XmlSerializer
attributes).Not Recommended Annotations
Any JAXB 2.0 annotation can be used but the following are not recommended: