Skip to main content

skip to main content

developerWorks  >  SOA and Web services  >

Deploying Web services with WSDL, Part 2: Simple Object Access Protocol (SOAP)

Learn SOAP syntax and deploy WSDL applications using SOAP

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

Bilal Siddiqui (wap_monster@yahoo.com), CEO, WAP Monster

01 Mar 2002

Simple Object Access Protocol (SOAP) provides access to remote objects. Examples of such objects are simple or Enterprise JavaBeans components and COM/COM+ objects, etc. These objects reside inside different enterprises and may exist anywhere on the Internet. Therefore, SOAP communication works across the Internet and is a mechanism to exchange information between different enterprises. In this article, Bial will discuss details of SOAP communications, how objects expose their functionality using SOAP, how to invoke SOAP objects and how to exchange information between SOAP-aware applications. He'll also demonstrate the deployment of SOAP services for the WSDL application of Part 1, and its invocation by a remote server.

SOAP and WSDL

I described WSDL in Part 1 of this series of articles. WSDL describes the interface of Web services. Web service owners will implement their interfaces using SOAP. Therefore WSDL services will actually exist as SOAP services. Once the Web service user has the WSDL file, he or she knows the interface details. He or she will now use SOAP to communicate with the Web services.

Think of Web services as objects that you can expose through WSDL interfaces and access remotely across the Internet using SOAP. Since services are objects, there must be some properties related to each service and behaviors for invocation of each service. SOAP messages are XML documents that may work over HTTP.

Why use SOAP?

Business-to-business (B2B) and application-to-application (A2A) requirements dictate that enterprises communicate with each other in order to exchange information. This concept is used in B2B, workflow, and across the enterprise integration. For example, consider a vertical supply chain where an enterprise will need to invoke the services of its suppliers in order to fulfill the requirements of its customers. Some suppliers will need to go further down the supply chain and invoke services of other enterprises.

It is evident that interoperability is of paramount importance in such applications. Any single enterprise will implement only one end of the SOAP communication channel. The other end will be somebody from anywhere on the Internet.

Integration and interoperability between enterprises has been a challenging task for both software engineers and enterprises in last few years. Platform dependency was also a big problem in achieving integration and interoperability. SOAP is the simplest mechanism yet to achieve integration and interoperability between enterprises.



Back to top


SOAP architecture

With a basic understanding of SOAP and its purpose, I will now extend the discussion toward its architecture to help you learn the inside story. Refer to Figure 1 where you can identify the following components of a typical SOAP communications architecture:

  1. SOAP client
  2. SOAP server
  3. actual service


Figure 1. Components of a typical SOAP communication architecture
Components of a typical SOAP communication architecture

Let me try to explain the architectural role of each of above mentioned entities.
The following discussion refers to Figure 1.

The SOAP client

The SOAP client is a SOAP-aware machine and is capable of generating and sending SOAP requests to a SOAP server over HTTP. A SOAP request is a type of SOAP message; normally there are only two types of SOAP messages: a SOAP request is what a SOAP client sends to a SOAP server and a SOAP response is what a SOAP server sends to a SOAP client in response. Listing 1 is typical SOAP request, see Listing 2 to review a SOAP response.

<SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
   <SOAP-ENV:Body>
	<m:getListOfModels xmlns:m = "uri reference" >
	</m:getListOfModels>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The SOAP server

The SOAP server is also a SOAP-aware machine and has the capability to accept requests from SOAP clients and author appropriate responses. These encoded responses go back to the requesting SOAP client. Inside the SOAP server there are three entities:

  1. service manager
  2. deployed services list
  3. XML translator

The service manager is responsible for managing services against requests. Refer to the SOAP request from Listing 1, where the element <m:getListOfModels xmlns:m="urn:MobilePhoneservice" > contains the name of the service. The service manager will read name of the SOAP service that the SOAP client wants to invoke and check whether the required service actually resides on this SOAP server. To that end, it will consult the deployed services list, a list of all services that the SOAP server hosts. If yes, the server manager will pass on the SOAP request to the XML translator. The XML translator is then responsible for converting the XML structure of the SOAP request to that of a programming language (for example, Java programming language) that programmers used to implement the actual service. It is also responsible for converting the response from the actual service back to the XML Structure of the SOAP response. Refer to Listing 2 for an illustration of the SOAP response.

<SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Body>
	<m:getListOfModelsResponse xmlns:m="urn:MobilePhoneservice">
		<Model>M1</Model>
		<Model>M2</Model>
		<Model>M3</Model>
	</m:getListOfModelsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The actual service

The box labeled actual service in Figure 1 is the location where actual service resides. The service implementation may be in the form of COM components or JavaBeans components, for example. The XML translator is responsible for translating XML structures into proper method invocation calls. When the XML translator invokes some method of actual service implementation, the method will perform its job and return the resulting information back to the XML translator.

Have a look at the arrow in Figure 1, which connects XML translator to the actual service. Both ends of this arrow are within the same enterprise, which means the same organization has the control over interfaces at both ends of communication. Compare this to arrow between SOAP client and SOAP server, which crosses the boundary of an enterprise. This is exactly the purpose of SOAP.



Back to top


SOAP request response mechanism

When SOAP client sends SOAP message to a SOAP server it uses HTTP protocol for transportation. This is called SOAP Binding with HTTP. When SOAP server receives the message, it hands it over to service manager. It checks the deployed services list for the required service in SOAP message. If it cannot locate the requested service, it responds back to SOAP client with request failure. But if the service is available, control is transferred from service manager to XML translator, which performs appropriate language conversion and accesses the actual service implementation. Service Implementation will process the request and sends results back to XML translator. XML translator converts it to SOAP response (XML Document) that is understandable by SOAP client. Again HTTP binding is used for transportation of SOAP response.
It is time to look at SOAP binding with HTTP in detail.



Back to top


SOAP binding with HTTP

When you bind SOAP with HTTP or operate SOAP over HTTP, you actually add HTTP headers to the SOAP requests and responses. Listing 1 is the structure of a typical SOAP request, while Listings 3, 4, 5 and 6 are complete HTTP requests to demonstrate the addition of HTTP headers to Listing 1. Similarly, Listing 7 is a complete HTTP response corresponding to the SOAP response from Listing 2.

Whenever you use SOAP over HTTP, Content-Type field must be text/xml. You'll now see the details of Listing 3 through Listing 7.

A SOAP request using HTTP

You can use SOAP in combination with the HTTP request method POST. In order to send a SOAP HTTP request, you need to supply a SOAPAction header field in HTTP.
SOAPAction specifies the intent of SOAP request. Servers (such as firewalls that filter SOAP request messages in HTTP) can use the value of the SOAPAction to make decisions.

HTTP client must use this header field when issuing a SOAP HTTP request. SOAPAction can have one of the following values: SOAPAction: "URI-Reference"
SOAPAction: "filename"
SOAPAction: ""
SOAPAction:

POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPACtion:"www.mobilephoneservice.com/Vendors/MobilePhoneservice#getListOfModels"

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  >
	<SOAP-ENV:Body>
		<m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
		</m:getListOfModels>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Listing 3 contains following URI Reference in SOAPAction: www.mobilephoneservice.com/Vendors/MobilePhoneservice#getListOfModels

This SOAPAction represents two things. First is the address of a particular SOAP deployment: www.mobilephoneservice.com/Vendors/MobilePhoneservice

Second is a fragment identifier that gives the name of the method of our interest ( #getListOfModels ).

POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPAction:"MobilePhoneservice#getListOfModels"

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  >
	<SOAP-ENV:Body>
		<m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
		</m:getListOfModels>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Listing 4 contains a filename ( MobilePhoneservice#getListOfModels ) in SOAPAction. The MobilePhoneservice file must be present at the host URI ( www.mobilephoneservice.com/Vendors ). This host URI is a combination of the host field in the HTTP header ( www.mobilephoneservice.com ) and the folder name, /Vendors .

POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPAction:""

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  >
	<SOAP-ENV:Body>
		<m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
		</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Listing 5 contains an empty string ("") in the SOAPAction. The empty string value represents that intent of SOAP is the same as Host URI (www.mobilephoneservice.com/Vendors).

POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPAction:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  >
	<SOAP-ENV:Body>
		<m:getListOfModels xmlns:m ="urn:MobilePhoneservice" >
		</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Listing 6 contains no value for SOAPAction. This indicates that there is no information about the intent of the message.

SOAP response using HTTP

There can be one of the two possible types of SOAP responses:

  • A successful SOAP operation producing SOAP results
  • An unsuccessful SOAP operation resulting in a SOAP fault message

HTTP/1.1 Content-Type:"text/xml"; Charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
	<m:getListOfModelsResponse xmlns:m = "URI-Reference">
		<model>m1</model>
		<model>m2</model>
	</m:getListOfModels>
</SOAP-ENV:Body>

Listing 7 is the first case where you get a meaningful result from the SOAP server.

Listing 8 is a typical SOAP fault message. SOAP HTTP responses follow the semantics of the HTTP status codes for communicating status information in HTTP. In the case of a SOAP error while processing a request, the SOAP HTTP server must issue an HTTP 500 "Internal Server Error" response including a SOAP message in the response with the SOAP fault element.

HTTP/1.1 500 Internal Server Error
Content-Type: "text/xml"; Charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
	<SOAP-ENV:Body>
		<SOAP-ENV:Fault> 
		<faultstring>Failed to process the request</faultstring>
		</SOAP-ENV:Fault>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Back to top


SOAP with e-mails

HTTP is not the only solution for binding SOAP messages. You can use other mechanisms like SMTP for SOAP binding where HTTP is not suitable. Binding SOAP to SMTP, you can establish a one-way transport route. Two one-way messages can be used to establish request/response communications. To send a SOAP message with SMTP, you will need to perform the following steps:

  • Use of the MIME-Version header field
    The MIME-Version uses a version number to differentiate between different MIME versions. It allows mail-processing agents (such as a POP server) to distinguish between mail messages that are generated by older versions and new versions. Refer to Listing 9 which uses a MIME-Version header field.
    TO: <info@waxsys.com>
    From: <abc@punjab.com>
    Reply-To: <abc@punjab.com>
    Date: SAT, 2 Feb 2002 16:00:00 
    Message-Id: <4FAB345C8D93E93B7A6E9@punjab.com>
    MIME-Version: 1.0
    Content-Type: text/xml; charset=utf-8
    Content-Transfer-Encoding: QUOTED-PRINTABLE
    
    <?xml version ="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    	<SOAP-ENV:Body>
    		<prnt:echoString xmlns:prnt="http://waxsys.com">
    			<msgString>Put your mail Message</msgString>
    		</prnt:echoString>
    	</SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

  • Use of the Content-Type header field:
    The Content-Type is used to identify the type of data in the message body. In case of SOAP message Content-Type should have a value "text/xml". Refer to Listing 9 , which uses Content-Type.
  • Use of Content-Transfer-Encoding field:
    Content-Transfer-Encoding is used to specify the type of transfer encoding, that is, whether data that you want to transfer is in character or binary format. Listing 9 uses Quoted-Printable encoding that corresponds to printable characters according to the ASCII character set. It encodes the data in such a way that the mail transport agent is unlikely to modify the resulting octets. Refer to Listing 9, which uses Content-Transfer-Encoding.


Back to top


SOAP Schema and authoring

SOAP message

A SOAP message is nothing but an XML document that consists of a mandatory SOAP Envelope having an optional SOAP Header and a mandatory SOAP Body.

Elements of a SOAP Schema:

  • Envelope
  • Header
  • Body
  • Fault

Envelope:
The Envelope is the top element that represents a SOAP message. This element must be present in order to send SOAP message. The Envelope uses SOAP namespace identifier http://schemas.xmlsoap.org/soap/envelope/ that is essential. If the Envelope contains the wrong namespace, an error will be generated regarding the version of Envelope namespace. Listing 10 is an empty Envelope. You call it an "empty envelope" to emphasize that it should eventually contain a "letter" (perhaps a business letter) before you can send it by "post". The "letter" in SOAP schema is referred to as a "SOAP Body" and HTTP POST (as discussed in the section on HTTP binding with SOAP) is the transport mechanism.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

</SOAP-ENV:Envelope>

Header:
The SOAP Header is optional. You can directly wrap a SOAP Body inside a SOAP Envelope and skip the header altogether. Headers provide a mechanism to extend functionality of SOAP message. For example, authentication is a typical extension provided with SOAP Header entries. In this case there will be an authentication framework, which will use SOAP as a lower level transport. Refer to Listing 11 to see header implementation in SOAP.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
	<m:Order xmlns:m="some URI" SOAP-ENV:mustUnderstand="1">
	</m:Order>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>

Body:
The Body element will contain the actual message that you want to send. It is a mandatory element and its child elements normally belong to a user-defined namespace. Listing 12 shows a SOAP message that refers to a user-defined namespace "u". The Body element is a container for mandatory information. This element must be present in the SOAP message and must be an immediate child element of the SOAP Envelope element. It must follow the SOAP header element directly. If the Header element is not present then it should follow the Envelope element directly. The body may contain child elements and they may be namespace-qualified.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
	<m:Order xmlns:m="some URI" SOAP-ENV:mustUnderstand="1">
	</m:Order>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
	<u:GetPrice xmlns:u="some URI" >
		<model>m1</model>
	</u:GetPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Fault:
This element indicates an error message. It should appear as a body entry and must not appear more than once within a Body element. Normally, the Fault element will appear in a SOAP response message to indicate that there was something wrong with the SOAP request.

Sub elements of Fault:

  • faultcode (identification of fault)
  • faultstring (description of fault)
  • faultactor (identifies who caused this fault)
  • detail (detail of the error. It is normally an application specific error, that is, it corresponds to user-defined namespace that was used in the body of a SOAP request)

Listing 13 is a typical fault message.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<m:Order xmlns:m="some URI" SOAP-ENV:mustUnderstand="1">
</m:Order>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Not necessary information</faultstring>
<detail>
	<d:faultdetail xmlns:d = "uri-referrence">
		<msg>
			application is not responding properly.
		</msg>
		<errorcode>12</errorcode>
	</d:faultdetail>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Back to top


A SOAP request for the WSDL file from Part 1

Having explained the general syntax of a SOAP message (request and response), I'll show how to develop a SOAP request for your MobilePhoneservice of Part 1 of this series of articles. You designed a complete WSDL interface explaining MobilPhoneservice in Part 1. Mobile Company offers two methods in MobilePhoneservice, one is getListOfModels() and the other is getPrice(modelNumber). GetListOfModels() takes no parameter but returns a list of Mobile models while getPrice(modelNumber) takes a parameter modelNumber and returns price of requested model. You'll document it in the form of a SOAP request but first I'll show you the generic form of SOAP request and response.

<SOAP-ENV:Envelope xmlns:SOAP-ENV ="SOAP schema's URI"
<SOAP-ENV:Body>
	<Instance:"Method Name" xmlns:Instance= "URI where method is located">
		<parameter1>value</parameter1>
		<parametern>value</parametern>
	</Instance:"Method Name">
</SOAP_Envelop:Body>
</SOAP-ENV:Envelope>

A single SOAP request or response can only specify one method of a service. The generic form of your envelope containing a SOAP request takes the form of Listing 14. Compare this generic form to the getListOfModels() method invocation request in Listing 16. In Listing 16, I have provided names for the method and URI. As there were no parameters required with getListOfModels() , so <m:getListOfModels> is an empty element in Listing 16.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
	<Instance:"Method Name"+"Response" 
	xmlns:Instance="URI where method is located">
	<return>
		<responseparameter1>value</responseparameter1>
		<responseparametern>value</responseparametern>
	</return>
	</Instance: "Method Name"+"Response">
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Listing 15 is a generic SOAP response. The Apache SOAP server adds the "Response" keyword at the end of a method name and encloses the return value in the <return> element as an immediate child method element. If the return value is a complex structure then the <return> element contains one or more <item> elements. Compare Listing 15 with Listing 17, which is the actual response from the getListOfModels() method. Listing 17 contains a list of items as a Vector data type, which is the return parameter. Similarly Listings 18 and 19 shows SOAP request and response against getPrice() method of MobilePhoneservice.

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
	<m:getListOfModels xmlns:m = "www.mobilphoneservice.com" >
	</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope 
	xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
	<ns1:getListOfModelsResponse xmlns:ns1="urn:MobilePhoneservice" 
	SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
	<return xmlns:ns2="http://xml.apache.org/xml-soap" 
		xsi:type="ns2:Vector">
		<item xsi:type="xsd:string">M1</item>
		<item xsi:type="xsd:string">M2</item>
		<item xsi:type="xsd:string">M3</item>
		<item xsi:type="xsd:string">M4</item>
		<item xsi:type="xsd:string">M5</item>
	</return>
	</ns1:getListOfModelsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<SOAP-ENV:Envelope 
	xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
	<m:getPrice xmlns:m ="www.mobilphoneservice.com">
		<modelNumber xsi:type ="xsd:String">M1</modelNumber>
	</m:getPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope 
	xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
	xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
	<ns1:getPriceResponse xmlns:ns1="urn:MobilePhoneservice" 
		SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
			<return xsi:type="xsd:string"> 5000 </return>
	</ns1:getPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Back to top


Deployment of WSDL-based services on a SOAP server

In this section you will deploy the WSDL service from Part 1 on an Apache SOAP server. The Apache SOAP toolkit keeps the WSDL service information in a deployment descriptor file. The deployment descriptor contains names of the WSDL service and all methods that it contains. The deployment descriptor will provide these names to SOAP server at runtime. The same deployment descriptor file also contains the address of the JavaBean component that implements the interface.

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
	id="URN:SERVICE-URN">
<isd:provider type="java" 
	scope="Request" 
	methods="EXPOSED-METHODS">
	<isd:java class="IMPLEMENTING-CLASS"/> 
</isd:provider>
<isd:faultListener>org.apache.soap.server.DOMFaultListener
</isd:faultListener>
</isd:service>

Listing 20 is a skeleton deployment descriptor which needs three bits of information (URN:SERVICE-URN, EXPOSED-METHODS and IMPLEMENTING-CLASS) in order to be used as a WSDL-based service deployment descriptor. URN:SERVICE-URN is the name of the service deployed. In this case it will be "urn:MobilePhoneservice". EXPOSED-METHODS is a single-space separated list of methods offered by the service. In this deployment it will be getListOfModels getPrice.

IMPLEMENTING-CLASS is the name of a Java class with a complete path. For example, samples.phonequote.MobilePhoneservice. In this case while testing this application you had the following directory structure:
Apache SOAP server: C:\foo\SOAP-2_2
Mobile phone service implementation:
C:\foo\SOAP-2_2\samples\phonequote\MobilePhoneservice

So the IMPLEMENTING-CLASS path refers to the directory where you installed SOAP toolkit. I have not provided the actual implementation of the Java classes. It depends on the business logic and can be anything.

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:MobilePhoneservice">
<isd:provider type="java"
	scope="Request"
	methods="getListOfModels getPrice">
	<isd:java class="samples.phonequote.MobilePhoneservice"/>
</isd:provider>
<isd:faultListener>
	org.apache.soap.server.DOMFaultListener
</isd:faultListener>
</isd:service>

Listing 21 is the completed deployment descriptor for the WSDL file from Part 1.



Back to top


A SOAP client communicating with a SOAP server

I have provided a sample application to demonstrate the communication of a SOAP client with a SOAP server. For this purpose I have given three listings: Startup.html (Listing 22), Operation.html (Listing 23), and Execute.jsp (Listing 24).

StartUp.html (Listing 22) is a simple HTML file that presents a GUI to the user and asks which SOAP method he or she wants to invoke. The user will select a method of his choice.

<HTML>
<BODY bgcolor="Teal">
<br/>
<p align="center">
	<font size="5" face="Arial" color="white"><b> 
	SOAP method invocation demo </b></font>
</p>
<hr/>
<font face="Arial" color="whitesmoke" size="3">
<br/><b>
	Click any of the method name to execute.<br/>
	1. Get the List of all Models that we manufacture.... 
		<a href="execute.jsp?index=1"> 
		<font color="orange"> GetListOfModels </font></a> <br/>
	2. Get the Price of any particular model......................
		<a href="operation.html"> 
		<font color="orange"> GetPrice </font></a>
</b>
</BODY>
</HTML>

Operation.html (Listing 23)will ask the user to provide parameters that go with the method invocation call.

<HTML>
<BODY bgcolor="Teal">
<br/>
<p align="center"> 
<font size="5" face="Arial" color="white"><b>
	GetPrice Operation input Form </b>
</font></p>
<hr/>
<p align="center"> 
<form action="execute.jsp" method="POST">
<input type="hidden" name="index" value="0">
<table textColor="white">
<tr><td>
<font color="whitesmoke"><b>Description :</b></font>
</td><td><font color="whitesmoke">
	Method GetPrice is used to Get Price of given Model Number</font>
</td></tr>
<tr><td>
<font color="whitesmoke"><b>Parameter(s)</b></font></td><td>
</td></tr>
<tr><td><font color="whitesmoke">Model Number </td></font>
<td><font color="whitesmoke">
	<input type="text" name="parameter" size="30"> 
	(required) </font>
</td></tr>
<tr><td>
	</td><td><input type="Submit" value="Invoke">
</td></tr>
</font>
</table>
</form>
</p>
</BODY>
</HTML>

Execute.jsp (Listing 24)contains all the interesting code. It detects which method was called and which parameters are passed. It will then send a method invocation call to the remote server.

<%@ page language="java" import="java.util.Vector" %>
<%@ page import="java.net.MalformedURLException, java.net.URL" %>
<%@ page import="java.util.Vector" %>
<%@ page import="org.apache.soap.SOAPException, 
		org.apache.soap.Constants" %>
<%@ page import="org.apache.soap.rpc.Call, org.apache.soap.rpc.Response, 
		org.apache.soap.rpc.Parameter" %>
<%@ page import="org.apache.soap.transport.http.SOAPHTTPConnection" %>
<%@ page import="org.apache.soap.Fault" %>

<HTML>
<BODY bgcolor="Teal">
<br/>
<p align="center">
<font color="whitesmoke">
<% 
	boolean isParameter = false ;
	SOAPHTTPConnection soapTransport = new SOAPHTTPConnection();

	// Address of the remote server. 
	// Normally this should be dynamically passed and detected.
	// We have hard coded it only for demonstration.
	URL url = new URL ("http://localhost:8080/soap/servlet/rpcrouter");

	// Build the call.
	Call call = new Call ();
	call.setTargetObjectURI ("urn:MobilePhoneservice");
	call.setSOAPTransport (soapTransport);
	call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);

	// We'll detect which method user selected
	// and give a call accordingly.
	// We'll pass parameters if present.

	if (request.getParameter("parameter")!=null)
	isParameter = true;

	if (request.getParameter("index").equals("0")) 
	{
		call.setMethodName("getPrice");
		Vector params = new Vector();
		String message = new String (request.getParameter("parameter"));
		params.addElement (new Parameter("message", String.class, 
		message , null));
		call.setParams(params);
	}
	else
		call.setMethodName("getListOfModels");

	Response resp = call.invoke ( url, /* actionURI */ "" );
	out.println("<p align=left> 
	<font size=\"4\" face=\"Arial\" color=\"white\">
	Response of [ "+call.getMethodName()+" ]
	</font><hr/>");
	
	// Check the response.
	if (resp.generatedFault ()) {
		Fault fault = resp.getFault ();
		out.println("<b>Fault is:</b>"+ fault.getFaultCode ()
		+" ["+fault.getFaultString ()+"]");

	} else {
		Parameter result = resp.getReturnValue ();
		out.println("<b>Response is: </b>"+ result.getValue ()+"");
	}
%>
<font>
</p>
</BODY>
</HTML>

In order to run this application, you will need two Apache SOAP servers. One of the servers will talk to the user and hosts Listings 22, 23 and 24. The other server (also called the remote server) is the place where we will need to deploy your WSDL-based service from Part 1 (described in a previous section, "Deployment of WSDL-based services on a SOAP server"). You have hard-coded the address of the remote server, http://localhost:8080/soap/servlet/rpcrouter, in Execute.jsp (Listing 24) only for demonstration. In practise you will read it from the WSDL file.



Back to top


Simple and compound data types in SOAP

In this section, I will start by explaining the distinction between simple and compound datatypes. I'll then show you how to encode them in SOAP.

Simple types include string, float, integer, enumeration, etc. For example the "name" of a mobile phone will have a type of "string". Compound types are formed from simple types but represent a single entity. For example, the "Student" type record may have different attributes, such as "studentName" of type "string" and "studentRollNumber" of type "int" but represents a single entity, "Student".

Listing 25 includes a compound datatype named "Mobile". You'll use this type later in your SOAP request.

1<? xml version="1.0" ?>
2<xsd:schema xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
3 	xmlns:xsd="http://www.w3.org/1999/XMLSchema">
4 	targetNameSpace= "www.mobilephoneservice.com/phonequote">
5 <xsd:element name ="Mobile">
6 <xsd:complexType>
7 	<xsd:element name="modelNumber" type="xsd:int">
8 	<xsd:element name="modelName" type="xsd:string">
9 	<xsd:element name="modelWeight" type="xsd:int">
10 	<xsd:element name="modelSize" type="xsd:int">
11 	<xsd:element name="modelColor">
12 		<simpleType base="xsd:string">
13 		<enumeration value="white" />
14 		<enumeration value="blue" />
15 		<enumeration value="black" />
16 		<enumeration value="red" />
17 		<enumeration value="pink" />
18 		</simpleType>
19 	</xsd:element>
20 </complexType>
21 </xsd:element>
22</xsd:schema>

Line 5 in Listing 25 shows the name (Mobile) of our type while line 6 acknowledges that it is a complex datatype. You know that complex datatypes have attributes. Lines 7 through 12 show the attributes of the "Mobile" datatype, defined as sub elements.

The element declared in line 7 shows that the "Mobile" type has an attribute named "modelNumber"; and its type is "int" (that is, "modelNumber" can take only integer values). Similarly, the elements declared in lines 9 and 10 have the same types but different attribute names. The element defined in line 8 has the attribute name "modelName" and is of type "string".

The element in line 11 requires a bit more understanding since it has a sub element named "simpleType" in line 12. Here you are defining a simple type inside the complex type, Mobile. The name of your simpleType is "modelColor" and it is an "enumeration". It has an attribute, "base", carrying the value "xsd:string", which indicates that the simple type "modelColor" has the functionality of the "string" type defined in the SOAP schema. Each <enumeration> tag in lines 13 to 17 carries an attribute, "value" ( "white", "blue", "black", "red" and "pink"). The enumerated types enable us to select one value from multiple options.



Back to top


Using compound data types types in SOAP requests

Listing 26 demonstrates the use of compound types in SOAP requests. It shows an envelope carrying a request in the Body element, in which you are calling the addModel method of an "m" namespace. Listing 26 uses the data type "Mobile" that was defined in Listing 25.

The AddModel method takes an argument of type "Mobile". We're referring "Mobile" structure with "msd" namespace reference. See the "xmlns:msd" declaration in <SOAP-ENV:Envelope> element of Listing 26. This is an example of employing user defined data types in SOAP requests.

1 <SoAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
2 xmlns:xsd="http://www.w3.org/1999/XMLSchema" 
3 xmlns:msd="www.mobilephoneservice.com/phonequote">
4 <SOAP-ENV:Body>
5 	<m:addModel xmlns:m="www.mobilephoneservice.com">
6 	<msd:Mobile>
7 		<modelNumber>1</modelNumber>
8 		<modelName>mlr97</modelName>
9 		<modelWeight>10</modelWeight>
10 		<modelSize>4</modelSize>
11 		<modelColor>white</modelColor>
12 	</msd:Mobile>
13 	</m:addModel>
14 </SOAP-ENV:Body>
15<SOAP-ENV:Envelope>



Back to top


Summary

In this installment, you have learned SOAP syntax, requests, responses, HTTP Binding, and the use of SOAP with e-mails. You also looked at the Apache SOAP server serving an Apache SOAP client. Finally, I briefly covered the topic of user-defined data types, which is an advanced topic that needs detailed study. In the next part of this series of articles, you will see more examples of user-defined data types. I'll also examine SOAP interoperability (that is, how SOAP implementations from different vendors coordinate with each other).



Resources



About the author

Bilal Siddiqui is an XML consultant. After graduating in Electronics Engineering from the University of Engineering and Technology, Lahore, in 1995, he began designing software solutions for industrial control systems. Later he turned to XML and used his experience programming in C++ to build Web and WAP-based XML processing tools, server-side parsing solutions, and service applications. You can e-mail Bilal for working copies of the code files contained in this article at wap_monster@yahoo.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top