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.
- Definitions
- Types
- Message
- Port Type
- Binding
- 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
<types>
<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:sequence>
<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" />
</xsd:sequence>
</xsd:complexType>
<!—Defining
Exceptionà
<xsd:element
name="NameMismatchFaultDetails">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="code" type="xsd:int"></xsd:element>
<xsd:element
name="message" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
|
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>
<message
name="addEmpResponse">
<part
name="response" type="xsd:string"></part>
</message>
<message
name="NameMisMatchException">
<part
name="NameMisMatchException"
element="tns:NameMismatchFaultDetails"></part>
</message>
<message
name="accept_header">
<part
name="Accept" type="xsd:string"></part>
</message>
|
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>
</operation>
</portType>
|
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" />
<input>
<soap:body
use="literal" namespace="http://cxfsoap.vcjain.com/"/>
</input>
<output>
<soap:body
use="literal" namespace="http://cxfsoap.vcjain.com/"/>
</output>
<fault
name="NameMisMatchException">
<soap:fault
name="NameMisMatchException" use="literal"
namespace="http://cxfsoap.vcjain.com/"/>
</fault>
</operation>
</binding>
|
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" />
</port>
</service>
|
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.
Comments
Post a Comment