Dive into WSDL

Everybody who is working with web service knows about WSDL document. WSDL stands for web service descriptive language and is used for describing a web service in language & implementation independent way. When I say language independent, means it is an xml document. WSDL document provides a detail description about a web service, about operation supported by web service, input and output parameter of an operation. With number of web service framework available, writing a web service is merely placing some annotations on business java class. Framework like CXF and others application server provides utility to generate a WSDL document using Java code and vice versa. With the use of utility we normally didn’t have to deal with different elements of WSDL document. But knowing about WSDL elements detail will help us to debug our application effectively.

I have created a sample web service project. You can access complete project from Git repository https://github.com/vcjain/webservice.git and can refer to employee.wsdl document.

A WSDL document has below top elements and they include other elements in turn.
  1. Definitions
  2. Types
  3. Message
  4. Port Type
  5. Binding
  6. Service

The <definitions> element is a root element and specifies namespace for different XML schemas.

<definitions name="employee" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                xmlns:tns="http://cxfsoap.vcjain.com/" xmlns="http://schemas.xmlsoap.org/wsdl/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://cxfsoap.vcjain.com/">

The name attribute is merely a name given to a WSDL document. It is not used in any processing and acts as an identifier only. In above example we have used default namespace for WSDL schema hence we can avoid prefix on a wsdl schema element in rest of document. The targetNamespace attribute will identify the namespace for element define in the WSDL document.

The <types> element is used to define any custom data type used in web service. For an example in our web service we have a POJO object Employee which is an input parameter in addEmployee operation. We can define Employee schema in <types> element. We can also import a schema specifying a location. Prefer to define all imports before defining any XML element. Below is how a <types> element declaration looks like in the WSDL document
          <import namespace=" http://cxfsoap.vcjain.com/"  location="http://cxfsoap.vcjain.com/department.xsd"/>
          <xsd:schema targetNamespace="http://cxfsoap.vcjain.com/">

<!—Defining Employee objectà
<xsd:complexType name="employee">
                                                <xsd:element minOccurs="0" name="firstName" type="xsd:string" />
                                                                <xsd:element name="ID" type="xsd:long" />
                                                                <xsd:element minOccurs="0" name="lastName" type="xsd:string" />
                                                                                <xsd:element maxOccurs="unbounded" minOccurs="0" name="subjects"
                                                                                                nillable="true" type="xsd:string" />

<!—Defining Exceptionà
<xsd:element name="NameMismatchFaultDetails">
                                                                                                <xsd:element name="code" type="xsd:int"></xsd:element>
                                                                                                <xsd:element name="message" type="xsd:string"></xsd:element>


In above snippet we have defined two Java object Employee and NameMisMatchException which are used in our web service. Other tags are simple XML tag used to define a schema.

The <message> element is used to describe incoming and outgoing messages of the web service. The way a message is define is based on whether we use messaging style as ‘rpc’ or ‘document’. In WSDL document we define multiple messages corresponding to input parameter, out parameter, SOAP headers and faults. A message in itself cannot be identified as input/output/fault. These messages are further referenced in <porttype> element to define their basic type (input/output/fault) and associate them with operations. The name attribute can have any name but it is a good convention to suffix message with request, response and fault to specify as Input, output and Exception message.
                 <message name="addEmpRequest">
                                <part name="employee" type="tns:employee"></part>
                <message name="addEmpResponse">
                                <part name="response" type="xsd:string"></part>
                <message name="NameMisMatchException">
                                <part name="NameMisMatchException" element="tns:NameMismatchFaultDetails"></part>
                <message name="accept_header">
                                <part name="Accept" type="xsd:string"></part>

A message can have a multiple parts. You can consider each part as a separate argument. If a method in your web service takes two arguments then we may need to define a message with two parts and each part representing an argument. In Java for calling a method we need to pass method argument in specified order hence in WSDL parts will take precedence in the order in which we define in WSDL document; moreover we can define order of parts (argument) in operation element under <porttype>. When we implement a web service in Java we can have only one return type hence an output message will only have one part. Since a web service can be implemented in any language other than Java, there is a notion of multiple parts in output message too.

The <porttype> element defines an abstract interface of a Web service. It resemble to a Java interface, with operation element resembling to Interface methods.
<portType name="EmpService">
                                <operation name="addEmp">
                                                <input message="tns:addEmpRequest"></input>
                                                <output message="tns:addEmpResponse"></output>
                                                <fault  name="NameMisMatchException" message="tns:NameMisMatchException"></fault>
The <operation> element defines name of operation and input, output and fault parameters. Each
Operation is composed of at most one input or output element and any number of fault elements. You can add parameterOrder attribute to operation tag to define specific order of input parts.

The <binding> element relates the abstract interface <porttype> element to concrete internet protocols, messaging styles and encoding styles. The <binding> element is composed of two different namespace elements, wsdl specific elements and protocol specific elements.

<binding name="EmpServiceBinding" type="tns:EmpService">
                                <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
                                                style="rpc" />
                                <operation name="addEmp">
                                                <soap:operation style="rpc" />
                                                                <soap:body use="literal" namespace="http://cxfsoap.vcjain.com/"/>
                                                                <soap:body use="literal" namespace="http://cxfsoap.vcjain.com/"/>
                                                <fault name="NameMisMatchException">
                                                                <soap:fault name="NameMisMatchException" use="literal" namespace="http://cxfsoap.vcjain.com/"/>

Each internet protocol has their own set of elements which describe protocol specific settings. In above snippet we have associate <porttype> with a SOAP protocol. Hence you can see different SOAP protocol specific tag like soap:binding, soap:operation, soap:body in binding element. If you are using HTTP protocol then you may have define http:binding, http:operation, http:urlEncoded etc elements.

The soap:binding element specify the internet protocol used to send soap messages (transport attribute)and default messaging style for operations (style attribute). J2EE web service only supports soap protocol and HTTP protocol for message transfer. The soap:operation element is specific to each operation and can override the default messaging style define in soap:binding element. The element soap:body specify encoding style of input, output and fault parameters (use attribute). It can be set to literal or encoding. If you closely look then you find that operation element of <binding> is directly associated with the operation element of <porttype>. In binding element we are associating each port type operation with its messaging and encoding style and defining a transfer protocol for a web service. There are some other soap specific elements also like soap:header, soap:headerfault etc but these are optional.

The last element is the <service> element which associated an endpoint URI (address) with a web service definition.
<service name="EmpService">
                                <port name="EmpServicePort" binding="tns:EmpServiceBinding">
                                                <soap:address location="http://localhost:8080/cxfsoap/emp" />

The service element may contain one or more port element, where each port element represents a web service. The type attribute must have a binding reference.

Conclusion: There are two approaches for developing and publishing a web service, one is to write some Java code and then generate a WSDL document and another is to create a WSDL document first and use it for web service implementation. It will be helpful to know basic knowledge of each element for second approach of web service development. Knowing about different elements of WSDL document will help us in defining WSDL document and help us in effective debugging.


Popular posts from this blog

Profiling Java Application using annotation

OAuth Simplified