This article introduces a couple of techniques that you can use to build interoperable Web services that take and return object collections. This is the first of a series of articles covering this subject. Future articles will cover more detailed scenarios. (This intermediate-level article was first published by IBM developerWorks, May 28, 2004, at http://www.ibm.com/developerWorks).
So far, so good. But what if you have an existing class that exposes language-specific Java collection classes in its method signatures, and you still want to expose this class via a Web service?
One relatively easy way of dealing with this situation is to create a wrapper around your service implementation, converting the collection interface into an array interface. For example, let's consider the original LinkedList-based CustomerService implementation listed above. We create a class with methods that invoke the original collection-based implementation but return Java arrays instead of the collections. The wrapper class might look like the one in Listing 5:
Listing 5. The wrapper class.
public class TheCustomerServiceWrapper { protected TheCustomerServiceLinkedList innerService = new TheCustomerServiceLinkedList();
Now you can create the appropriate Web services artifacts based on this wrapper class, which internally uses the existing collection-based implementation.
Summary
The Java programming language offers a variety of collection classes for different types of collections of objects. None of these, however, are language-neutral, and serializing instances of them into XML is difficult and sometimes impossible. The only recommended way to expose object collections is to use arrays. The WS-I Basic Profile also describes and recommends this approach.
Using Java's collection classes in the signatures of the public methods of your classes is generally a poor choice, regardless of the implications associated with Web services, because doing so dilutes the "contract" between invoker and provider. These classes invariably store the objects they "collect" as generic references to java.lang.Object. This prevents static-type checking by the compiler and introduces new classes of runtime errors. In cases where an implementation already exists, you can still use an array to expose it as an interoperable Web service by using wrapper classes.
Note that this practice agrees nicely with our good practice recommendation that business logic be coded in a Java class and wrapped in a session EJB to be exposed as a Web service.