Introduction to Web Services Description Language


WSDL was originally designed by IBM, Microsoft, and Ariba to provide a standard mechanism for describing Web services. This work was then submitted to the W3C for standardization and has grown to encompass a large number of vendors. Similar to CORBA IDL, WSDL was designed to meet the needs of distributed systems. WSDL is a standard format for describing Web service interfaces. Using WSDL, tools can automate the generation of proxies for Web services in a language-independent and platform-independent way. Like CORBA IDL, a WSDL file is a contract between client and server.

Note that WSDL has been designed such that it can express bindings to protocols other than SOAP. In this chapter, we examine WSDL as it relates to SOAP over HTTP.

Summary of the WSDL Formal Specification

The elements within a WSDL document can be divided into two groups: the service interface definition and service implementation definition. A service interface definition is an abstract or reusable service definition that may be referenced by multiple service implementation definitions. This is analogous to defining an abstract interface in a programming language and having multiple concrete implementations. The service interface contains three elements that comprise the reusable portion of the service description, including <types>, <message>, <portType>, and <binding> elements. The service implementation definition describes how a particular service interface is implemented by a given service provider, and it also describes its location so that a requestor can interact with it. In WSDL, a Web service is modeled as a <service> element. It contains a collection of <port> elements—the <port> element associates a URL (endpoint) with a <binding> element from the service interface definition. This discussed in more detail below.

WSDL documents use the following elements for defining network services:

  • Types Machine- and language-independent type definitions are specified by the <types> element. This element provides data type definitions used in messages using some type system. For maximum interoperability and platform neutrality, WSDL prefers the use of XSD as the canonical type system.

  • Message Abstract, typed definition of the data being transmitted. A message consists of logical parts, each of which is associated with a type-definition within some type system or encoding scheme. A message can be thought of as an operation/method parameter.

  • Operation Abstract description of an action supported by the service. An operation element, including its sub-elements, collectively define a signature (operation name, input parameters, and output parameters). There are four forms of primitive operations based on the nature of the interaction: one-way, request-response, notification, and solicit-response.

  • PortType Abstract interface (set of operations) supported by one or more endpoints. An interface refers to one or more operations, input messages, and output messages. Like the CORBA IDL interface, a <portType> element including its sub-elements collectively define a group of operations.

    Note

    Recapping this discussion, the <portType> is an abstract interface that consists of abstract <operation>(s). <operation> has parameters defined by abstract <message>(s). Each <message> parameter is defined within the <types> element.

  • Binding Specifies concrete protocol and data format specifications for the <operation>(s) and <message>(s) defined by a particular <portType>. A <portType> is abstract and not realizable unless associated with a <binding>. Similar to a Java class that implements an Interface, a <binding> provides the implementation details for the <portType>.

  • Port Specifies an address for a binding, thus defining a single communication endpoint. It is actually defining the network address (IP) of the machine that is hosting the service.

  • Service Specifies a collection of related ports that make up the service. This has the effect of packaging all the previously discussed elements into a single service offering.

We recap these definitions with a WSDL document in the next subsection. One way of looking at a WSDL file is that it determines what gets sent over the wire. WSDL, in addition to defining the "interface contract," also specifies the transport protocol for interacting with the service interface. WSDL also specifies whether SOAP messages employ RPC- or document-style semantics. An RPC-style message looks like a function call with zero or more parameters, and employs the request-response semantics, whereas a document-style message is used for exchanging an XML document. We elaborate further on this in later sections.

A Closer Look at a Sample WSDL File

WSDL is very verbose. To understand each element of a WSDL construct, we use a very simple example. We take a bottom-up approach starting with a Java class with a single method. We examine the automatically generated WSDL representation of our simple Java class. As noted earlier, developers will usually use a tool for generating the WSDL; in our case we have employed the BEA WebLogic Workshop for building this simple Web service example. Think of WSDL as our contract on the Internet to the outside world—in this section we generate WSDL for the simple service MyService shown here:

 public class MyService {     public int foo(int arg) {         return arg;     } } 

This Java class contains a method foo(), which accepts an integer parameter and returns the same value. A WSDL document needs to be created for describing foo() within the context of a Web service. The following WSDL has been generated using the BEA WebLogic Workshop tool; as such, some of the URIs used in this document are BEA specific. The WSDL document shown can be used by any SOAP client to access MyService's (the Web service) foo() method. Observe the complexity of representing a simple service using WSDL. We discuss each element of the following WSDL document later in this section.

 <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:conv="http://www.openuri.org/2002/04/soap/conversation/" xmlns:cw="http://www.openuri.org/2002/04/wsdl/conversation/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"  xmlns:jms="http://www.openuri.org/2002/04/wsdl/jms/"  xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"  xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://www.openuri.org/"  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:xm="http://www.bea.com/2002/04/xmlmap/"  targetNamespace="http://www.openuri.org/">      <types>           <s:schema attributeFormDefault="qualified"                        elementFormDefault="qualified"                        targetNamespace="http://www.openuri.org/">                 <s:element name="foo">                      <s:complexType>                           <s:sequence>                                <s:element minOccurs="1" maxOccurs="1"                                                name="arg" type="s:int"/>                           </s:sequence>                      </s:complexType>                 </s:element>                 <s:element name="fooResponse">                      <s:complexType>                           <s:sequence>                                <s:element minOccurs="1" maxOccurs="1"                                                name="fooResult" type="s:int"/>                           </s:sequence>                      </s:complexType>                 </s:element>                 <s:element name="int" type="s:int"/>           </s:schema>      </types>      <message name="fooSoapIn">           <part name="parameters" element="s0:foo"/>      </message>      <message name="fooSoapOut">           <part name="parameters" element="s0:fooResponse"/>      </message>      <message name="fooHttpGetIn">           <part name="arg" type="s:string"/>      </message>      <message name="fooHttpGetOut">           <part name="Body" element="s0:int"/>      </message>      <message name="fooHttpPostIn">           <part name="arg" type="s:string"/>      </message>      <message name="fooHttpPostOut">           <part name="Body" element="s0:int"/>      </message>      <portType name="MyServiceSoap">           <operation name="foo">                <input message="s0:fooSoapIn"/>                <output message="s0:fooSoapOut"/>           </operation>      </portType>      <portType name="MyServiceHttpGet">           <operation name="foo">                <input message="s0:fooHttpGetIn"/>                <output message="s0:fooHttpGetOut"/>           </operation>      </portType>      <portType name="MyServiceHttpPost">           <operation name="foo">                <input message="s0:fooHttpPostIn"/>                <output message="s0:fooHttpPostOut"/>           </operation>      </portType>      <binding name="MyServiceSoap" type="s0:MyServiceSoap">           <soap:binding transport="http://schemas.xmlsoap.org/soap/http"                           style="document"/>           <operation name="foo">                <soap:operation soapAction="http://www.openuri.org/foo"                                   style="document"/>                <input>                     <soap:body use="literal"/>                </input>                <output>                     <soap:body use="literal"/>                </output>           </operation>      </binding>      <binding name="MyServiceHttpGet" type="s0:MyServiceHttpGet">           <http:binding verb="GET"/>           <operation name="foo">                <http:operation location="/foo"/>                <input>                     <http:urlEncoded/>                </input>                <output>                     <mime:mimeXml part="Body"/>                </output>           </operation>      </binding>      <binding name="MyServiceHttpPost" type="s0:MyServiceHttpPost">           <http:binding verb="POST"/>           <operation name="foo">                <http:operation location="/foo"/>                <input>                     <mime:content type="application/x-www-form-urlencoded"/>                </input>                <output>                     <mime:mimeXml part="Body"/>                </output>           </operation>      </binding>      <service name="MyService">           <port name="MyServiceSoap" binding="s0:MyServiceSoap">                <soap:address                          location="http://server1:7001/WS_MyService/MyService.jws"/>            </port>           <port name="MyServiceHttpGet" binding="s0:MyServiceHttpGet"> <http:address                  location="http://server1:7001/WS_MyService/MyService.jws"/>           </port>           <port name="MyServiceHttpPost" binding="s0:MyServiceHttpPost">                <http:address                    location="http://server1:7001/WS_MyService/MyService.jws"/>           </port>      </service> </definitions> 

You will probably agree that for the simple service depicted by class MyService, one will not want to manually define WSDL. Developing Web services without the use of advanced tools is not recommended. Once the WSDL is created, the vendor tool can help create stubs and proxies, and the Web service can be subsequently used by a SOAP client written in any programming language. The wide availability of tools to automate development of Web services from existing server-side components allows the developer to focus on developing business services rather than develop any infrastructure components. Developing a Web service requires two steps:

  1. Implement the business logic in a server-side component. This is discussed in Chapter 7.

  2. Expose the business component interface as a Web service using WSDL. This is the subject of this section.

WSDL data typing is based on "XML Schema: Datatypes" (XSD), which is now a W3C recommendation. There are different versions of this document (1999, 2000, and 2001), and declaring it as one of the namespace attributes in the <definitions> element specifies which version is used in our WSDL file. For instance the declaration, xmlns:s="http://www.w3.org/2001/XMLSchema", makes all the predefined types, specified in the XMLSchema 2001 version, available to the MyService WSDL definition. This namespace is referred by other constructs using the s prefix, as in s:int, which makes a reference to the predefined type int defined in the XMLSchema.

WSDL Namespaces

Several namespaces have been declared in the root element <definitions>. These namespace declarations provide a shorthand for each namespace used in the document. For instance xmlns:xsd defines a shorthand xsd for the namespace http://www.w3.org/2001/XMLSchema. This enables references to this namespace later in the document simply by prefixing (or "qualifying") a name with xsd: as in xsd:int, which is a qualified type name. Normal scoping rules apply for the shorthand prefixes. For example, a prefix defined in an element only holds within that element.

The purpose of namespaces is to avoid naming conflicts. It is similar to namespace in C++ or in the Java programming language. Two separate Java packages may define the same variable or method names. An importer of these packages can refer to a name, unambiguously, if package qualification is used. In our example, all types in the conv namespace can be referenced by using conv:typename. conv: is a shorthand for http://www.openuri.org/2002/04/soap/conversation/.

Note that URIs are used as namespaces because they guarantee uniqueness. The location pointed to by the URI does not have to correspond to a real Web location. The targetNamespace attribute declares a namespace to which all element names declared within the MyService WSDL will belong. In the sample WSDL file, the targetNamespace specified in <definitions> is http://www.openuri.org/.

In the sample GreaterCause example discussed later, you will observe that the targetNamespace is http://www.GreaterCause.com, and the corresponding datatypes as seen by the clients of the Web service will use com.GreaterCause.www as package prefix.

Types

The <types> element may be omitted if there are no data types that need to be declared. For those who programmed CORBA IDL, this section resembles IDL type definitions that are used by the IDL operation definitions. For maximum interoperability and platform neutrality, WSDL prefers the use of XSD as the canonical type system, and treats it as an intrinsic type system. This is apparent from the use of the namespace xmlns:s="http://www.w3.org/2001/XMLSchema" in our sample WSDL.

 <types>     <s:schema ...>         <s:element name="foo">             <s:complexType>                 <s:sequence>                     <s:element minOccurs="1" maxOccurs="1"                                name="arg" type="s:int"/>                 </s:sequence>             </s:complexType>         </s:element>         <s:element name="fooResponse">             <s:complexType>                 <s:sequence>                     <s:element minOccurs="1" maxOccurs="1"                                name="fooResult" type="s:int"/>                 </s:sequence>             </s:complexType>         </s:element>         <s:element name="int" type="s:int"/>     </s:schema> </types> 

The type names "arg" and "fooResponse" are defined within the body of the <types> element using the <s:element> element. These definitions are subsequently used within the <message> element to define the parameters—this is done using the name and element attributes of its subordinate <part> element.

Messages

A <message> element defines the parameters for an operation/method. Each <part> child element in the <message> element corresponds to a parameter that is passed to the operation. Input parameters are defined in a single <message> element, separate from output parameters, which have their own <message> elements. Parameters that are both input and output have their corresponding <part> elements in both input and output <message> elements. By convention, the name of a return <message> element ends in Response, as in fooResponse to correspond to the method foo. Each <part> element has a name and type attribute, just as a method parameter has both a name and a type, where the attribute element refers to the element we described using the <element> construct in the <types> section. When used for document exchange (in contrast to RPC operations), WSDL allows the use of <message> elements to describe the document to be exchanged. The message-typing attribute element refers to an XSD element using a QName (prefixed by s0:). The message-typing attribute type refers to an XSD simpleType or complexType using a QName (prefixed by s:). Prefix s0: refers to targetNamespace="http://www.openuri.org/, which is the namespace associated with this WSDL, and therefore references the elements with name foo and fooResponse from the <types> section. Prefix s: refers to xmlns:s= "http://www.w3.org/2001/XMLSchema and the related XSD type system. A message binding describes how the abstract content is mapped into a concrete format. We cover a more complex scenario when discussing the sample application's (GreaterCause) Web service implementation in the section "Web Service Implementation."

 <message name="fooSoapIn">     <part name="parameters" element="s0:foo"/> </message> <message name="fooSoapOut">     <part name="parameters" element="s0:fooResponse"/> </message> <message name="fooHttpGetIn">     <part name="arg" type="s:string"/> </message> <message name="fooHttpGetOut">     <part name="Body" element="s0:int"/> </message> <message name="fooHttpPostIn">     <part name="arg" type="s:string"/> </message> <message name="fooHttpPostOut">     <part name="Body" element="s0:int"/> </message> 

The WSDL tool generated <message> elements for three separate bindings—fixed XML, HTTP Get, and HTTP Post as follows:

  • For XML binding fooSoapIn, fooSoapOut

  • For HTTP Get binding fooHttpGetIn, fooHttpGetOut

  • For HTTP Post binding foorHttpPostIn, fooHttpPostOut

The message names provide a unique name for messages defined within the enclosing WSDL document, while the part name provides a unique name among all parts within the enclosing message.

Port Types

A <portType> element defines one or more abstract operations using <operation> elements. For our simple service, MyService the tool produces three separate contracts as follows. Notice that the messages bound to the various operations have been defined in the current namespace (prefixed by s0:) using the <message> elements discussed in the preceding subsection.

 <portType name="MyServiceSoap">     <operation name="foo">         <input message="s0:fooSoapIn"/>         <output message="s0:fooSoapOut"/>     </operation> </portType> <portType name="MyServiceHttpGet">     <operation name="foo">         <input message="s0:fooHttpGetIn"/>         <output message="s0:fooHttpGetOut"/>     </operation> </portType> <portType name="MyServiceHttpPost">     <operation name="foo">         <input message="s0:fooHttpPostIn"/>         <output message="s0:fooHttpPostOut"/>     </operation> </portType> 

The port type name attribute provides a unique name among all port types defined within the enclosing WSDL document. MyServiceSoap allows access to MyService using standard fixed XML format (document-style messages). MyServiceHttpGet allows access to MyService using a standard HTTP Get call, and MyServiceHttpPost allows access to MyService using a standard HTTP Post call. These abstract operations (contracts) will "bind" to their corresponding concrete protocols and associated data formats using the <binding> element discussed in the next section. The <operation> element can have one, two, or three child elements, namely, the <input>, <output>, and <fault> elements. These constructs specify how SOAP messages are constructed; this is discussed further in the section "Introduction to Simple Object Access Protocol." WSDL has four transmission primitives or message exchange patterns that an endpoint can support.

  • One-way The endpoint receives a message. Only the <input> element is specified for the corresponding WSDL construct. This is used for creating asynchronous services. In this scenario, the client application that invokes the Web service never receives a response, including any exceptions.

  • Request-response The endpoint receives a message, and sends a correlated message. This model is used in the GreaterCause example. In this scenario, the <input>, <output>, and an optional <fault> element specify the abstract message format.

  • Solicit-response The endpoint sends a message, and receives a correlated message. In this scenario, the <input>, <output> and an optional <fault> element specify the abstract message format. Specification precedes <input> and <fault> specifications.

  • Notification The endpoint sends a message. Only the <output> element is specified for the corresponding WSDL construct.

WSDL refers to these primitives as operations. Although request-response or solicit-response can be modeled abstractly using two one-way messages, it is useful to model these as primitive operation types. These primitives represent message exchange patterns. Although the request-response or the solicit-response operations are semantically related, they may be implemented as part of one or two actual network communications. The primitives are merely an abstract representation. It is the binding that will specify how the messages are actually sent. WSDL only defines bindings for one-way and request-response primitives.

Bindings

The purpose of the <binding> element is to specify how each <operation>, with corresponding parameters, and the correlated response is sent over the wire using the SOAP message format. The immediate child elements of the <binding> element are used to specify the concrete grammar for the input, output, and fault messages. In MyService WSDL snippet shown below, the <soap:binding> element specifies the protocol (using the transport attribute) and data format (using style attribute) for each <operation> scoped within the parent <binding> element. Each binding must specify exactly one protocol. SOAP allows each operation to be realized using a different invocation style. Let's examine the binding MyServiceSoap, which specifies document-style message exchange; this is the first <binding> element in the following snippet. The binding MyServiceSoap references the corresponding portType that it binds using the type attribute.

 <binding name="MyServiceSoap" type="s0:MyServiceSoap">    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"                  style="document"/>    <operation name="foo">        <soap:operation soapAction="http://www.openuri.org/foo"                        style="document"/>        <input>             <soap:body use="literal"/>        </input>        <output>            <soap:body use="literal"/>        </output>    </operation> </binding> <binding name="MyServiceHttpGet" type="s0:MyServiceHttpGet">     <http:binding verb="GET"/>     <operation name="foo">         <http:operation location="/foo"/>         <input>             <http:urlEncoded/>         </input>         <output>             <mime:mimeXml part="Body"/>         </output>     </operation> </binding> <binding name="MyServiceHttpPost" type="s0:MyServiceHttpPost">     <http:binding verb="POST"/>     <operation name="foo">         <http:operation location="/foo"/>         <input>             <mime:content type="application/x-www-form-urlencoded"/>         </input>         <output>                 <mime:mimeXml part="Body"/>         </output>         </operation> </binding> 

For binding MyServiceSoap, the transport attribute in the WSDL fragment instructs the SOAP runtime to use HTTP as the transport because it is set to http://schemas.xmlsoap.org/soap/http. The transport attribute also instructs it to use document-oriented messages, because the style attribute of the <soap:binding> element is set to "document"; the value of the style attribute is the default attribute for each contained <soap:operation> element. The <operation> element with name="foo" specifies binding information for the operation foo defined in the portType element. The following snippet is a mapping of the MyServiceSOAP binding construct to its corresponding SOAP message (wire format):

 <SOAP-ENV:Envelope   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">    <SOAP-ENV:Body>           <m:foo xmlns:m="http://www.openuri.org/">                  <arg>2222</arg>           </m:foo>    </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

The <soap:body> element specifies how the message parts appear inside the SOAP Body element. When the operation ‘style’ attribute is ‘rpc’, each part is a parameter or a return value and appears inside a wrapper element within the body (refer to section 7.1 of the SOAP specification). This wrapper element in named identically to the operation name. Each message part appears under the wrapper, represented by an accessor named identically to the corresponding parameter of the call. If the operation ‘style’ attribute is ‘document’, there are no additional wrappers, and the message parts appear directly under the SOAP Body element. A comparison between ‘rpc’ and ‘document’ style messages is discussed in the section "Workshop SOAP:style Semantics."

The mandatory ‘use’ attribute indicates whether the message parts (the parameters of foo) are encoded using some encoding rules, or whether the parts define the concrete schema of the message. If the ‘use’ attribute is set to ‘encoded’, each message part references an abstract type using the ‘type’ attribute. In our example, the use is set to "literal" meaning that each part of the message (that is, foo's parameters) references a concrete definition using the ‘element’ or ‘type’ attribute specified in the message elements. Note that WSDL includes a binding for HTTP 1.1's GET and POST verbs in order to describe the interaction between an HTTP client and an HTTP server. For details on serialization rules for message parts, please refer to the SOAP specification at http://www.w3.org/TR/SOAP/.

Observe the use of <http:urlEncoded/> in the binding MyServiceHttpGet.The urlEncoded element indicates that all message parts are encoded into the HTTP request URI using the standard URI-encoding rules.

Services

The services element contains <port> elements, each of which refers to a <binding> element discussed previously. A port defines an endpoint; it specifies the location of the Web service and the associated binding. In our sample MyService WSDL, the following construct is created for identifying the MyService Web service:

 <service name="MyService">      <port name="MyServiceSoap" binding="s0:MyServiceSoap">           <soap:address               location="http://server1:7001/WS_MyService/MyService.jws"/>      </port>      <port name="MyServiceHttpGet" binding="s0:MyServiceHttpGet">           <http:address               location="http://server1:7001/WS_MyService/MyService.jws"/>      </port>      <port name="MyServiceHttpPost" binding="s0:MyServiceHttpPost">      <http:address          location="http://server1:7001/WS_MyService/MyService.jws"/>      </port> </service> 

MyServiceSoap defines the endpoint for MyService. The tool generated three separate bindings (XML, HTTP GET, and HTTP POST), and defined a corresponding port for each binding. Note that all locations point to MyService, implying that the same service can be called by three different clients, each associated with a different binding. Each port provides semantically equivalent behavior. The SOAPAction attribute of the HTTP header specifies the URI of the end point servicing the SOAP request.




Practical J2ee Application Architecture
Practical J2EE Application Architecture
ISBN: 0072227117
EAN: 2147483647
Year: 2003
Pages: 111
Authors: Nadir Gulzar

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net