Sharing My Personal Notes on WSDL and SOAP binding

In an unfortunate event few months back, I lost most of part from my learning notes (that’s what I call the collection). However I noticed one of my document which I wanted to print left in my pd, my learning notes on WSDL for operational web service. Which I created during my training course on SOA by www.javapassion.com. So here I am making these fortunate notes eternal.
So let’s start this lengthy post, which I may cut short later when get time to review.
A web-service is a service which has Programmatic Interfaces exposed over Internet for app. to app. communication. WSDL is the way to define the web service interface for SOAP binding.
WSDL
The key value proposition of WSDL as a standard description of web service is it enables automation of communication details in app. to app. communication. That is, machines can figure out from WSDL document what services are available and how to invoke them without manual pre-arrangement or preconfiguration between the two.
Please also note WSDL’s limitation as well. It defines only the low-level aspects of a web service. That is, it does not specify the high-level business collaboration semantics. Again, this is where ebXML business process and partner profile concept can be very useful.

Under WSDL, a Web service is described as a set of communication endpoints that are capable of exchanging messages. These communication endpoints are called ports. An endpoint is made of two parts:

  • 1. Abstract definitions of operations and messages
  • 2. Concrete binding to networking protocol (and corresponding endpoint address) and message encoding. One concrete example of network protocol is SOAP over HTTP.

The whole idea of this separation of abstract definitions from concrete binding is to allow the reuse of abstraction definitions regardless of present or future network protocols.

WSDL Elements: WSDL specification defines 7 element types.
1. Types: Data type definitions, used to describe exchanged messages
2. Message: Abstract, typed definitions of data being exchanged
3. Operation: Abstract description of an action. Refers to an input and/or output messages
4. Port Type: Collection of operations, Abstract definition of a service
5. Binding: Concrete protocol and data format (encoding) for a particular Port type

  • Protocol examples: SOAP 1.1 over HTTP or SOAP over SMTP
  • Encoding examples: SOAP encoding, RDF encoding

6. Port: Defines a single communication endpoint

  • Endpoint address for binding
  • URL for HTTP, email address for SMTP

7. Service: Aggregate set of related ports

WSDL Syntax: The grammar for a WSDL is as below

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl"
		targetNamespace="your namespace here"
		xmlns:tns="your namespace here"
		xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap">

	<wsdl:types>
		<xs:schema targetNamespace="your namespace here (could be another) "
			xmlns:xsd="http://www.w3.org/2001/XMLSchema"
			<!-- Define types and possibly elements here -->
		</schema>
	</wsdl:types>

	<wsdl:message name="some operation input">
		<!-- part(s) here -->
	</wsdl:message>
	<wsdl:message name="some operation output">
		<!-- part(s) here -->
	</wsdl:message>

	<wsdl:portType name="your type name">
		<!-- define operations here in terms of their messages -->
	</wsdl:portType>

	<wsdl:binding name="your binding name" type="tns:port type name above">
		<!-- define style and transport in general and use per operation -->
	</wsdl:binding>

	<wsdl:service>
		<!-- define a port using the above binding and a URL -->
	</wsdl:service>

</wsdl:definitions>

Types of Operations
1. One-way: The endpoint receives a message

	<operation name=”submitPurchase”>
		<input message=”purchase”/>
	</operation>
	

2. Request/response: The endpoint receives a message, and sends a correlated message

	<operation name=”submitPurchase”>
		<input message=”purchase”/>
		<output message=”confirmation”/>
	</operation>
	
	<operation name=”submitPurchase”>
		<input message=”purchase”/>
		<output message=”confirmation”/>
		<fault message=”faultMessage”/>
	</operation>

	

3. Notification: The endpoint sends a message

	<operation name=”deliveryStatus”>
		<output message=”trackingInformation”/>
	</operation>
	

4. Solicit/response: The endpoint sends a message, and receives a correlated message

	<operation name=”clientQuery”>
		<output message=”bandwidthRequest”/>
		<input message=”bandwidthInfo”/>
		<fault message=”faultMessage”/>
	</operation>
	

Authoring Style Recommendation

  • Reusability and maintainability
  • Maintain WSDL document in 3 separate parts
  • – Data type definitions
    – Abstract definitions
    – Specific service bindings

  • Use “import” element to import necessary part of WSDL document

Stockquote example Schema and WSDL:

A. stockquote.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://example.com/stockquote/schemas"
	xmlns="http://www.w3.org/2000/10/XMLSchema">
	<element name="TradePriceRequest">
		<complexType>
			<all>
				<element name="tickerSymbol" type="string" />
			</all>
		</complexType>
	</element>
	<element name="TradePrice">
		<complexType>
			<all>
				<element name="price" type="float" />
			</all>
		</complexType>
	</element>
</schema>

B. stockquote.wsdl

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="StockQuote"
	targetNamespace="http://example.com/stockquote/definitions" 	   xmlns:tns="http://example.com/stockquote/definitions"
	   xmlns:xsd1="http://example.com/stockquote/schemas" 	   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	   xmlns="http://schemas.xmlsoap.org/wsdl/">
	<import namespace="http://example.com/stockquote/schemas"
		location="http://example.com/stockquote/stockquote.xsd" />
	<message name="GetLastTradePriceInput">
		<part name="body" element="xsd1:TradePriceRequest" />
	</message>
	<message name="GetLastTradePriceOutput">
		<part name="body" element="xsd1:TradePrice" />
	</message>
	<portType name="StockQuotePortType">
		<operation name="GetLastTradePrice">
			<input message="tns:GetLastTradePriceInput" />
			<output message="tns:GetLastTradePriceOutput" />
		</operation>
	</portType>
</definitions> 

C. stockquoteservice.wsdl

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="StockQuote" targetNamespace="http://example.com/stockquote/service"
	   xmlns:tns="http://example.com/stockquote/service" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	   xmlns:defs="http://example.com/stockquote/definitions" xmlns="http://schemas.xmlsoap.org/wsdl/">
	<import namespace="http://example.com/stockquote/definitions"
		location="http://example.com/stockquote/stockquote.wsdl" />
	<binding name="StockQuoteSoapBinding" type="defs:StockQuotePortType">
		<soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" />
		<operation name="GetLastTradePrice">
			<soap:operation soapAction="http://example.com/GetLastTradePrice" />
			<input>
				<soap:body use="literal" />
			</input>
			<output>
				<soap:body use="literal" />
			</output>
		</operation>
	</binding>
	<service name="StockQuoteService">
		<documentation>My first service</documentation>
		<port name="StockQuotePort" binding="tns:StockQuoteBinding">
			<soap:address location="http://example.com/stockquote" />
		</port>
	</service>
</definitions> 

Binding Element: A binding defines message format and protocol details for operations and messages defined by a particular portType. There may be any number of bindings for a given portType.

  • Defines protocol details and message format for operations and messages defined by a particular portType
  • Specify one protocol out of
    – SOAP (SOAP over HTTP, SOAP over SMTP)
    – HTTP GET/POST
  • Provides extensibility mechanism
    – Can includes binding extensibility elements
    – Binding extensibility elements are used to specify the concrete grammar

Binding Element Syntax: The grammar for a binding is as below.

			
<wsdl:definitions .... >
	...
	<wsdl:binding name="nmtoken" type="qname"> *
	<-- extensibility element per binding --> *
	
	<wsdl:operation name="nmtoken"> *
		<-- extensibility element per operation --> *

		<wsdl:input name="nmtoken"? > ?
			<-- extensibility element per input -->
		</wsdl:input>
	
		<wsdl:output name="nmtoken"? > ?
			<-- extensibility element per output --> *
		</wsdl:output>
	
		<wsdl:fault name="nmtoken"> *
			<-- extensibility element per fault --> *
		</wsdl:fault>

	</wsdl:operation>
	</wsdl:binding>
</wsdl:definitions>

SOAP Binding Extension: WSDL includes a binding for SOAP 1.1 endpoints, which supports the specification of the following protocol specific information:

  • An indication that a binding is bound to the SOAP 1.1 protocol
  • A way of specifying an address for a SOAP endpoint.
  • The URI for the SOAPAction HTTP header for the HTTP binding of SOAP
  • A list of definitions for Headers that are transmitted as part of the SOAP Envelope

This binding grammar it is not an exhaustive specification since the set of SOAP bindings is evolving. Nothing precludes additional SOAP bindings to be derived from portions of this grammar. For example:

  • SOAP bindings that do not employ a URI addressing scheme may substitute another addressing scheme by replacing the soap:address element defined in section 3.8.
  • SOAP bindings that do not require a SOAPAction omit the soapAction attribute defined in section 3.4.

SOAP Binding Extensions Syntax: The SOAP Binding extends WSDL with the various extension elements shown below highlighted.

<definitions ....>
  <binding ....>
    <soap:binding style="rpc|document" transport="uri">
    <operation ....>
      <soap:operation soapAction="uri"? style="rpc|document" ?>?
        <input>
          <soap:body parts="nmtokens"? use="literal|encoded"
            encodingStyle="uri-list"? namespace="uri" ?>
            <soap:header message="qname" part="nmtoken" use="literal|encoded"
              encodingStyle="uri-list"? namespace="uri"?>*
              <soap:headerfault message="qname" part="nmtoken"
                use="literal|encoded" encodingStyle="uri-list"? namespace="uri"? />*
            <soap:header>
        </input>
        <output>
          <soap:body parts="nmtokens" ? use="literal|encoded"
            encodingStyle="uri-list" ? namespace="uri" ?>
            <soap:header message="qname" part="nmtoken" use="literal|encoded"
              encodingStyle="uri-list" ? namespace="uri" ?>*
              <soap:headerfault message="qname" part="nmtoken"
                use="literal|encoded" encodingStyle="uri-list" ? namespace="uri" ? />*
              <soap:header>
        </output>
        <fault>*
          <soap:fault name="nmtoken" use="literal|encoded" encodingStyle="uri-list" ? namespace="uri" ?>
        </fault>
    </operation>
  </binding>
  <port ....>
    <soap:address location="uri" />
  </port>
</definitions>

soap:binding:- The soap:binding element MUST be present when using the SOAP binding. The purpose of the SOAP binding element is to signify that the binding is bound to the SOAP protocol format: Envelope, Header and Body. This element makes no claims as to the encoding or format of the message

<definitions ....>
	<binding ....>
		<soap:binding transport="uri" ? style="rpc|document" ?>
	</binding>
</definitions>

1. style attribute applies to each contained operation (default: document) unless it is overidden by operation specific style attribute
2. transport attribute indicates which transport to use
http://schemas.xmlsoap.org/soap/http (for HTTP)
http://schemas.xmlsoap.org/soap/smtp (for SMTP)

soap:operation:

<definitions ....>
	<binding ....>
		<operation ....>
			<soap:operation soapAction="uri" ? style="rpc|document" ?>?
		</operation>
	</binding>
</definitions>

1. style attribute indicates whether the operation is RPCoriented (messages containing parameters and return values) or document-oriented (message containing document(s))
– Affects the way in which the Body of the SOAP message is constructed on the wire.
2. soapAction attribute specifies the value of the SOAPAction header for this operation. This URI value should be used directly as the value for the SOAPAction header; no attempt should be made to make a relative URI value absolute when making the request.

soap:body: The binding element provides information on how to assemble the different message parts inside the Body element of the SOAP message. The element is used in both RPC-oriented and document-oriented messages, but the style of the enclosing operation has important effects on how the Body section is structured:

<definitions ....>
	<binding ....>
		<operation ....>
			<input>
				<soap:body parts="nmtokens" ? use="literal|encoded" ?
					encodingStyle="uri-list" ? namespace="uri" ?>
			</input>
			<output>
				<soap:body parts="nmtokens" ? use="literal|encoded" ?
					encodingStyle="uri-list" ? namespace="uri" ?>
			</output>
		</operation>
	</binding>
</definitions>


soap:body for RPC style:
If the operation style is rpc, each part is a parameter or a return value and appears inside a wrapper element within the body. The wrapper element is named identically to the operation name and its namespace is the value of the namespace attribute.

  • Each message part (parameter) appears under the wrapper, represented by an accessor named identically to the corresponding parameter of the call.
  • Parts are arranged in the same order as the parameters of the call.

WSDL document:

  • The operation name of WSDL document is used to name the wrapper element (immediate child element under element)
  • Name of the wrapper element is a method
    • Each part is a parameter or a return value and appears inside a wrapper element within the
      <soap:Body>

      SOAP message:

      • Contents of the Body are formatted as a struct
      • Parts are arranged in the same order as the parameters of the call

      Example: MyHelloServiceRpcLiteral.wsdl

      <?xml version="1.0" encoding="UTF-8"?>
      <definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
      	xmlns:tns="urn:Foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="MyHelloService"
      	targetNamespace="urn:Foo">
      	<types />
      	<message name="HelloIF_sayHello">
      		<part name="String_1" type="xsd:string" />
      		<part name="Integer_2" type="xsd:int" /> </message>
      	<message name="HelloIF_sayHelloResponse">
      		<part name="result" type="xsd:string" /> </message>
      	<portType name="HelloIF">
      		<operation name="sayHello" parameterOrder="String_1 Integer_2">
      			<input message="tns:HelloIF_sayHello" />
      			<output message="tns:HelloIF_sayHelloResponse" />
      		</operation>
      	</portType>
      	<binding name="HelloIFBinding" type="tns:HelloIF">
      		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
      			style="rpc" />
      		<operation name="sayHello">
      			<input>
      				<soap:body use="literal" namespace="urn:Foo" />
      			</input>
      			<output>
      				<soap:body use="literal" namespace="urn:Foo" />
      			</output>
      			<soap:operation soapAction="" />
      		</operation>
      	</binding>
      	<service name="MyHelloService">
      		<port name="HelloIFPort" binding="tns:HelloIFBinding">
      			<soap:address xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      				location="http://localhost:8080/hello-jaxrpc/hello" />
      		</port>
      	</service>
      </definitions>
      

      This is the WSDL document for the helloservice Web service in which RPC style and Literal data format are used.
      As for the data format, the literal data format means that each part references to a schema definition, which could be a simple type such as xsd:string as it is the case for this example or a complex type.

      SOAP Request Message: RPC, Literal: This is actual SOAP message that reflects RPC style and literal data format.

      <?xml version="1.0" encoding="UTF-8"?>
      <soap:Envelope xmlns:n="urn:Foo"
      	xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 	xmlns:xs="http://www.w3.org/2001/XMLSchema"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      	<soap:Body>
      		<n:sayHello>
      			<String_1>MyRpcLiteralMessage</String_1>
      			<Integer_2>79</Integer_2>
      		</n:sayHello>
      	</soap:Body>
      </soap:Envelope>
      

      SOAP Response Message: RPC, Literal:

      <?xml version="1.0" encoding="UTF-8"?>
      <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
      	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 	xmlns:ns0="urn:Foo">
      	<env:Body>
      		<ns0:sayHelloResponse>
      			<result>Hello MyRpcLiteralMessage79</result>
      		</ns0:sayHelloResponse>
      	</env:Body>
      </env:Envelope> 
      

      SOAP:body for Document style: For document stype, each message has a single element. And the element attribute of the element defines schema definition of XML document fragment.

      WSDL document:

      ●	Each <message> has single <part> element
      ●	The element attribute of <part> refers to schema definition of XML document fragment, which is defined inside <types>
      

      SOAP message:
      ● SOAP Body element contains an XML document fragment (document)
      ● E.g.) Purchase order XML document fragment
      ● There are no wrappers

      Example: MyHelloServiceDocLiteral.wsdl

      <?xml version="1.0" encoding="UTF-8"?>
      <definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
      	xmlns:tns="urn:Foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="MyHelloService"
      	targetNamespace="urn:Foo">
      	<types>
      		<schema xmlns="http://www.w3.org/2001/XMLSchema" 
      			xmlns:soap11-enc="http://schemas.xmlsoap.org soap/encoding/" 			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"	targetNamespace="urn:Foo">
      			<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
      			<complexType name="sayHello">
      				<sequence>
      					<element name="String_1" type="string" nillable="true" />
      					<element name="Integer_2" type="int" nillable="true" />
      				</sequence>
      			</complexType>
      			<complexType name="sayHelloResponse">
      				<sequence>
      					<element name="result" type="string" nillable="true" />
      				</sequence>
      			</complexType>
      			<element name="sayHello" type="tns:sayHello" />
      			<element name="sayHelloResponse" type="tns:sayHelloResponse" />
      		</schema>
      	</types>
      	<message name="HelloIF_sayHello">
      		<part name="parameters" element="tns:sayHello" />
      	</message>
      	<message name="HelloIF_sayHelloResponse">
      		<part name="result" element="tns:sayHelloResponse" />
      	</message>
      </definitions>
      

      This is the WSDL document for the helloservice Web service in which Document style and Literal data format are used.

      Please note that there two complexType definitions, “sayHello” and “sayHelloResponse” within the types element. These two definitions will be used to reflect the XML document fragments, one in the request and the other in the response SOAP messages.

      SOAP Request Message: Doc, Literal: This is actual SOAP message that reflects document style and literal data format.
      Here the tns:sayHello element (along with its child elements) reflects a XML document fragment whose type is defined by the XML schema definitions.

      <?xml version="1.0" encoding="UTF-8"?>
      <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
      	xmlns:tns="urn:Foo" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      	<soap:Body>
      		<tns:sayHello>
      			<String_1>MyDocLiteralMessage</String_1>
      			<Integer_2>78</Integer_2>
      		</tns:sayHello>
      	</soap:Body>
      </soap:Envelope>
      

      SOAP Response Message: Doc, Literal:

      <?xml version="1.0" encoding="UTF-8"?>
      <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
      	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 	xmlns:ns0="urn:Foo">
      	<env:Body>
      		<ns0:sayHelloResponse>
      			<result>Hello MyDocLiteralMessage78</result>
      		</ns0:sayHelloResponse>
      	</env:Body>
      </env:Envelope>
      

      use attribute of soap:body: use=”literal|encoded”

      • literal
        – parts define the concrete schema of the message
        – XML document fragment can be validated against its XML schema
      • encoded
        – Indicates whether the message parts are encoded using some encoding rules
      • use=”literal”: Each part references a concrete schema definition using either the element or type attribute (WS-I profile says use element)

        • element attribute
          Document style: the element referenced by the part will appear directly under the Body element
          RPC style: the element referenced by the part will appear under an accessor element named after the message part.
        • type attribute: The type referenced by the part becomes the schema type of the enclosing element

        use=”encoded”: Each message part references an abstract type using the type attribute
        – abstract types are used to produce a concrete message by applying an encoding specified by the encodingStyle attribute.
        – part names, types and value of the namespace attribute are all inputs to the encoding.

        Possible Style/Use Combinations
        1. style=”rpc” and use=”encoded”
        2. style=”rpc” and use=” literal”
        3. style=”document” and use=”encoded”
        4. style=”document” and use=”literal”

        Example: SOAP Binding style=”rpc” use=”encoded” MyHelloServiceRpcEncoded.wsdl

        <?xml version="1.0" encoding="UTF-8"?>
        <definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
        	xmlns:tns="urn:Foo" 	xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
        	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        	name="MyHelloService" targetNamespace="urn:Foo">
        	<types />
        	<message name="HelloIF_sayHello">
        		<part name="String_1" type="xsd:string" />
        		<part name="Integer_2" type="ns2:int" />
        	</message>
        	<message name="HelloIF_sayHelloResponse">
        		<part name="result" type="xsd:string" />
        	</message>
        	<portType name="HelloIF">
        		<operation name="sayHello" parameterOrder="String_1 Integer_2">
        			<input message="tns:HelloIF_sayHello" />
        			<output message="tns:HelloIF_sayHelloResponse" />
        		</operation>
        	</portType>
        	<binding name="HelloIFBinding" type="tns:HelloIF">
        		<operation name="sayHello">
        			<input>
        				<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        					use="encoded" namespace="urn:Foo" />
        			</input>
        			<output>
        				<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        					use="encoded" namespace="urn:Foo" />
        			</output>
        			<soap:operation soapAction="" />
        		</operation>
        		<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
        	</binding>
        	<service name="MyHelloService">
        		<port name="HelloIFPort" binding="tns:HelloIFBinding">
        			<soap:address xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 			location="http://localhost:8080/hellojaxrpc/hello" />
        		</port>
        	</service>
        </definitions>
        

        SOAP Request Message: rpc, encoded:

        <?xml version="1.0" encoding="UTF-8"?>
        <soap:Envelope xmlns:n="urn:Foo"
        	xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/" 
        	xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
        	xmlns:xs="http://www.w3.org/2001/XMLSchema"
        	xmlns:xsi="http://www.w3.org/XMLSchema-instance">
        	<soap:Body 	soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        		<n:sayHello>
        			<String_1 xsi:type="xs:string">MyRpcEncodingMessage
        			</String_1>
        			<Integer_2 xsi:type="ns2 :int">77</Integer_2>
        		</n:sayHello>
        	</soap:Body>
        </soap:Envelope>
        

        SOAP Response Message: rpc, encoded:

        <?xml version="1.0" encoding="UTF-8"?>
        <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
        	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        	xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 
        	xmlns:ns0="urn:Foo"
        	env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        	<env:Body>
        		<ns0:sayHelloResponse>
        			<result xsi:type="xsd:string">Hello 										MyRpcEncodingMessage77</result>
        		</ns0:sayHelloResponse>
        	</env:Body>
        </env:Envelope>
        

        Example: SOAP Binding style=”document” use=”encoded”

        <?xml version="1.0" encoding="utf-8"?>
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        	xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
        	xmlns:tns="http://tempuri.org/" 	xmlns:types="http://tempuri.org/encodedTypes"
        	xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        	<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        		<types:HelloEncodedWorldResponse
        			xsi:type="types:HelloEncodedWorldResponse">
        			<HelloEncodedWorldResult href="#id1" />
        		</types:HelloEncodedWorldResponse>
        		<types:MethodDuration id="id1" xsi:type="types:MethodDuration">
        			<start xsi:type="xsd:dateTime">dateTime</start>
        			<end xsi:type="xsd:dateTime">dateTime</end>
        			<rVal xsi:type="xsd:string">string</rVal>
        		</types:MethodDuration>
        	</soap:Body>
        </soap:Envelope>
        

JAXB, Custom XML to Java Map using XMLAdapter

In some cases XML structure that is specific to a Java container is very different, e.g. Map. And we want to bind our Java classes with a customized and more readable XML, JAXB XmlJavaTypeAdapter annotation comes very handy in such situations. Such mappings require an adapter class, written as an extension of XmlAdapter, and XmlJavaTypeAdapter annotation suggests JAXB to use the adapter at specified location:

For illustration purpose, we’ll have a custom XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<profile>
	<messages>
		<message id="1">
			<subject>hi</subject>
			<body>wat's up mike.. r u gonna catch us tonight?</body>
		</message>
		<message id="2">
			<subject>re:hi</subject>
			<body>My apologies, forgot to tell ya, I'm out of town!!!</body>
		</message>
	</messages>
</profile>

And this is our JAXB annotated message class(minimal):


public class Message {
	@XmlAttribute
	private String id;
	@XmlElement
	private String subject;
	@XmlElement
	private String body;
}

And the profile class with required annotations, note that we have a HashMap of Message where message id is the key and Message object itself as a value. Also note the use of @XmlJavaTypeAdapter which provides mapping between custom XML and HashMap during the process of marshaling/ unmarshaling. Going forward we’ll see how we are going to achieve that.

@XmlRootElement(name="profile")
public class Profile {
    @XmlElement
    @XmlJavaTypeAdapter(MessageAdapter.class)
    private HashMap<String, Message> messages;
    
    public Profile(){}
    public Profile(HashMap<String, Message> b ){
    	messages = b;
    }
}

To fill the gap we need to provide something that JAXB knows how to handle, we can use a wrapper class which contains Array of objects of type Messagse.

public class Messages {
    @XmlElement(name="message")
    public Message[] messages;
}

Now you must have got a fair idea that how JAXB is going to read XML messages to Message array back and forth. Let’s write an adapter to map our Array to a HasMap.

public class MessageAdapter extends XmlAdapter<Messages,Map<String, Message>> {
    @Override
    public Map<String, Message> unmarshal( Messages value ){
    	Map<String, Message> map = new HashMap<String, Message>();
        for( Message msg : value.messages )
            map.put( msg.getId(), msg );
        return map;
    }  

    @Override
    public Messages marshal( Map<String, Message> map ){
        Messages msgCont = new Messages();
        Collection<Message> msgs = map.values();
        msgCont.messages = msgs.toArray(new Message[msgs.size()]);
        return msgCont;
    }
}

And here is the test class to assert our assumptions:

public class XmlAdapterTest extends TestCase{
	
	public void testAdapter() throws Exception {
		InputStream is = this.getClass().getClassLoader().getResourceAsStream("profile.xml");
		if (is != null) {
			JAXBContext jc;
			try {
				//test unmarshaling
				jc = JAXBContext.newInstance(Profile.class.getPackage().getName());
				Unmarshaller u = jc.createUnmarshaller();
				Profile profile = (Profile) u.unmarshal(is);
				assertNotNull(profile.getMessages());
				assertEquals( 2, profile.getMessages().size());
				
				//test marshaling
				Marshaller marshaller=jc.createMarshaller();
				File xmlDocument = new File("output.xml");
				marshaller.marshal(profile, new FileOutputStream(xmlDocument));
				assertTrue(xmlDocument.length() > 0);
				xmlDocument.delete();
			} catch (JAXBException e) {
				e.printStackTrace();
				fail();
			}
		}
	}
}

Still need the source code, find here: jaxb-typeadapter source, Sushant

Apache CXF to create rest web service

I’m here to demonstrate the steps involved to create RESTful Service using Apache CXF, JAX-RS and Spring build tool that I’m going to use is Maven:

1. Start with a java web application, Maven’s mvn archetype:generate and choosing the simple webapp archetype. If you’re new to maven please refer to getting-started-with-maven.

2. Now, since I’ll be using Spring and CXF, let’s start and add the dependencies:

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
			<version>2.2.12</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>

3. Don’t forget to alter the compiler plugin, as we’ll be using Java 6 features:

	<plugin>
	    <groupId>org.apache.maven.plugins</groupId>
	    <artifactId>maven-compiler-plugin</artifactId>
	    <configuration>
	        <source>1.6</source>
	        <target>1.6</target>
	    </configuration>
	</plugin>

4. Now that we have the api we need, we now need a service to expose. Following is the interface for the service:

public interface UserService {
	
	    public UserCollection getUsers();

	    public User getUser(Integer id);
   
	    public void newUser(Integer id, String name) throws IOException;
}

5. Since, we are using JAX-RS spec to expose REST services; here I’ll add some more annotations to the service interface:

@Path("/user-service/")
@Produces("application/xml")
public interface UserService {
	
	    @GET
	    @Path("/users")
	    public UserCollection getUsers();

	    @GET
	    @Path("/user/{id}")
	    public User getUser(@PathParam("id") Integer id);
   
	    @POST
	    @Path("/new")
		@Produces(MediaType.TEXT_HTML)
		@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
		public void newUser(
				@FormParam("id") Integer id,
				@FormParam("name") String name,
				@Context HttpServletResponse servletResponse
		) throws IOException;
	}

6. Now we only need to do some Spring configurations. First, we’ll Spring-enable the web context

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/appContext.xml</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
        </listener-class>
</listener>

7. And add the CXF servlet for handling the REST calls:

<servlet>
	<servlet-name>CXFServlet</servlet-name>
	<servlet-class>
		org.apache.cxf.transport.servlet.CXFServlet
	</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>CXFServlet</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>

8. The only thing left to do is the Spring configuration. CXF needs 3 of its own Spring configuration files, so we’ll need to import those.

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://cxf.apache.org/jaxrs
		http://cxf.apache.org/schemas/jaxrs.xsd"
	default-lazy-init="false">
	<!-- do not use import statements if CXFServlet init parameters link to 
		this beans.xml -->

	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<jaxrs:server id="userService" address="/">
		<jaxrs:serviceBeans>
			<ref bean="userServiceImpl" />
		</jaxrs:serviceBeans>
		<jaxrs:extensionMappings>
			<entry key="xml" value="application/xml" />
			<entry key="json" value="application/json" />
		</jaxrs:extensionMappings>
	</jaxrs:server>
	<bean id="userServiceImpl" class="service.impl.UserServiceImpl" />
</beans>

Finally, to run the service, use the tomcat plugin to quickly startup a Tomcat container:

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>tomcat-maven-plugin</artifactId>
	<version>1.0</version>
	<executions>
		<execution>
			<phase>pre-integration-test</phase>
			<goals>
				<goal>run-war</goal>
			</goals>
			<configuration>
				<port>8080</port>
				<path>/cxf-rest</path>
				<warFile>
					${project.basedir}/target/${project.build.finalName}.war
    			</warFile>
				<fork>true</fork>
			</configuration>
		</execution>
	</executions>
</plugin>

Now use, mvn tomcat:run-war to start the tomcat and have a look at your web service.

ANNEXTURE: JAX-RS Annotation quick reference-

Bean Annotation and parameters
@Path annotation is applied to resource classes or methods. The value of @Path annotation is a relative URI path and follows the URI Template format and may include arbitrary regular expressions. When not available on the resource method, it’s inherited from a class.
HTTP Method: JAX-RS specification defines a number of annotations such as @GET, @PUT, @POST and @DELETE. Using an @HttpMethod designator, one can create a custom annotation such as @Update or @Patch for e.g.

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH {
}

@PathParam annotation is used to map a given Path template variable to a method parameter. For example:

@Path("/user/{id}")
	public User getUser(@PathParam("id") Integer id);

@QueryParam annotation is used to extract URI query parameter from the HTTP request. @QueryParam allows you to inject URL query parameters into any primitive type as well as any class that either has a public static valueOf(String) method or a constructor that takes one parameter of type String.

@Path("/users")
public UserCollection getUers(@QueryParam("size") 
@DefaultValue("50") int size){
   	}

@HttpHeader, @MatrixParam, @FormParam and @CookieParam annotations are also supported.

Media types: Consider this resource class with 2 resource methods:

@Path("/")
public class Test1 {

 @Path("/adduser")
 @POST 
 @Consumes({"application/json", "application/xml"})
 @Produces({"application/json", "application/xml"})
 public User addUser(UserDetails details) {...}
}

For this specific example, in both cases either JAXB or JSON message body readers and writers will be selected to deserialize the input stream into UserDetails and serialize User into the output stream. Message body providers can have @Produces and @Consumes set too, and they have to match those on a chosen resource method.

Source Code: cxf-rest, Sushant

Resources:
1. http://cxf.apache.org/docs/jax-rs.html
2. ReSTful concepts
3. Getting Started with maven

ReSTful web service concepts

REST is an architecture style for designing networked applications. It relies on a stateless, client-server, cacheable communications protocol — and in virtually all cases, the HTTP protocol is used.
REST web services architecture conforms to the W3C’s Web Architecture, and leverages the architectural principles of the Web, building its strength on the proven infrastructure of the Web. It utilizes the semantics of HTTP whenever possible and most of the principles, constraints, and best practices published by W3C’s Technical Architecture Group (TAG) also apply.
The REST web services architecture is related to the Service Oriented Architecture. This limits the interface to HTTP with the four well-defined verbs: GET, POST, PUT, and DELETE. REST web services also tend to use XML as the main messaging format.
Implementing REST correctly requires a resource-oriented view of the world instead of the object-oriented views many developers are familiar with. A resource is an abstract thing identified by a URI.

REST principles

1. Addressable Resources: Every “thing” on your network should have an ID. With REST over HTTP, every object will have its own specific URI.
2. A Uniform, Constrained Interface: When applying REST over HTTP, stick to the methods provided by the protocol. This means following the meaning of GET, POST, PUT, and DELETE religiously.
3. Representation oriented: You interact with services using representations of that service. An object referenced by one URI can have different formats available. Different platforms need different formats. AJAX may need JSON. A Java application may need XML.
4. Communicate statelessly: Stateless applications are easier to scale.

REST development guidelines

URI Opacity:
The creator of a URI decides the encoding of the URI, and users should not derive metadata from the URI itself. URI opacity only applies to the path of a URI. The query string and fragment have special meaning that can be understood by users. There must be a shared vocabulary between a service and its consumers.

Query String Extensibility:
A service provider should ignore any query parameters it does not understand during processing. If it needs to consume other services, it should pass all ignored parameters along. This practice allows new functionality to be added without breaking existing services.

Deliver Correct Resource Representation:
A resource may have more than one representation. There are four frequently used ways of delivering the correct resource representation to consumers:
1. Server-driven negotiation: The service provider determines the right representation from prior knowledge of its clients or uses the information provided in HTTP headers like Accept, Accept-Charset, Accept-Encoding, Accept-Language, and User-Agent. The drawback of this approach is that the server may not have the best knowledge about what a client really wants.
2. Client-driven negotiation: A client initiates a request to a server. The server returns a list of available of representations. The client then selects the representation it wants and sends a second request to the server. The drawback is that a client needs to send two requests.

3. Proxy-driven negotiation: A client initiates a request to a server through a proxy. The proxy passes the request to the server and obtains a list of representations. The proxy selects one representation according to preferences set by the client and returns the representation back to the client.
4. URI-specified representation: A client specifies the representation it wants in the URI query string.

Asynchronous Services
It is actually quite easy to implement an asynchronous REST service. An asynchronous service needs to perform the following:
1. Return a receipt immediately upon receiving a request.
2. Validate the request.
3. If the request if valid, the service must act on the request as soon as possible. It must report an error if the service cannot process the request after a period of time defined in the service contract.

Request receipt

Transaction Lifecycle and Status URI

The status resource can be seen as a different view of its associated transaction resource. The status URI should only differ in the query string with an additional status parameter. For example:

Transaction URI: http://www.example.com/abc123
Transaction Status URI: http://www.example.com/abc123?view=status

A transaction request submitted to a service will experience the following lifecycle as defined in Web Service Management: Service Life Cycle
The state diagram of a request (taken from Web Service Management: Service Life Cycle)

As an example of the status XML, when a request is just received:

<status state=”received” timestamp=”2009-12-03T12:34:33+5:30″ />

The XML contains a state attribute, which indicates the current state of the request. Other possible values of the state attribute are processing, processed, and failed. When a request is processed:

<status state=”processed” timestamp=”2009-12-03T12:34:33+5:30″ >
<result uri=”http://example.com/rest/123/abc&#8221; />
</status>

Receiving and Sending XML
When receiving and sending XML, one should follow the principle of strict out and loose in. When sending XML, one must ensure it is validated against the relevant schema. When receiving an XML document, one should only validate the XML against the smallest set of schema that is really needed. Any software agent must not change XML it does not understand.

Exception handling and propagation
To deal with exceptions, JAX-RS provides the WebApplicationException, which extends the Java RuntimeException class. The WebApplicationException can take an HTTP status code or javax.ws.rs.core.Response object as part of the constructor. The Response object can be used to set the entity information providing a user readable error message along with the HTTP status code.
Typically, exception handling for RESTful service would fall into one of the following categories:

1. The implementation class can throw an unchecked WebApplicationException with the required HTTP Error code. The HTTP specification defines which HTTP response code should be used for unsuccessful requests, which can be interpreted by clients in a standard way. For example, Status code 4xx defines client error, such as Bad request, and 5xx defines the server request where server failed to fulfill a valid request.

2. The implementation class can create a javax.ws.rs.core.Response object and send a custom error message to the client or send the required HTTP status code in the response.

3. The implementation class can throw a checked exception and you can wire an ExceptionResolver implementation to convert the application exception to the Response object. The ExceptionResolver interface provides a contract for a provider that maps Java exception to a Response. For instance, if you are fetching information from the database, and a record does not exist, and your application throws a RecordNotFound exception, then you can map this exception to a Response object using your ExceptionResolver implementation. The Response object can be populated with a custom error message and sent back to the client, as mentioned in the second approach.

Let’s sum up with the resources for further reading:
1. http://rest.elkstein.org
2. http://www.xml.com/lpt/a/1459
3. http://www.infoq.com/articles/rest-anti-patterns