Contract 1 ST Inter Op

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 12

MSDN Home > Visual Studio > Resources for Java Developers > Microsoft .

NET and Java/J2EE Interoperability > Microsoft .NET IBM o Each Web service demonstrates heterogeneous interoperability. By changing one setting in the Web service client, the Web service
WebSphere Web Services Interoperability client can either communicate with the .NET Web service or the WebSphere Web service.

o In this simple example, database access is not required to run each Web service and client.
Contract First Web Services Interoperability between Microsoft .NET
o In this document, we will go into detail about how to build Web Service 1 from first principles. We do not go into the same level of
and IBM WebSphere detail for Web Services 2 and 3.

Eric Cherng 2. This whitepaper that talks about each of the Web services in detail and their design.
Vertigo Software, Inc.
The techniques and concepts discussed in this article are general, and apply to connecting platforms from any two vendors. However the samples were
James Duff developed and tested only with the pairing of the Microsoft .NET Framework and the IBM WebSphere SDK for Web Services.
Vertigo Software, Inc.
Prerequisites and Required Software
Dino Chiesa
Microsoft Corporation This interoperability article (and the related sample) assumes that the reader is familiar with the basics of both the .NET Framework and ASP.NET
and the IBM WebSphere Application Server. Web Service 1 is for developers who have never created Web services before or who have not
October 28, 2004 experienced both platforms. Even if you are familiar with Web services and both platforms involved we recommend that you at least review the Web
Service 1 documentation as it contains useful hints and tips that are not covered in Web Services 2 and 3.
Intended audience:
Architects and Developers
Software Requirements
Download the Interoperability Sample for this article
The following software was used to create and test the samples.
Introduction
Interoperability Sample Contents Microsoft Windows XP Professional SP1
Prerequisites and Required Software
Why Web Services? Microsoft Internet Information Services 5.1
Web Service 1: Addition
Web Service 2: Ratings and Reports
Web Service 3: Product Search Microsoft .NET Framework 1.1 SDK
Conclusion
Recommendations/Tips
Acknowledgements Sun Java SDK 1.4
Useful Links
WebSphere SDK for Web Services (WSDK) 5.1
Introduction
As Web service adoption increases, vendors are striving to add more features and standards into their frameworks to enable richer and more robust Java Web Services Developer Pack (JWSDP) 1.3
communication between systems. As organizations spend more time and money investigating how best to leverage Web services and its enabling
If you do not have any of the Java software, it is crucial that you install the required software in this order:
technologies, they should be aware of the strengths and limitations of the technology specifically, those related to developer agility, maintainability
and interoperability. This paper specifically focuses on interoperability and takes as a starting point, interoperability between the Microsoft .NET 1. Sun Java SDK v1.4
Framework and IBM WebSphere via Web services. The goal of this whitepaper and the accompanying sample is to show developers of each platform
how to integrate with the other platform. More specifically we will look into Microsoft's .NET Platform and IBM's WebSphere Platform. The samples
demonstrate basic techniques and principles that are reusable across all projects where cross-platform interoperability via Web services is required. 2. Eclipse v2.1.3

Interoperability Sample Contents 3. WSDK v5.1

The sample contains:


4. JWSDP v1.3
1. Web service sample code
5. Eclipse requires a Java SDK, and while the WSDK includes one, WSDK requires Eclipse to be present first!
o Web services and Web service clients written in both Java and C# for three distinct service interfaces:

2. Web Service 1: This demonstrates a simple addition Web service and is intended to familiarize you with the relevant toolkits and 6. More information about setup can be found in the README file in the interoperability samples download.
platforms.
Why Web Services?
3. Web Service 2: This demonstrates passing complex object types between the two platforms.
Web services as an application technology have been with us for many years. Long before organizations and companies created the standards for Web
services, Business Analysts, Architects and Software Engineers realized that their company's data was spread across many systems that needed to talk
4. Web Service 3: This demonstrates one design pattern for building extensible Web services to handle cases where data mappings are to each other. Previous attempts to link applications together using RPC based technologies such as RMI, DCOM, and other platform-specific inter-
subject to change. connection mechanisms had typically failed due to the wide variety of vendors and platforms that were in use across organizations. These approaches
PUT/GET verbs, and manual message marshalling had problems with maintainability and programmer productivity. Hence, developers turned to
When the .NET runtime detects the WSDL parameter in the request, it uses reflection on the code decorated with the WebMethod attribute to
using some common standards and protocols, namely XML and HTTP.
dynamically generate an operation in the WSDL file to describe the underlying service.
When engineers started building applications that talked to each other, XML was chosen because of its ubiquitous use and support across all
This implementation approach works very well and is quite simple, but can introduce a few problems, especially in scenarios where the Web service
platforms. HTTP was chosen due its wide adoption and its ability to traverse firewalls. Vendors such as Microsoft and IBM started building
is used to connect heterogeneous systems. For example, in the Implementation First approach it is possible to include platform-specific types in the
frameworks to support these development efforts and to make the job of the developer easier. The frameworks achieve this by removing the burden of
Web service. .NET DataSets and Java Vectors are platform specific types that can't be represented easily in other platforms. This is because there is
XML serialization and de-serialization and by providing the common infrastructure pieces such as the code required to make connections between
currently no single well-defined mapping between such platform-specific types and XML. Just because a .NET client can recognize a blob of XML as
systems. With the birth of Web services came the promise of simpler, easier integration between heterogeneous systems and applications. Vendors,
a Dataset, it doesn't mean a Web service client written in Java can do the same. Interoperability problems arise as a result.
using Web services as a catalyst, are now rallying around the concept of Service Oriented Architecture where individual solutions, which may still be
built (justifiably) using proprietary RPC protocols such as RMI and DCOM, can be connected together to enable real time data to flow across the The W3C XML Schema standard defines a number of built-in data types, among them string, integers of various sizes, Boolean, single- and double-
enterprise. precision floating point, dateTime, and others. Each application platform also supports a set of its own data types. The intersection of these data type
sets defines the types that will be most interoperable across different platforms. If you start with XML Schema types, it is easy to map to platform
So the benefits and potential for integration exists, but, in practice, most developers find that creating interoperable Web services is quite a challenge.
types, but if you start with platform types there may not always be a mapping to an XML Schema type. For example, XML Schema integers, strings,
There are many hidden dangers in creating even the simplest of Web services, such as conflicting types or unsupported features. Our first sample will
Booleans, and float all map nicely to the corresponding data types in .NET or Java. However, Vectors and Hashtables are native types to individual
show you one example of an interoperable Web service and walk you through the process of designing and creating such a Web service.
platforms and are not part of the XML schema official types. See the XML Schema data types specifications for more information on the supported
data types.
Web Service 1: Addition
Most Web services runtimes (including the one built-in to the .NET Framework and the WSDK) can map between these XML Schema primitives and
The first sample demonstrates the basics of interoperable Web service. It is a simple addition Web service that accepts two integers from the client platform-specific primitives, i.e. a string in XML Schema maps to a System.String in .NET, and to a java.lang.String in Java. Using the XML
and returns the sum of the two numbers. Schema primitives, as well as structures and arrays built from those primitives, it is possible to construct more complex data types, described in XML
Schema, that can be mapped with high-fidelity from one platform to another. These data types can then be employed in WSDL documents for use in
The following high-level diagram depicts what the architecture of this Web service looks like: the Web service.

This is the core of what is known as the "WSDL first" design: by using XML Schema types to define the data types used in the Web service you
increase the probability that you will use data types that can be mapped from one platform to another.

The WSDL First approach is also sometimes called the "Schema First" approach. Even though the two terms are typically used interchangeably,
there is actually a small distinction between the two terms. What we are advocating in this paper is that architects and developers consider building up
the contract using WSDL definitions before they build the underlying code to support the service. To build the WSDL file developers can either create
XML Schema definitions that are specific to the interface they are used with, "WSDL First" design, or they can use XML Schemas that are already
defined within their application domain, "Schema First" design. This paper will use the "WSDL First" terminology.

Figure 1. High-level architecture of Web Service 1

Which Comes First, the Implementation or the Interface?


The most common approach when building Web services, and the one demonstrated most often and supported best by tools, is to "infer" a Web
service interface from an existing implementation. A developer might write:
public int Add(int x, int y) {
return x+y;
}

In ASP.NET, exposing this as a Web service is as simple as adding a WebMethod attribute to the code. This approach is often called
"Implementation First" or "Code First", because the Web service interface, formally described in a Web Service Description Language (WSDL)
document, is derived from the implementation.

Figure 2. Implementation First Web service development


Figure 3. WSDL First Web service development
With the Implementation First Web service development approach, you start off by writing code for your Web service (see #1 in Figure 2). After you
compile, the Web services framework uses your code to dynamically generate a WSDL file (see #2). When clients request your Web service The challenge with the WSDL First approach is that current tools in production today do not promote this practice. It's definitely possible, but not
definition, they retrieve the generated WSDL and then create the client proxy based on that definition (see #3). easy. Visual Studio provides a Schema editor and an XML editor, but no WSDL editor. Eclipse also does not include a WSDL editor. Fortunately
both environments do provide a capability to generate Web service skeleton code, in addition to client-proxy code from a WSDL file.
For example, in ASP.NET, the WSDL can be dynamically generated from an implementation with the URL like so:
http://hostname:port/Service1.asmx?WSDL
such as Altova's XmlSpy, that have WSDL designers to help with the task. However, even this may not be a solution as many developers are not able style="document" />
<operation name="Add">
to "think in WSDL." <soap:operation soapAction="http://example.org/Add"
style="document" />
One solution to this problem is to quickly prototype a Web service interface using the Implementation First approach. We use the dynamic WSDL <input>
generation features of ASP.NET, or IBM WSDK, to create a template WSDL file. Then we can begin development using the WSDL First approach, <soap:body use="literal" />
</input>
tweaking the interface as required. This process iterates until the WSDL is final. <output>
<soap:body use="literal" />
As you can see from Figure 3 above, there are three high-level steps for creating Web services using the WSDL First approach: </output>
</operation>
</binding>
1. Create the WSDL document <service name="Service1">
<port name="Service1Soap" binding="s0:Service1Soap">
2. Implement the WSDL document <soap:address
location="http://localhost/NetWSServer/Service1.asmx" />
a. Create the Web service </port>
</service>
</definitions>
b. Create the Web service client
Of course for the WSDL-wiz, this exercise is trivial, but for the rest of us, it would take forever to learn the 51-page WSDL specifications. This is
Sub-steps A and B of step 2 can be done in any order you wish. Because both depend on the WSDL document, it is only important that the WSDL why we use the Implementation First to start off because writing code to create a Web service is the simplest method for developers.
document be created first before A or B is done.
First create a C# ASP.NET Web Service project in Visual Studio .NET. Name the project WebService1WSDL.
The rest of this section will walk through the steps to developing the first Web service sample following the WSDL First process. The complete
source code for this sample can also be found in the download accompanying this paper.

Creating the WSDL from Visual Studio .NET (Implementation First)


Before we go into the WSDL First approach of creating Web services we will look at the Implementation First development model in Visual Studio
.NET. The reason that we are demonstrating this method first is that creating a WSDL file from scratch is hard. Using the WSDL file generated from
the Implementation First approach to "jump-start" the development process is a much simpler alternative given the tools at our disposal. Imagine
having to type this all out by hand:
<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:s0="http://example.org/"
targetNamespace="http://example.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://example.org/">
<s:element name="Add">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="x"
type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="y"
Figure 4. Visual Studio .NET New Project dialog box
type="s:int" />
</s:sequence> Next, open the code for Service1.asmx. Uncomment the HelloWorld method and replace the method with this one:
</s:complexType>
</s:element> [WebMethod]
<s:element name="AddResponse"> public int Add(int x, int y)
<s:complexType> {
<s:sequence> return -1;
<s:element minOccurs="1" maxOccurs="1" name="AddResult" }
type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</types>
<message name="AddSoapIn">
<part name="parameters" element="s0:Add" />
</message>
<message name="AddSoapOut">
<part name="parameters" element="s0:AddResponse" />
</message>
<portType name="Service1Port">
<operation name="Add">
<input message="s0:AddSoapIn" />
<output message="s0:AddSoapOut" />
</operation>
</portType>
<binding name="Service1Soap" type="s0:Service1Port">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
Figure 5. Implementation First Web service code

Build the project and make sure there aren't any errors. Next, right click on Service1.asmx and set the page as the start page. You can now press F5
and view the Web service test page as shown in Figure 6.

Figure 7. Framework generated WSDL file

You have just created a WSDL file, without having to learn any WSDL specifications!

Another important tip here is that since we generated the WSDL file from this temporary project, the location of the Web service in the WSDL
Figure 6. Web service test page document is hard coded to point to this temporary project. While this does not affect the Web service, the clients that use this WSDL file will use this
reference as the location of the Web service. Thus, it is important that you change this value before deploying this WSDL file to our web site. We will
It's important to realize that the ASMX file is the actual Web service. The page you are looking at is generated by the framework to document the change this reference later once we know the actual location of our Web service.
Web service, and to allow the developer to test the Web service without having to manually create a client application. The test functionality is only
available when you view the page locally, and does not work for Web services that take complex data types as input parameters. For security reasons, If you forget to change this location and client applications have already been built, you can still fix the reference by modifying the location that client
you should remember to disable this test page once you deploy your Web service to a production machine. references point to. Both .NET and WebSphere Web service client proxies allow setting a URL property. This is also useful when moving from
development to production where the final end point of the service is the only thing you want to change.
Next, click on the Service Description link on the top right side of the page. This will open another web page showing you the generated WSDL for
your service. The WSDL generation function is always available unless you specifically disable it. Save the generated WSDL to a file on your local Since the Web service we're building is simple, our generated WSDL file does not require any more tweaking. The next step is to create the actual
drive and name it WebService1.wsdl. .NET Web service.

Implementing the .NET Web Service (WSDL First)


Using the WSDL generated in the previous step, we will now create a new .NET Web service.

In order to go from the WSDL file to a source code file, we will use a console application called wsdl.exe to generate the code. This tool will parse a
WSDL file and any other external files to create a single source code file containing all classes, methods, and types required to implement our Web
service. Wsdl.exe is installed along with Visual Studio .NET 2003 (and the .NET SDK). To use the tool, you will need to open the Visual Studio
.NET 2003 Command Prompt, which is by default located in the Start menu, All Programs, Microsoft Visual Studio .NET 2003, Visual Studio
.NET Tools. Once open, navigate the command prompt to where you previously saved WSDL file.

Execute the following command to have wsdl.exe generate our Web service source file.
wsdl.exe /server WebService1.wsdl
Figure 8. Visual Studio .NET 2003 Command Prompt executing wsdl.exe
Figure 9. Windows Explorer showing the Web service project files
Notice that the utility outputs a message indicating that Service1.cs has been successfully created. This file will be the starting point for our Web
The sample Web service, Service1.asmx, was generated as a part of the Visual Studio project wizard. Since the wsdl.exe command only generates the
service.
template implementation code and not the entry point (the ASMX) file, we want to reuse the VS generated Service1.asmx instead of creating our own.
The file generated by wsdl.exe is only a template of the method that we want to implement; hence, it needs to be modified in order to work properly. However Service1.asmx already has a corresponding source file. An easy way to combine the ASMX file with our implementation code is by simply
deleting the implementation code generated by VS (Service1.asmx.cs) and renaming our implementation code to that. Make sure that Service1.asmx
The current wsdl.exe command always generates an abstract class for the Web service when it is executed with the /server option. We'll convert this
and Service1.asmx.cs are not open in Visual Studio before you do this. So, delete the current Service1.asmx.cs and then rename our Service1.cs to
to a concrete class by removing the abstract keyword and providing an implementation for the Add method. We will also put the class in the
Service1.asmx.cs.
WebService1 namespace. The resulting code looks like the following:
namespace WebService1 To verify that the code transplant worked, select Service1.asmx in Solution Explorer in Visual Studio and click the View menu, and then click Code.
{
/// <remarks/>
You should now see the template code with the Add method implementation we modified earlier displayed in Visual Studio .NET.
[System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap",
Namespace="http://tempuri.org/")] Finally, to test that the Web service is working properly, right click on Service1.asmx and click Set As Start Page. Then go to the Debug menu, and
public class Service1 : System.Web.Services.WebService { click on Start to build the project and to open Service1.asmx in your browser. Verify that your Web service works correctly using the test page.
/// <remarks/>
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute(
"http://tempuri.org/Add", RequestNamespace="http://tempuri.org/",
ResponseNamespace="http://tempuri.org/",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=
System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public int Add(int x, int y) {
int result;
result = x + y;
return result;
}
}
}

You might wonder, why not just subclass the generated abstract class, instead of converting it to a concrete class? There's a good reason. The wsdl.exe
tool generates code that is decorated with attributes that are used by .NET's XML serializer and Web services runtime to map from objects to XML
and back. For example, an attribute in our example uses the http://tempuri.org namespace for the generated XML document. These attributes are not
inherited by subclasses. Therefore, sub-classing the abstract class, we would need to cut-and-paste all of these attributes on our concrete class.

So instead of duplicating all the attributes by hand, it is simpler to just edit the file directly. Of course, this means that if the WSDL changes, you will
need to regenerate the source code for the WSDL file, and if not done carefully, this process may erase all our existing code. You will have to
manually copy the Web service implementation code from your old file to the new file.

Now that we have the Web service source code ready, it is time to create our Visual Studio solution. Create a new Visual Studio .NET C# ASP.NET
Web Service project and give it the name WebService1.

Once you have your project created, copy the Web service implementation code Service1.cs created earlier to the directory where Visual Studio
generated the Web service files. This is usually in c:\inetpub\wwwroot\WebService1.
.NET Web service.
Figure 10. Web Service Add test page
Implementing the WSDK Web Service Client
Now that we have a Web service implemented, it's time to create a client to consume the Web service. Since this paper is about interoperability, we
will consume the .NET Web service using a JSP page running within IBM's WebSphere Application Server.

Start Eclipse and create a new Dynamic Web Project. Give it the project name WebServiceClient1 and name the EAR project file
WebServiceClient1Ear.

Figure 11. Response from the Web service of adding 12 and 45

To wrap up the .NET Web service, we now need to go back to the original WSDL document to make some minor changes. As mentioned before, the
WSDL document is currently pointing at our temporary project Web service. Now that we have finished creating our real Web service, we can modify
the location reference to point to this Web service. You can do this by opening up the original WSDL document and then replacing the soap:address
element's location attribute to point to the location of this new Web service. The new soap:address element should look similar to the following:
<port name="Service1Soap" binding="s0:Service1Soap">
<soap:address location="http://localhost/NetWSServer/Service1.asmx" />
</port> Figure 13. Eclipse showing the WebServiceClient1 project

Next, add the WSDL file to the WebServiceClient1 project. You can do this by dragging and dropping the file directly into the project in the Eclipse
Navigator pane.

Now we want to generate a Java proxy for the Web service. Similar to how Visual Studio .NET creates a proxy class when adding a web reference to
a project, the WSDK Tools will create a set of Java files that make calling the Web service easier than manipulating the network stream directly.
Because we had already added the WSDL document in the project, you can create the proxy by right clicking the WSDL document, point to the Web
Services menu, and then click on Generate Client. This will bring up the WSDL to Java Bean Proxy wizard as shown below in Figure 14.

Figure 12. Location of Web service being modified in the WSDL file
the service in debug mode. In the Java side, once you execute the add function in the JSP page, you should see Visual Studio .NET stop the execution
of the Web service and break at the point you specified.

At this point, we have verified that the Java proxy class generated from the WSDL is functioning properly. We also used the test page generated by
the WSDK wizard to test calling the .NET Web service from Java. Since both are working properly, this completes both the .NET Web service and
the Java Web service client demo of Web Service 1. Though we do not describe in detail the steps for creating the .NET Web service client and the
Java Web service server, the sample code accompanying this article does include implementations of both server and client, in both .NET and Java.
If you want to generate these yourself, you can find other tutorials for those steps.

Web Service 2: Ratings and Reports


The second sample builds on the first by creating a Web service that uses a much more complex data schema. Our goal for this sample is to show
interoperability between .NET and WebSphere when using complex data types. In the schema for this sample, there is a combination of complex
types, simple types, enumerations, restrictions, arrays, and types that inherit from other types in addition to the standard XML Schema types. The
differences between the two platforms and the issues in developing interoperable Web services are more apparent in this sample because of this
increased complexity.

Scenario
The company, Stuff Sellers, sells various products to various business types. Each business is allowed to submit reviews of the products they buy.
Web Service 2 takes the scenario of a ratings service that allows users to submit a report for a given rating or to obtain a list of all reports for a given
rating identified by a number. In this case a report can be seen as analogous to a review and the sum of the reviews is used to generate the final rating.
Figure 14. WSDL to Java Bean Proxy wizard
Data Schema
In the first dialog, make sure to check the Test the generated proxy check box. This will generate the test JSP page (similar to the test page generated
from Service1.asmx when creating the Web service in Visual Studio) that we will use to verify the proxy classes generated. The default options for The following diagram depicts the high level elements of the data schema.
the rest of the wizard will work so click Finish.

After Eclipse completes generating all the necessary files, the following test page is displayed in the Eclipse main window.

Figure 16. Main elements of Web Service 2 data schema

The top level element is Ratings. Each Ratings element contains an array of ReportSet elements (encapsulated in the ReportSetArray type). Then
each ReportSet element contains an array of Report elements (encapsulated in the ReportArray type). All three of these top level elements are data
types that inherit from the MyBase type. To see the actual XML Schema definition for this data schema, refer to the WebService2SharedTypes.xsd
file in the samples download.

As is the case with WSDL, there are two ways to generate an XML Schema. The first is to manually design the schema using a schema designer (in
the case of XML Schema, Visual Studio does include a designer). The second is to infer the schema from an existing .NET type, using the xsd.exe
utility. And as with WSDL, these two techniques can be combined in an iterative approach to tweak a schema so that it looks just right.

In some cases, the data schema has been previously defined, and exists independently of the Web service implementation or interface. This may be the
case when you are assigned to create a Web service based on the design of a current system. Whether you create the schema or are provided with an
existing one, the data schema should be described in a self standing XML Schema XSD file, to allow for modularity and re-use.

The following is a class diagram depicting the XML Schema defined in the data schema for this Web service. In the same code, the schema is defined
Figure 15. Eclipse IDE showing the test JSP page
in the file WebService2SharedTypes.xsd. The code generated from the data schema (the XML Schema file) on each platform should follow a class
structure similar to this diagram.
Click on add(int,int) in the Methods pane and provide 2 numbers to be added in the Inputs pane. You should see the sum of your 2 numbers in the
bottom Result pane. Behind the scenes, this JSP page is calling the Web service proxy class, generated earlier by the WSDK Web service wizard, to
call our .NET Web service. Because we had changed the Web service location reference in the WSDL document, our Java client knows exactly where
to find the Web service we created in step 2 earlier. If the displayed sum of your 2 numbers is correct, then this successfully verifies that the Java
proxy was generated properly and is actually talking to the .NET Web service.
XML Schema definition of MyBase looks like this:
<xs:complexType name="MyBase">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="ID" type="xs:int"
nillable="true" />
</xs:sequence>
</xs:complexType>

When minOccurs=0, this indicates that the ID property can be left out of the resulting XML document. This causes a problem for the .NET platform.
In .NET, the xsd:int maps to Int32, which is a value type, and value types cannot be NULL. Basically this means there is no way to determine
whether the ID property has been set or not since all values of Int32 are valid values. The .NET Framework resolves this problem by creating another
variable named IDSpecified of type Boolean. This variable is checked by the .NET XML Serialization logic to determine whether the ID variable has
been set or not, essentially giving ID the NULL/not NULL value. Therefore whenever you attempt to access the ID variable, you should always
check or set the IDSpecified variable first. For more information on this usage pattern, see the MSDN documentation for the XmlIgnoreAttribute
class.

The following is what the MyBase type gets translated to in C# code:


[System.Xml.Serialization.XmlTypeAttribute(Namespace=
"http://example.org/sharedtypes")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Report))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ReportSet))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Ratings))]
public class MyBase
{
public int ID;
Figure 17. Class diagram of the data schema in Web Service 2
[System.Xml.Serialization.XmlIgnoreAttribute()]
Web Service Definition public bool IDSpecified;
}
In the first Web service, we used the .NET Framework to generate the initial template WSDL file. Because our Web service was simple, that was the This issue does not occur when using the WebSphere sample, because when an xsd:int is used with minOccurs=0, the WSDK tools generate a
only step we needed to do to create the WSDL. Unfortunately, this Web service is not as simple and thus requires some manual tweaking. Including variable of type java.lang.Integer instead of the native int Java type. The java.lang.Integer type is a reference type, and it is possible for a variable
references to our data schema, changing the namespace, and creating the proper messages for the portTypes are just some of the changes we had to of this type to take the NULL value to indicate that it has not been set. Using the tools provided in the WSDK, the following is what the MyBase type
make to the template WSDL file in order to maintain interoperability. gets translated to in Java code:
public class MyBase implements java.io.Serializable {
The WSDL document for this Web service defines two operations: GetRatings and SubmitReport. GetRatings returns a Ratings type if the ID private java.lang.Integer ID;
provided matches a given rating. The SubmitReport operation is used by clients to submit a new Report associated with a specific Ratings and
ReportSet. You can see the WSDL definition of these operations in WebService2.wsdl in the samples download. public MyBase() {
}
There are two ways to include XML Schema definitions in WSDL files: you can define the schema inline in the WSDL file or by referencing your public java.lang.Integer getID() {
XML Schema files in your WSDL file using the xsd:import element. Because inline definitions are part of the WSDL file, they are simple to return ID;
maintain. However, since a data schema describes data and not the Web service interface, and is sometimes used independently of the web service }
interface, it is more logical to separate the two definitions into two separate files. If your Web service is simple and doesn't require many complex data public void setID(java.lang.Integer ID) {
types, then inline schema will work fine (as in Web Service1), but in general most Web services should separate the data schema from the Web this.ID = ID;
service definition. }
}
In this Web service, we decided to use the xsd:import method to reference the external XML Schema file, WebService2SharedTypes.xsd from the Another difference that is evident when comparing the C# code generated from the XML Schema, to the Java code generated for the same schema, is
WSDL file, WebService2.wsdl. In the WSDL file, it looks like this: the inclusion of code attributes in the C# code. As we said earlier, these are used by the XML Serializer in .NET to help in mapping from class
<types> instance to XML. Java also requires similar "metadata". In the case of the Web services runtime in WSDK, this metadata it is stored independently, in
<xs:schema targetNamespace="http://example.org/"> an XML file that defines the type mappings. See the WSDK documentation for more information.
<!-- Import the Shared Types -->
<xs:import namespace="http://example.org/sharedtypes"
schemaLocation="WebService2SharedTypes.xsd"/> Another point of interest: if you examine the classes generated by either the .NET tools or the WSDK tools, you will find that the generated data types
<!-- Import the Message Parameters --> may not be what you, as a developer, would write without considering interoperability. Examine the Ratings.java class generated by WSDK.
<xs:import namespace="http://example.org/interface" Excluding some housekeeping code, it looks like this:
schemaLocation="WebService2Interface.xsd"/>
</xs:schema> public class Ratings extends org.example.MyBase implements java.io.Serializable {
</types> private java.lang.String description;
. . . private int confidenceLevel;
private java.util.Calendar expiration;
Implementation private org.example.ReportSetArray allReports;

public Ratings() {
To create the Web service template code in .NET, run wsdl.exe with the following parameters: }
wsdl.exe WebService2.wsdl WebService2Interface.xsd
WebService2SharedTypes.xsd public java.lang.String getDescription() {
return description;
Notice that wsdl.exe requires the input WSDL file and all of the included XSD files to be specified on the command line together. When importing an }
XSD into a WSDL, it is possible to provide a schemaLocation attribute. According to the WSDL specification, this attribute serves as a "hint" for the
public void setDescription(java.lang.String description) {
location of the schema, and the hint may or may not be followed by tools that interpret the WSDL file. In this case, wsdl.exe does not use the this.description = description;
schemaLocation hint, so the external schema files must be specified on the command line. On the other hand, the IBM WSDK tools do utilize the }
schemaLocation hint and will load the files directly when specified.
public int getConfidenceLevel() {
return confidenceLevel;
} and a Published Date. Therefore, the base product type will expose all of the properties that are common across product types, and will allow
public void setConfidenceLevel(int confidenceLevel) {
extensions for properties that are specific to particular product types.
this.confidenceLevel = confidenceLevel;
} Data Schema
public java.util.Calendar getExpiration() {
return expiration; The following is a class diagram of the data schema defined for Web Service 3.
}

public void setExpiration(java.util.Calendar expiration) {


this.expiration = expiration;
}

public org.example.ReportSetArray getAllReports() {


return allReports;
}

public void setAllReports(org.example.ReportSetArray allReports) {


this.allReports = allReports;
}
}

For the primitive data members, of type int and string, perhaps they reflect what any designer might hand-author: following JavaBean conventions
with getters and setters wrapped around a private member. But then some of the differences appear. The date value is handled by a Calendar, not a
java.util.Date. And, an Array is wrapped by a custom class, also accessible via a getter/setter pair. This generated class may not be what you would
write yourself, but it does the job, and it has the added advantage of being interoperable. You could make the same statements about the code
generated by the .NET tools.

We followed the general steps outlined in the section for Web Service 1, above, to build two Visual Studio projects: one for the client, and one for the
server. We did likewise with the WSDK to build two WebSphere projects. All of these clients and servers are mutually interoperable. Compile and
run the Visual Studio projects and the Eclipse projects in the samples download to see all of this in action. Be sure to check the Readme for the
samples download before proceeding.

This sample explored the use of complex data types in an interoperable Web service. The W3C XML Schema plays a key role in defining the message
types and data elements to be exchanged. This section discussed how to develop an XSD for a complex data type, and how to employ that XML
Schema in a WSDL document. This section also pointed out some of the edge cases to be aware of, for example, the difference between value and
reference types in .NET, and the implications that this difference has on XML Serialization.
Figure 18. Class diagram of the data schema in Web Service 2
In the next sample, we will expand on the ideas from this sample and explore interoperability using extensible data elements.
The XML Schema type definition for SearchResult (in WebService3SharedTypes.xsd) is defined as the following:
Web Service 3: Product Search <xs:complexType name="SearchResult">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="SKU"
Most Web services employ a fixed data schema that is, the types of data sent over the wire are known at design time. But sometimes a static data type="xs:string"/>
schema does not fulfill the requirements for the application. Consider the following business scenario. <xs:element minOccurs="1" maxOccurs="1" name="Price"
type="xs:decimal" />
Scenario <xs:element minOccurs="1" maxOccurs="1" name="Name"
type="xs:string"/>
<xs:element minOccurs="1" maxOccurs="1" name="Description"
As mentioned in Web Service 2, Stuff Sellers sells various products to both consumers and other businesses. Because the company sells so many type="xs:string" />
different products, the manager has asked us to create a Web service that will make it easier to search the database of products. Our search will be <xs:element minOccurs="1" maxOccurs="1" name="ProductType"
type="xs:string" />
used indirectly by consumers through the Internet store front, and directly by other businesses. <xs:any minOccurs="1" maxOccurs="1" processContents="lax" />
</xs:sequence>
The manager would like the Web service to support the following three requirements: </xs:complexType>

1. Allow dynamic data. Because Stuff Sellers often adds new product types to their database, the Web service definition should be flexible As you can see, SearchResult is the parent type that represents all products found by the Web service. SearchResult contains properties that are
enough to add support for the new types without breaking existing clients. common to all product types. In addition, SearchResult also contains an xsd:any element, which acts as a wildcard. An XML file that validates to
this schema can include any XML element at that location. For our purpose, the xsd:any element will contain one of the product property types that
can be returned by the Web service. We have defined three such product property types in WebService3ExtendedProperties.xsd: DvdProperties,
2. Support basic processing. Companies looking for products from Stuff Sellers may be only interested in products with a certain property. For BookProperties, and CDProperties. In practice, a client application will access the common properties by checking SearchResult, and will access
example, the discount store may be looking for products that are less than 50 cents. The Web service should be able to return data and allow the extended properties for that product by checking the member variable that contains the product specific properties types.
the client to do a simple check on the results for this property without too much difficulty.
An alternative to using xsd:any in the schema to match any XML element is to employ a string element in the schema, which will contain
dynamically generated XML. Using a string is a similar "wildcard" approach. The difference is that the XML contained within the string will be
3. Be extensible. Stuff Sellers may need to modify the Web service in the future and would like the Web service to be able to easily support "escaped" for transmission, and so will be opaque to XML parsers, which is not what we want. It is cleaner to integrate the dynamic XML as part of
new features while minimizing the impact on existing clients. the XML document instead of escaping it into a string element. In either case, there is a bit of extra work required, to generate the XML on the
sending side, or to parse it on the receiving side.
In addition to these requirements, the manager would like the Web service interface to be as simple as possible. Specifically, the Web service should
have only a single entry point.
Web Service Definition
Looking over the products that Stuff Sellers currently sells, we find that all products at a minimum have a Name, Description, Price, and a SKU.
Just as in the second sample, the WSDL document for this Web service is separated into two files: WebService3.wsdl and
These attributes will make up the base properties for all our products. In addition, each product also has its own unique set of attributes. For example a
XML Schema file that contains the data types used by the Web service. The following is a sample capture of the SOAP message returned by the Web perform the Java-to-XML binding. One such add-on is the JAXB API that is part of Sun's JWSDP. Installing the JWSDP will give you the JAXB
service to the client. compiler, which can generate Java class from an XML Schema, similar to the xsd.exe utility for .NET. Using the classes to reference the data types is
<?xml version="1.0" encoding="utf-8" ?> much simpler than directly manipulating XML elements. In JAXB, the generated data type classes are also responsible for "marshalling" or
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" "serializing" to, and "unmarshalling" or "deserializing" from, XML files that conform to that XSD.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> The .NET Framework SDK also includes a tools and a framework for binding XML data to .NET classes. The Xsd.exe tool parses an XSD file to
<soap:Body>
<SearchResponse xmlns="http://example.org/sharedtypes"> create a corresponding source code file that contains the data type definition classes. At runtime, applications can use the System.Xml.Serialization
<SearchResult> namespace of classes to create an object graph from an XML stream, or vice-versa.
<SearchResult>
<SKU>B05502HB9I</SKU>
<Price>14.99</Price>
For example, at compile time, to generate C# classes from the WebService3ExtendedProperties.xsd schema, use the following command:
<Name>Spain's History</Name> xsd.exe /classes WebService3ExtendedProperties.xsd
<Description>Short documentary on the history of the
Spain.</Description> And then at runtime, to create the object graph from a file, use these few lines of code:
<ProductType>DVD</ProductType>
FileStream fs = new FileStream(path, FileMode.Open);
<DvdProperties xmlns="http://example.org/resulttypes">
XmlSerializer s= new XmlSerializer(typeof(BookPropertiesType));
<Region>EUROPE</Region>
BookPropertiesType props;
<Format>PAL</Format>
try {
<Language>Spanish</Language>
<ReleaseDate>2000-05-14</ReleaseDate> props= (BookPropertiesType) s.Deserialize(fs);
}
</DvdProperties>
</SearchResult> finally {
<SearchResult> fs.Close();
}
<SKU>A04D5E87RJ</SKU>
<Price>20.00</Price> Normally, for data types used in Web services interfaces, the steps of creating the data type classes and performing the serialization are performed
<Name>Spain's History</Name>
<Description>Companion coffee table book to the documentary automatically for you: the former by the wsdl.exe tool or the "Add Web Reference" in Visual Studio, and the latter by the web services runtime in
"Spain's History".</Description> .NET. When you pass a parameter to a web service, the parameter is automatically serialized to XML for transmission across the network. The use of
<ProductType>Book</ProductType> xsd.exe is necessary here to create the classes because the WebService3ExtendedProperties.xsd schema is not explicitly included in the web service
<BookProperties xmlns="http://example.org/resulttypes">
<Authors>
interface definition.
<Author>Mark Person</Author>
</Authors> What about the serialization at runtime? When parsing a Schema, xsd.exe will map xsd:any elements to fields of type XmlElement. By modifying
<Publisher>BookPub Central</Publisher> the generated classes, changing the type of the field to System.Object rather than System.Xml.XmlElement, and decorating the field with
<ISBN>0459756212</ISBN>
<PublishedDate>2003-08-08</PublishedDate> XmlElementAttribute attributes, we can tell the framework to map the XML data to specific .NET datatypes, rather than a generic XmlElement. For
</BookProperties> example, in this snippet, the Any field will map to one of the three flavors of extended properties.
</SearchResult>
[System.Xml.Serialization.XmlElementAttribute(ElementName="DvdProperties",
</SearchResult>
Type=typeof(NetWSServer3.DvdPropertiesType),
</SearchResponse>
Namespace="http://example.org/resulttypes")]
</soap:Body>
[System.Xml.Serialization.XmlElementAttribute(ElementName="BookProperties",
</soap:Envelope>
Type=typeof(NetWSServer3.BookPropertiesType),
There is also a third file, WebService3ExtendedProperties.xsd, which isn't imported into the WSDL, but is essential for the Web service to generate Namespace="http://example.org/resulttypes")]
[System.Xml.Serialization.XmlElementAttribute(ElementName="CDProperties",
a response, and for clients to be able to interpret the response from the Web service. This file contains the definitions of the dynamic part of the data: Type=typeof(NetWSServer3.CDPropertiesType),
the extended properties for the product types. Namespace="http://example.org/resulttypes")]
public object Any;
The advantage of keeping the product types separate from the types used by the Web service is the ability to extend the product types, without With these modifications to the generated classes, the .NET runtime will automatically and implicitly serialize the Product property object types to
modifying the interface. Eventually Stuff Sellers will expand its business and start selling other types of products. Since search results will contain and from XML. Without this capability, the developer would have to explicitly serialize these classes to XML. And in fact, this is the approach taken
these new products, adding the new products in a simple way is a crucial requirement. With our design, supporting new types is a simple matter of with WebSphere for the extended properties types. (See the sample code for details).
extending the Web service implementation to return the new types and extending the data schema defined in WebService3ExtendedProperties.xsd.
Publishing the new XSD file to the web and letting customers know of the change are the last steps needed. There is no change needed to the WSDL While developing this sample, one consideration was to determine whether to make the ProductType an enum or just a string. The benefit of an
file. Enumeration is that the different types are explicitly stated and thus cannot be confused. However in the end, the decision not to use enum was taken
because of the requirement for extensibility: we want the flexibility to create additional and possibly remove existing product types without breaking
Web service clients that do not wish to use the extended properties or simply pass on the extended properties to other services can chose to ignore the existing clients. If ProductType was defined as an enum, then future product types that get passed to old clients would break. Therefore a string was
extended properties. At runtime, these clients need not de-serialize the XML blob into objects. For example, if an application is written to filter used instead because this allowed the flexibility to expand the product lines while keeping existing Web service clients still working.
products based only on price, then it doesn't matter what type of product is returned. In this case, the client only needs to check the base property
Price of the SearchResult type and can safely ignore the extended properties. As with Web Service 2, the data types generated here by the tools probably will not match what a developer might write when modeling the problem
in code. However, here again, the key advantage of starting with WSDL and generating code is interoperability.
With the use of xsd:any, the Web service has the flexibility to add new features without having to break existing clients. New Web service clients can
use the new product types while existing applications will simply ignore the new product types. Even if existing product types are removed, the As with Web Service 2, we followed the general steps outlined in the introduction of this article to produce client and server projects for both Visual
existing Web service clients will still function properly because they will simply not execute the code pertaining to the old products. This design Studio and the WebSphere web services SDK. And here again, the resulting clients and servers are fully interoperable. Ok, enough description.
provides the best of both worlds, where response messages can be extended for new applications, while still allowing existing applications to function Compile and run the Visual Studio projects and the Eclipse projects in the samples download to see the extensibility of Web Service 3 of this in
properly. action.

Implementation Web Service 3 showed the use of complex data types, statically included as well as dynamically included in a WSDL. The support for extensible
types allows for the flexibility to expand and to modify the interface with minimal changes required to the Web service and to the Web service clients.
Converting between XML and corresponding instances of objects is called "XML serialization", or "XML binding". The process of converting
between parameters to a Web service call, and the XML sent over the wire in a Web service request or response, is usually done automatically by the
Web services runtime. However, when using schema extensions that are not defined in the WSDL (or its imported XSDs), this XML serialization and
Conclusion
de-serialization must be done manually. .NET exposes tools and programming interfaces that enable this.
With the three Web services shown in the paper, we can see that it is definitely possible to create interoperable Web services using complex data
types. The easy path through the developer tools the "Implementation First" approach often leads to interoperability challenges. However, by
be avoided. Even though we have shown the "WSDL First" approach specifically for .NET and WebSphere, the concepts illustrated apply to for Web Service 2, you will need to execute the following command:
interoperability across all platforms. wsdl.exe WebService2.wsdl WebService2Interface.xsd
WebService2SharedTypes.xsd
Hand-authoring WSDL is not easy. This paper also explored the approach of iteratively developing and refining WSDL files and W3C XML Schema
Refer to Web Service 2 for more information on this topic.
definitions, using the prototyping tools included in Visual Studio .NET and the WSDK.

Finally, the paper provided tips and pointers about likely pitfalls on the path to creating interoperable and extensible Web services. Armed with these Wsdl.exe by default generates template code in C#. If you prefer another language (i.e. VB.NET), include the /l option with the command:
ideas of creating interoperable Web services, we may eventually achieve the dream of ubiquitous access to any system, regardless of platform and wsdl.exe /l:vb WebService1.wsdl
architecture. When generating a source file for a Web service (using the /server option), the tool creates an abstract template class that is associated with the
WSDL document. It is recommended that you modify this file directly rather than sub-classing the generated file. For more information on this topic,
The following is a listing of recommendations and tips reviewed in this paper. refer to Web Service 2.

Recommendations/Tips Visual Studio .NET 2005, will support generating template source files from the WSDL directly in the IDE. In addition to this, if the WSDL
document changes and the template file needs to be regenerated, the IDE will do so in such a way that any existing code already in the old template
Working with WSDL Documents will carry over to the new one.

1. When coding the WSDL by hand, be very careful of the current namespace context. The string for the namespace must be exactly the same Working with Visual Studio .NET
for all references to the same namespace.
When creating a Web service application in Visual Studio .NET, the generated project automatically provides the test page that appears when the Web
service is accessed through the browser. Since we are developing Web services using the WSDL first approach, it is recommended that you disable
2. If your Web service must return a complicated data type for which the mapping to and from XML is not well defined, consider creating your this automatically generated WSDL and publish our own WSDL in a public location. To disable the automatically generated test page and WSDL,
own data type that represents the same data. This permits maximum portability while still allowing you to pass your necessary data. add the following into the <system.web> element of your web.config file of your project:
<webServices>
3. To promote modularity and re-use, use XSD import rather than inline schema definitions. See Web Service 2 and Web Service 3 samples for <protocols>
<remove name="Documentation" />
examples. </protocols>
</webServices>

4. Be careful of a data type's optional attributes in the XML Schema definition. Some of these can alter how the implementation code is In addition to the wsdl.exe approach to creating a Web service proxy class, you can also use the built in tools in Visual Studio .NET for a more user
generated. Refer to Web Service 2 for an example with the ID definition. friendly approach. The Add Web Reference dialog box will ask you to point it to a WSDL file, which it will take in then generate a proxy class.
Behind the scenes, the dialog essentially calls wsdl.exe in the background to process the WSDL file.
5. The Web Services Interoperability (WS-I) Organization is the official organization that was formed to promote interoperable Web services Unfortunately there is a bug in creating a client proxy if you use the Add Web Reference command in Visual Studio .NET 2002 to point to a WSDL
across all platforms and languages. The organization created a specification for interoperability called the WS-I Basic Profile and provides document that uses xsd:import. If this is your case, always use the wsdl.exe command to generate the client proxy. This bug has been fixed in Visual
tools to validate WSDL files against this specification. Studio .NET 2003, which will properly retrieve all the imported files and then generate the client proxy class.

6. When an exception occurs in the Web service, a SOAPFault element is returned in the SOAP message. Typically the Web service Creating the WSDL from Eclipse
framework will catch the SOAPFault and return its own Exception class. In the .NET Framework, SOAPFault is caught and wrapped in a
System.Web.Services.Protocols.SoapException. In WebSphere, com.ibm.ws.webservices.engine.WebServicesFault is the exception With the tools provided by the WSDK, the Web services functionality in Eclipse is similar to Visual Studio. In Eclipse, you will need to create a Java
that is thrown. Additional information about the error can be found by accessing the properties of the exception classes mentioned. Bean or EJB and use that as the template for a Web service. There are also some command line utilities you can use to generate Web service template
files. You can find documentation in Eclipse to get more detailed instructions on how to do this.

7. All XSD complex types are translated into classes. Because Java currently does not support enumerations, enumeration values are translated
to public static string constants in the corresponding Java class.
Acknowledgements
Thanks to Simon Guest of Microsoft for his excellent technical reviews and feedback. Also thanks to Neil Chopra and Mike Hanley of Vertigo
8. Some features of XSD schema cannot be represented well in some current platforms. One example is the unsigned integer types in XSD. Software for testing and helping with some of the ideas in this paper.
Although .NET provides unsigned types, Java does not. Therefore using unsigned integers types within interoperable Web services is not
recommended. Useful Links
9. Using arrays is tricky when working with boundary conditions. In .NET, if an empty array is serialized, only the header XML element is Title Location
created. If a NULL array is serialized, it is completely ignored and nothing is serialized out as XML. On the other hand, Java will serialize Microsoft Web http://msdn.microsoft.com/webservices/
the XML element for both cases. The difference is that for the NULL case, the Web services runtime within WebSphere will tag the XML Services
element with an xsd:nil=true attribute to indicate that the array is null. Homepage
IBM Web http://www.ibm.com/webservices
10. When a WebSphere client de-serializes an empty .NET array, it will create an array with a NULL reference. If a WebSphere client Services
deserializes a null .NET array, a java.lang.NullPointerException exception is thrown. Homepage
BEA Web http://www.bea.com/webservices/
11. When a .NET client deserializes an empty WebSphere array, it will create an array that has Length equal to zero. When a .NET client Services
deserializes a null WebSphere array, it will set the array reference to NULL. Homepage
WS-I http://www.ws-i.org
Working with Wsdl.exe Organization

When a WSDL file references other files (i.e. XSD files), you must explicitly provide the location of these files as arguments to wsdl.exe. For security WS-I Basic http://www.ws-i.org/Profiles/BasicProfile-1.0.html
Profile Final
reasons, wsdl.exe will not automatically load files from the schemaLocation references in the WSDL file. For example, if you're generating the code
Specification
Yasser Shohoud http://msdn.microsoft.com/msdnmag/issues/02/12/WebServicesDesign/
Will Provost http://webservices.xml.com/pub/a/ws/2003/07/22/wsdlfirst.html
Top of Page

Manage Your Profile |Legal |Contact Us |MSDN Flash Newsletter


©2005 Microsoft Corporation. All rights reserved. Terms of Use |Trademarks |Privacy Statement

You might also like