Library articles and tutorials

Web Services Interoperability between J2EE and .NET - Part 2

Collection of complex data types

Collection objects might contain elements of any data types. Thus, many consider them as weakly-typed data structures. That makes them a wonderful programming tool. In object-oriented programming, there are rich libraries of collection types. In Java for example, there are:

  • java.util.Hashtable
  • Vectors
  • Hashmap
  • Set
  • ArrayList
While in C#, there are:
  • System.Collections.Hashtable
  • SortedList
  • Queue
  • Stack
  • ArrayList

If exposed across Web services, these collection types can cause insurmountable problems. The problem lies in how the receiving side is able to understand the serialized Simple Object Access Protocol (SOAP) messages that contain the weakly-typed object elements and native data types.

Even though some collection types look extremely similar between languages, such as System.Collections.ArrayList in C# and java.util.ArrayList in Java, remember that the elements in the collections are generic references. To accurately unmarshall the XML representation of a collection, consumers must have prior knowledge of the original concrete types. The burden is on the toolkit developers to interpret the XML Schemas published by the Web services providers and map the SOAP messages to the native data - - not an easy task for the weakly-typed collections.

Now, let's take a look at what the XML Schemas look like for the Collection types. This time, consider a Web service deployed on the Microsoft .NET framework. Suppose that an InventoryService accepts a System.Collections.ArrayList of Product as arguments, sets the new price by increasing 10 percent for each product in the ArrayList , and returns the new object of System.Collections.ArrayList type.

Listing 1. An Inventory Web service in C#

namespace Inventory
{
  [WebService(Namespace="http://services.inventory")]
  public class InventoryService: WebService
  {
    //increase the product price by 10 percent
    private static float inc_rate = 0.10F;
    public struct Product {
        public string name;
        public int    qty;
        public float price;
    }
    [WebMethod]
    [XmlInclude(typeof(Product))]
    public ArrayList updateProductPrice(ArrayList products)
    {
        ArrayList newList = new ArrayList();
        IEnumerator eList = products.GetEnumerator();
        while(eList.MoveNext())
        {
          Product item = (Product)(eList.Current);
          item.price = item.price * (1 + inc_rate);
          newList.Add(item);
        }
        return newList;
    }
  }
}

The WSDL engine in the .NET framework generates the following XML Schema for the Collection type, ArrayList , and the Product complex type :

Listing 2. The XML Schema for the ArrayList and Product

1.    <types>
2.    <s:schema xmlns:s="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://services.inventory">
3.    <s:element name="updateProductPrice">
4.    <s:complexType>
5.    <s:sequence>
<s:element maxOccurs="1" minOccurs="0" name="products"
type="s0:ArrayOfAnyType"/>
6.    </s:sequence>
7.    </s:complexType>
8.    </s:element>
9.    <s:complexType name="ArrayOfAnyType">
10.    <s:sequence>
11.    <s:element maxOccurs="unbounded" minOccurs="0" name="anyType"
nillable="true"/>
12.    </s:sequence>
13.    </s:complexType>
14.    <s:complexType name="Product">
15.    <s:sequence>
16.    <s:element maxOccurs="1" minOccurs="0" name="name" type="s:string"/>
17.    <s:element maxOccurs="1" minOccurs="1" name="qty" type="s:int"/>
18.    <s:element maxOccurs="1" minOccurs="1" name="price" type="s:float"/>
19.    </s:sequence>
20.    </s:complexType>
21.    <s:element name="updateProductPriceResponse">
22.    <s:complexType>
23.    <s:sequence>
<s:element maxOccurs="1" minOccurs="0" name="updateProductPriceResult"
type="s0:ArrayOfAnyType"/>
24.    </s:sequence>
25.    </s:complexType>
26.    </s:element>
27.    </s:schema>
28.    </types>

Lines 9 through 13 (see Listing 2) define a complex type, xsd:ArrayOfAnyType , with an unbounded sequence of elements anyType . The ArrayList of Products has been translated into a sequence of anonymous elements in the XML Schema definition. This is expected; however, it poses two problems. First, other Collection types will also be translated into xsd:ArrayOfAnyType . Therefore, how does the SOAP toolkit on another platform decide which Collection type to map it to?

Secondly, the xsd:anyType is the default type when the type is not specified. Line 11 in Listing 2 is expected because the objects in a Collection are generic references -- the types are not known until run-time. The problem occurs when the SOAP toolkit in another platform receives the serialized objects. How can you find the right serializer to de-serialize the XML payload back to the concrete objects?

AddThis

Comments

  1. 16 Jan 2006 at 09:50

    I'm developing a .NET Web Service that have some functions with datetime parameters but the I can't call it from Java client with nulls. Can you explain me how to define a complex type to wrap the value type and set the complex type to be null to indicate a null reference?


    Thanks

  2. 14 Jul 2005 at 13:21

    Hi,


    Nice article - but what sould go next - some examples (or maybe names of solutions) of software which translates between different SOAP datatypes... There have to be such a frameworks for type matching, aren't these?



    best regards
    stic

Leave a comment

Sign in or Join us (it's free).

Related discussion

Events coming up

  • Oct 14

    What’s New in Visual Studio 2008 Service Pack 1?

    Birmingham, United Kingdom

    “Service Pack? We’re calling it a Service Pack? Are you kidding??!?!” Visual Studio 2008 Service Pack 1 will release later in 2008 alongside .NET Framework V3.5 Service Pack 1 and, together, they represent a significant upgrade to Visual Studio 2008. There are enhancements across many areas of the .NET Framework such as data access, windows application development and web development and there are also corresponding changes in the development environment to support the new framework features.