Chapter 2. SOAP 1.1 Web Service Standards

List and describe the encoding types used in a SOAP message.

The SOAP encoding style is based on a simple type system that is a generalization of the common features found in type systems in programming languages, databases and semi-structured data. A type either is a simple (scalar) type or is a compound type constructed as a composite of several parts, each with a type. This is described in more detail below. This section defines rules for serialization of a graph of typed objects. It operates on two levels. First, given a schema in any notation consistent with the type system described, a schema for an XML grammar may be constructed. Second, given a type-system schema and a particular graph of values conforming to that schema, an XML instance may be constructed. In reverse, given an XML instance produced in accordance with these rules, and given also the original schema, a copy of the original value graph may be constructed.

There are following SOAP encoding types:

  • Simple Types:

    • Strings

    • Enumerations

    • Array of Bytes

  • Compound Types:

    • Arrays

    • Structures

Simple Types

For simple types, SOAP adopts all the types found in the section "Built-in datatypes" of the "XML Schema Part 2: Datatypes" Specification, both the value and lexical spaces. Examples include: boolean (true, false, 0 or 1), byte, short, int, long, float, double, string (java.lang.String), decimal (java.math.BigDecimal), date (java.util.GregorianCalendar), dateTime (java.util.Date), SOAP-ENC:base64 (byte []).

The following examples are a SOAP representation of these primitive data types:

					
<element name="age" type="int"/>
<element name="height" type="float"/>
<element name="displacement" type="negativeInteger"/>
<element name="color">
  <simpleType base="xsd:string">
    <enumeration value="Green"/>
    <enumeration value="Blue"/>
  </simpleType>
</element>

<age>45</age>
<height>5.9</height>
<displacement>-450</displacement>
<color>Blue</color> 

					

Strings

The datatype "string" is defined in "XML Schema Part 2: Datatypes" Specification. Note that this is not identical to the type called "string" in many database or programming languages, and in particular may forbid some characters those languages would permit. (Those values must be represented by using some datatype other than xsd:string.) A string MAY be encoded as a single-reference or a multi-reference value. The containing element of the string value MAY have an "id" attribute. Additional accessor elements MAY then have matching "href" attributes. For example, two accessors to the same string could appear, as follows:


<greeting id="String-0">Hello</greeting>
<salutation href="#String-0"/>

					
However, if the fact that both accessors reference the same instance of the string (or subtype of string) is immaterial, they may be encoded as two single-reference values as follows:

<greeting>Hello</greeting>
<salutation>Hello</salutation>

					
Schema fragments for these examples could appear similar to the following:

<element name="greeting" type="SOAP-ENC:string"/>
<element name="salutation" type="SOAP-ENC:string"/>

					
(In this example, the type SOAP-ENC:string is used as the element's type as a convenient way to declare an element whose datatype is "xsd:string" and which also allows an "id" and "href" attribute. See the SOAP Encoding schema for the exact definition. Schemas MAY use these declarations from the SOAP Encoding schema but are not required to.)

Enumerations

Enumeration as a concept indicates a set of distinct names. A specific enumeration is a specific list of distinct values appropriate to the base type. For example the set of color names ("Green", "Blue", "Brown") could be defined as an enumeration based on the string built-in type. The values ("1", "3", "5") are a possible enumeration based on integer, and so on. "XML Schema Part 2: Datatypes" supports enumerations for all of the simple types except for boolean. The language of "XML Schema Part 1: Structures" Specification can be used to define enumeration types. If a schema is generated from another notation in which no specific base type is applicable, use "string". In the following schema example "EyeColor" is defined as a string with the possible values of "Green", "Blue", or "Brown" enumerated, and instance data is shown accordingly:


<element name="EyeColor" type="tns:EyeColor"/>

<simpleType name="EyeColor" base="xsd:string">
   <enumeration value="Green"/>
   <enumeration value="Blue"/>
   <enumeration value="Brown"/>
</simpleType>

<Person>
   <Name>Mikalai Zaikin</Name>
   <Age>29</Age>
   <EyeColor>Brown</EyeColor>
</Person>
									
					

Array of Bytes

An array of bytes MAY be encoded as a single-reference or a multi-reference value. The rules for an array of bytes are similar to those for a string. In particular, the containing element of the array of bytes value MAY have an "id" attribute. Additional accessor elements MAY then have matching "href" attributes. The recommended representation of an opaque array of bytes is the 'base64' encoding defined in XML Schemas, which uses the base64 encoding algorithm. However, the line length restrictions that normally apply to base64 data in MIME do not apply in SOAP. A "SOAP-ENC:base64" subtype is supplied for use with SOAP:


<picture xsi:type="SOAP-ENC:base64">
  aG93IG5vDyBicm73biBjb3cNCg==
</picture>
									
					

Polymorphic Accessor

Many languages allow accessors that can polymorphically access values of several types, each type being available at run time. A polymorphic accessor instance MUST contain an "xsi:type" attribute that describes the type of the actual value. For example, a polymorphic accessor named "cost" with a value of type "xsd:float" would be encoded as follows:


<cost xsi:type="xsd:float">29.95</cost>
									
					
as contrasted with a cost accessor whose value's type is invariant, as follows:

<cost>29.95</cost>
									
					

Compound types

A "struct" is a compound value in which accessor name is the only distinction among member values, and no accessor has the same name as any other.

An "array" is a compound value in which ordinal position serves as the only distinction among member values.

Structures

The members of a Compound Value are encoded as accessor elements. When accessors are distinguished by their name (as for example in a struct), the accessor name is used as the element name. Accessors whose names are local to their containing types have unqualified element names; all others have qualified names. The following is an example of a struct of type "book":


<book>
  <author>Mikalai Zaikin</author>
  <title>SCDJWS Study Guide</title>
  <intro>This is a certification guide</intro>
</book>

					
And this is a schema fragment describing the above structure:

<xsd:element name="book">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="author" type="xsd:string" />
      <xsd:element name="title" type="xsd:string" />
      <xsd:element name="intro" type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
									
					

Arrays

SOAP arrays are defined as having a type of "SOAP-ENC:Array" or a type derived there from. Arrays are represented as element values, with no specific constraint on the name of the containing element (just as values generally do not constrain the name of their containing element). Arrays can contain elements which themselves can be of any type, including nested arrays. New types formed by restrictions of SOAP-ENC:Array can also be created to represent, for example, arrays limited to integers or arrays of some user-defined enumeration. The representation of the value of an array is an ordered sequence of elements constituting the items of the array. Within an array value, element names are not significant for distinguishing accessors. Elements may have any name. In practice, elements will frequently be named so that their declaration in a schema suggests or determines their type. As with compound types generally, if the value of an item in the array is a single-reference value, the item contains its value. Otherwise, the item references its value via an "href" attribute. The following example is a schema fragment and an array containing integer array members:


<element name="myFavoriteNumbers" type="SOAP-ENC:Array"/>

<myFavoriteNumbers SOAP-ENC:arrayType="xsd:int[3]">
   <number>1</number> 
   <number>2</number> 
   <number>3</number> 
</myFavoriteNumbers>
									
					
In that example, the array "myFavoriteNumbers" contains several members each of which is a value of type xsd:int. This can be determined by inspection of the SOAP-ENC:arrayType attribute. Note that the SOAP-ENC:Array type allows unqualified element names without restriction. These convey no type information, so when used they must either have an xsi:type attribute or the containing element must have a SOAP-ENC:arrayType attribute. Naturally, types derived from SOAP-ENC:Array may declare local elements, with type information. As previously noted, the SOAP-ENC schema contains declarations of elements with names corresponding to each simple type in the "XML Schema Part 2: Datatypes" Specification. It also contains a declaration for "Array". Using these, we might write:

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:int[3]">
   <SOAP-ENC:int>1</SOAP-ENC:int>
   <SOAP-ENC:int>2</SOAP-ENC:int>
   <SOAP-ENC:int>3</SOAP-ENC:int>
</SOAP-ENC:Array>
									
					
Arrays can contain instances of any subtype of the specified arrayType. That is, the members may be of any type that is substitutable for the type specified in the arrayType attribute, according to whatever substitutability rules are expressed in the schema. So, for example, an array of integers can contain any type derived from integer (for example "int" or any user-defined derivation of integer). Similarly, an array of "address" might contain a restricted or extended type such as "internationalAddress". Because the supplied SOAP-ENC:Array type admits members of any type, arbitrary mixtures of types can be contained unless specifically limited by use of the arrayType attribute.

Array values may be structs or other compound values. For example an array of "my:order" structs :


<SOAP-ENC:Array SOAP-ENC:arrayType="my:order[2]">
   <order>
       <product>Melon</product>
       <price>0.99</price>
   </order>
   <order>
       <product>Apple</product>
       <price>1.49</price>
   </order>
</SOAP-ENC:Array>
									
					
Arrays may have other arrays as member values. The following is an example of an array of two arrays, each of which is an array of strings:

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[][2]">
  <item href="#array-1"/>
  <item href="#array-2"/>
</SOAP-ENC:Array>

<SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[3]">
  <item>row1column1</item>
  <item>row1column2</item>
  <item>row1column3</item>
</SOAP-ENC:Array>

<SOAP-ENC:Array id="array-2" SOAP-ENC:arrayType="xsd:string[2]">
  <item>row2column1</item>
  <item>row2column2</item>
</SOAP-ENC:Array>
									
					
Arrays may be multi-dimensional. In this case, more than one size will appear within the asize part of the arrayType attribute:


<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[2,3]">
  <item>row1column1</item> 
  <item>row1column2</item> 
  <item>row1column3</item> 
  <item>row2column1</item> 
  <item>row2ccolumn2</item> 
  <item>row2column3</item> 
</SOAP-ENC:Array>
									
					

NOTE: According to WS-I BP 1.0 you MUST NOT use soapenc:Array type for array declarations or soapenc:arrayType attribute in the type declarations.

Mapping between XML Schema types and SOAP Java types

Table 2.1. Mapping between XML Schema types and SOAP Java types

XML Schema typeSOAP Java type
stringjava.lang.String
integerjava.math.BigInteger
intint
intjava.lang.Integer (if nillable="true")
longlong
longjava.lang.Long (if nillable="true")
shortshort
shortjava.lang.Short (if nillable="true")
decimaljava.math.BigDecimal
floatfloat
floatjava.lang.Float (if nillable="true")
doubledouble
doublejava.lang.Double (if nillable="true")
booleanboolean
booleanjava.lang.Boolean (if nillable="true")
bytebyte
bytejava.lang.Byte (if nillable="true")
dateTimejava.util.GregorianCalendar
base64Binarybyte[]
hexBinarybyte[]
timejava.util.GregorianCalendar
datejava.util.GregorianCalendar
anySimpleTypejava.lang.String
anyjavax.xml.soap.SOAPElement

Element that is nillable, meaning that the element CAN BE EMPTY without causing a validation error. For each of the XML schema built-in types that map to a Java primitive, there is a corresponding Java primitive wrapper that can be used if a nillable="true" attribute is specified.

Example of mapping XML Schema-Java class

XML Schema:


<schema>
  <complexType name="Address">
    <sequence>
      <element name="street" nillable="true" type="xsd:string"/>  
      <element name="city" nillable="true" type="xsd:string"/>
      <element name="state" nillable="true" type="xsd:string"/>
      <element name="zip" type="xsd:int"/>    
    </sequence>
  </complexType>
</schema>
					
					
Java class:
public class Address {
	public String street;
	public String city;
	public String state;
	public int zip;
} 
					
NOTE: Since zip is not nillable, it can be primitive, otherwise it would be:

XML Schema:


<schema>
  <complexType name="Address">
    <sequence>
      <element name="street" nillable="true" type="xsd:string"/>  
      <element name="city" nillable="true" type="xsd:string"/>
      <element name="state" nillable="true" type="xsd:string"/>
      <element name="zip" nillable="true" type="xsd:int"/>    
    </sequence>
  </complexType>
</schema>
					
					
Java class:
public class Address {
	public String street;
	public String city;
	public String state;
	public Integer zip;
} 
					

In XML Schema, we can use nillable attribute to indicate that whether the element's content could be nil, as in <xsd:element name="birthDate" type="xsd:date" nillable="true"/>. If the content of an element is nil, we can use xsi:nil attribute to signal the processor, as in <birthDate xsi:nil="true" /> and this element must not contain any content.

More examples on nillable attribute. Consider following XML Schema:

					
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  <xsd:element name="rootElement" nillable="true"> 
    <xsd:complexType> 
      <xsd:sequence> 
        <xsd:element name="myElement" type="xsd:string"/> 
      </xsd:sequence> 
    </xsd:complexType> 
  </xsd:element> 
</xsd:schema>
 					
					
VALID:

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
	<myElement>I am valid</myElement> 
</rootElement> 
					
					
VALID:

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:nil="true"  /> 
					
					
INVALID (when xsi:nil is true, the element MUST BE EMPTY):

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:nil="true"> 
	<myElement>I am NOT valid</myElement> 
</rootElement> 
					
					
INVALID (element rootElement MUST have myElement child and xsi:nil has not been set to true):

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /> 
					
					

Mapping arbitrary XML content to Java

The <xsd:any/> element is an element that represents arbitrary XML content within an XML document. It is what its name indicates: any kind of XML. This lets you create complex type definitions in an XML Schema without describing what the exact structure of certain parts of the complex type is. Here is an example that shows the definition of a type called Order. It contains two regular elements and one <xsd:any/> element:

					
<schema elementFormDefault="qualified"   
   xmlns="http://www.w3.org/2001/XMLSchema">

   <complexType name="Order">
      <sequence>
         <element name="date" nillable="true" type="xsd:dateTime"/>
         <element name="customer" nillable="true" type="xsd:string"/>
         <xsd:any maxOccurs="unbounded"/>
      </sequence>
   </complexType>
</schema>
					
					
An instance of this type can contain any number of additional XML elements without violating the schema definition. You can add additional information to an Order element without defining its format in the schema. The JAX-RPC 1.1 specification defines that <xsd:any/> element is mapped to the SAAJ's javax.xml.soap.SOAPElement interface. This means that the Service Endpoint Interface [SEI] will contain a parameter or return value of type javax.xml.soap.SOAPElement for each place in the schema where <xsd:any/> was used and, respectively, javax.xml.soap.SOAPElement[] if the maxOccurs attribute is bigger than 1. Therefore, a JAX-RPC tool will generate the following class from the sample schema above:
public class Order implements java.io.Serializable {
    private java.util.GregorianCalendar date;
    private java.lang.String customer;
    private javax.xml.soap.SOAPElement[] _any;
    ...
}
					
This approach can be usefule when your Web service uses some data that you don't want to be mapped into a Java class, but rather want to let the JAX-RPC engine hand it to the implementation in its XML form. The implementation could then parse it or simply pass it on as XML for further processing in the backend application. Similarly, you can create a client proxy that lets you pass in a SOAPElement rather than a mapped Java object.

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCBCD 1.3 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     Free SCJP 5.0 (Tiger) Study Guide     Free Mock Exam Engine     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     IBM Test 000-255. Developing with IBM Rational Application Developer for WebSphere Software V6 Study Guide