Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
The Florida State University
College of Arts and Sciences
A Java Implementation of the
Simple Object Access Protocol
By Dongmei Gao
December 4, 2001
A project submitted to the Department of Computer Science
In partial fulfillment of requirements for the
Degree of Master of Science
Major Professor: Dr. Robert van Engelen
Master Project committee
----------------------------------Prof. Robert van Engelen
Major Professor
----------------------------------Prof. Ernest McDuffie
Committee Member
---------------------------------Prof. David Whalley
Committee Member
Page 2 of 52
TABLE OF CONTENTS
Abstract
1
2
3
4
5
……………………………………………………………………………………….. 4
THE SIMPLE OBJECT ACCESS PROTOCOL: SOAP .................................................. 5
1.1
SOAP OVERVIEW ............................................................................................................. 5
1.2
INTEROPERABILITY ........................................................................................................... 5
1.3
BASIC CONCEPTS OF SOAP............................................................................................... 7
1.4
SOAP ARCHITECTURE ...................................................................................................... 8
1.5
THE USE OF SOAP FOR RPC........................................................................................... 13
1.6
SECURITY CONSIDERATIONS ........................................................................................... 17
1.7
SOAP ADVANTAGES....................................................................................................... 18
1.8
SOAP DISADVANTAGES ................................................................................................. 18
SOAP FOR JAVA ............................................................................................................... 20
2.1
SFJ ARCHITECTURE ........................................................................................................ 20
2.2
THE REMOTE METHOD PARAMETER TYPES .................................................................... 22
SJF DESIGN AND IMPLEMENTATION ....................................................................... 23
3.1
SERIALIZATION ............................................................................................................... 23
3.2
DE-SERIALIZATION .......................................................................................................... 32
3.3
FAULT CLASS .................................................................................................................. 37
CLIENT-SERVER APPLICATION EXAMPLE ............................................................ 38
4.1
WHOIS ............................................................................................................................ 38
4.2
GETALLSOAPSERVICES ................................................................................................. 42
CONCLUSIONS AND FUTURE WORK ......................................................................... 51
REFERENCE .............................................................................................................................. 52
Page 3 of 52
Abstract
The Simple Object Access Protocol (SOAP) is a lightweight remote method invocation protocol
for the exchange of structured data in a decentralized, distributed environment. The SOAP
protocol is based on XML and HTTP, which makes it a programming language and platform
neutral vehicle for remote method invocation over the Internet and through firewalls. The SOAP
for Java (SFJ) project implements SOAP in Java by developing algorithms for marshalling native
and user-defined Java data structures in SOAP without the use of a library of SOAP-like Java
data structures. To this end, the Java reflection package is utilized to serialize and deserialize
data structures in SOAP. With SFJ a Java program can be run and interoperate with other SOAP
applications in a distributed environment through SOAP remote method invocation.
Page 4 of 52
1 The Simple Object Access Protocol: SOAP
This section introduces SOAP as a programming language and platform-neutral protocol for
remote method invocation. The basic concepts of SOAP will be discussed, its architecture
presented, the use of SOAP for remote method invocation is illustrated, SOAP security issues are
addressed, and the advantages and disadvantages of SOAP for remote method invocation are
summarized.
1.1
SOAP Overview
A more recent development is the Simple Object Access Protocol (SOAP). SOAP is a versatile
message exchange format that is simple and lightweight. The XML-based protocol is language
and platform neutral, which means that information sharing relationships can be initiated among
disparate parties, across different platforms, languages and programming environments. SOAP is
not a competitive technology to component systems and object-request broker architectures such
as the CORBA component model and DCOM, but rather complements these technologies.
CORBA, DCOM, and Enterprise Java enable resource sharing within a single organization while
SOAP technology aims to bridge the sharing of resources among disparate organizations
possibly located behind firewalls. SOAP applications exploit a wire-protocol (typically HTTP) to
communicate with Web services to retrieve dynamic content. For example, real-time stock quote
information of a stock portfolio can be graphed on the display of a cell phone or can be analyzed
within a spreadsheet program running on a desktop computer. This allows real-time ``what-if''
scenarios and enables the development of agents that access real-time information. Other
examples are the visualization of factory processes on PDAs, control and visualization of largescale simulations from a desktop computer, people sharing laboratory results using cell phones,
remote database access, and science portals.
There are many existing SOAP implementations (including Java implementations), such as,
Apache SOAP/Axis (Java), eSOAP, gSOAP, IONA XMLBus, kSOAP, pocketSOAP 1.1 beta
SILAB/TclSOAP, SIM SOAP4R, Spray B2001, SQLData, WASP Advanced 3.0, WASP for
C++, White Mesa 2.5, xSOAP (Java), and Interoperability.
Page 5 of 52
Web Service, WSDL, and Clients
SOAP is a language- and platform-neutral RPC protocol that adopts XML as the marshalling
format. SOAP applications typically adopt HTTP as a firewall-friendly transport protocol. These
and other key interoperability features of SOAP are summarized below:
Ubiquity. The SOAP protocol and its industry-wide support promises to make services
available to users anywhere, e.g. in cellphones, pocket PCs, PDAs, embedded systems, and
desktop applications.
Services. SOAP Web services are units of application logic providing data and services to other
applications over the Internet or intranet. A Web service can be as simple as a shell or Perl script
that uses the Common Gateway Interface (CGI) of a Web server such as Apache. A Web service
can also be a server-side ASP, JSP, or PHP script, or an executable CGI application implemented
in any programming language for which an XML parser is available.
WSDL. The Web Service Description Language (WSDL) is an XML format for describing
network services as abstract collections of communication endpoints capable of exchanging
structured information. The platform- and language-neutral WSDL descriptions published by
Web services enable the automatic generation of SOAP stubs for the development of clients
within a specific programming environment. The language-specific stubs can be used to invoke
the remote methods of the Web service, see the Web Service, WSDL, and Clients Figure above.
UDDI. The Universal Description, Discovery, and Integration (UDDI) specification provides a
universal service for registry, lookup, discovery, and integration of world-wide business services.
WSDL descriptions complement UDDI by providing the abstract interface to a service.
Page 6 of 52
Firewalls. Firewalls can be configured to selectively allow SOAP messages to pass through,
because the intent of a message can be determined from the header part of the SOAP message.
1.2
Basic Concepts of SOAP
1.2.1 Definition
SOAP is a lightweight XML-based protocol for exchange of information in a
decentralized, distributed environment.
The basic design characteristics of SOAP are:
1) It is a lightweight protocol. SOAP is a standard way of regulating data transmission
between computers. The SOAP authors decided to specify SOAP only as a low-layer
protocol for structured data exchange. The authors clearly stated that they did not want to
define an entire distributed object system specification.
2) It is used to exchange structured data. SOAP is designed to exchange structured and
typed information. It is a remote method invocation (a.k.a. remote procedure calling
RPC) protocol for the Internet.
3) It is an XML-based protocol. The SOAP specification mandates an XML vocabulary
that is used for representing remote method parameters, return values, and (remote)
exceptions.
4) It works in a decentralized, distributed environment. It is a protocol specification for
invoking methods on servers, services, components and objects servers in a platformindependent manner. It commonly uses the HTTP protocol to transport the XML-encoded
remote method parameters over the Internet between disparate systems.
1.2.2 Brief History of SOAP
SOAP was originally developed by Microsoft, DevelopMentor, and Userland Software
and was then submitted to the Internet Engineering Task Force (IETF), who eventually
Page 7 of 52
made it an official recommendation. The basic specification was drawn up in spring 1998
by Dave Winer of UserLand Software. His XML-RPC specifications, on which SOAP is
based and which are available on www.xmlrpc.com, are almost identical to the
original SOAP specifications. With SOAP 1.1, IBM and Lotus joined DevelopMentor,
Microsoft and Userland Software, along with a group of partners.
1.2.3 Standards
1) SOAP relies on HTTP 1.0 or greater and can take advantage of the HTTP extension
framework (http://www.w3.org/Protocols/HTTP/ietf-http-ext).
2) SOAP also relies on the core W3C XML recommendation
(http://www.w3.org/TR/1998/REC-xml-19980210).
3) SOAP supports (but does not mandate) the W3C XML namespace recommendation
(http://www.w3.org/TR/REC-xml-names).
4) SOAP payloads must be well-formed XML, but no validation (via DTDs or
otherwise) is required. XML Schemas are used to describe SOAP data types
(http://www.w3.org/1999/XMLSchema).
1.3
SOAP Architecture
This section briefly introduces the architecture of the SOAP protocol.
1.3.1 Elements of the SOAP Protocol
The SOAP protocol consists of four parts:
1) An envelope that defines a framework for describing what is in an XML-encoded
SOAP message and how to process it.
2) A set of encoding rules that define a data serialization mechanism that can be used to
express instances of application-defined data types in XML.
3) A convention for representing remote procedure calls and responses.
Page 8 of 52
4) A binding convention for exchanging messages between systems using an underlying
protocol. Bindings describe how to use SOAP in combination with HTTP and the
experimental HTTP Extension Framework.
1.3.2 The Basic SOAP Payload Structure
XML is a simple and extensible markup language. Because XML is just text, any
application can understand it as long as the application understands the character
encoding in use. By default, XML assumes that all characters belong to ISO/IEC 10646,
known as the Universal Character Set (UCS). The XML specification
(http://www.w3.org/XML/) mandates that all XML processors must accept character data
encoded using the UCS Transformation Formats UTF-8 or UTF-16. Therefore, any XML
data stream encoded in UTF-8 or UTF-16 can be understood regardless of platform or
programming language. This makes XML a good choice for describing method
invocations in a platform and language-neutral fashion.
The basic SOAP payload structure consists of three parts.
1) The SOAP envelope: this is the root XML element in the XML document tree
representing a message.
2) The (optional) SOAP header: this is a generic mechanism that adds characteristics to
the SOAP message. SOAP defines several attributes that can be used to indicate who
must process the message, and whether this process is optional or mandatory.
3) The SOAP body: this is the container for the mandatory information being sent to the
message endpoint.
Page 9 of 52
1.3.2.1 SOAP Envelope
This is the first part of the SOAP message and the mandatory root element of the XML
document tree. It contains the name of the element (Envelope), followed by a namespace
defining the SOAP version being used, and the optional encodingStyle attribute which points to a
link where the serialization (tree structure) and encoding rules are defined. The envelope is
presented as follows:
Page 10 of 52
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xml.org/soap/envelope/”
SOAP-ENV:encodingStyle="http://schemas.xml.org/soap/encoding/"/>
……
</SOAP-ENV:Envelope>
1.3.2.2 SOAP Header
This is an optional part of the SOAP message encapsulated in the SOAP envelope. It carries
information to intermediaries, and is made up of one of more entries. These bear a local name, a
full name, a namespace and the two actor attributes which designate the endpoint of the entry,
and mustUnderstand, which indicates the optional nature of the process. A SOAP application
must include a correct SOAP namespace for all the elements and attributes defined in the
message generated. This is a URI that points to a description of the message information in order
to guarantee the uniqueness of the message.
<SOAP-ENV:Header>
<t:newEvent xmlns:t="http://www.techmetrix.com/eventmanager"
SOAP-ENV :actor="http://schemas.xml.org/soap /actor/next/"
SOAP-ENV :mustUnderstand="1">
Christmas Event
</t:newEvent>
</SOAP-ENV:Header>
1.3.2.3 SOAP Body
The information to be processed by the endpoint is found in the body of the SOAP message. This
can contain a set of entries that are all kept in the root of the message body.
<SOAP-ENV:Body>
<m:NewCustomer xmlns:m="Some-URI">
<Name>Dumser</Name>
<Surname>Johann</Surname>
<City>Cambridge</City>
<ZipCode>01800</ZipCode>
<State>MA</State>
Page 11 of 52
<Country>USA</Country>
</m:NewCustomer>
</SOAP-ENV:Body>
1.3.3 HTTP Structure
The http protocol is used so that the SOAP message will be transported effectively.
1.3.3.1 HTTP Header
The HTTP header is just before the SOAP message. The HTTP protocol sends a POST request
via the network. In the first line, the send method, URI request and protocol version are defined:
POST /Computer HTTP/1.1
The next line gives the target site:
Host: www.techmetrix.com
The next three lines are used to define the MIME format for message display, the HTTP coding
and the length of the message.
Content-Type: text/xml;
charset="utf-8"
Content-Length: 10
Then, methods are added, such as SOAPAction, which determines the intention of the HTTP
request. The identifier following the # sign must match the name of the first tag in the SOAP
message body.
SOAPAction="http://www.techmetrix.com#EventManager"
1.3.4 SOAP Message Structure
Below is an example of the SOAP message request code, followed by an explanatory diagram:
Page 12 of 52
POST /EventManager HTTP/1.1
Host: www.techmetrix.com
Content-Type: text/xml;
charset="utf-8"
Content-Length: 60
SOAPAction="http://www.techmetrix.com/Event#New Customer"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xml.org/soap/envelope/"
SOAP-ENV :encodingStyle="http://schemas.xml.org/soap/encoding/"/>
<SOAP-ENV:Header>
<t:Name xmlns:t="www.techmetrix.com/EventManager"
SOAP-ENV :actor="http://schemas.xml.org/soap/actor /next/"
SOAP-ENV :mustUnderstand="1">
Dumser
</t:Name >
</SOAP-ENV:Header>
<SOAP:Body>
<m:NewCustomer xmlns:m="www.techmetrix.com/Event">
<Entreprise>SQLI</Entreprise>
<Address>Paris</Address>
</m:NewCustomer>
</SOAP:Body>
</SOAP:Envelope>
1.4
The Use of SOAP for RPC
1.4.1 SOAP Web Services
SOAP applications exploit a wire-protocol (typically HTTP) to communicate with Web services
to retrieve dynamic content. SOAP Web services are units of application logic providing data
and services to other applications over the Internet or Intranet. Web services can be as simple as
a shell or Perl script. It can also be a server-side ASP, JSP, or PHP script, or an executable CGI
application implemented in the programming language for which an XML parser is available.
The SOAP protocol and its industry-wide support promises to make services available to users
anywhere. In SOAP RPC, the Web Services are treated like procedures or components are
treated in traditional programming.
1.4.2 Header requirements
The format of the URI in the first line of the header is not specified. For example, it could be
empty, a single slash, if the server is only handling XML-RPC calls. However, if the server is
Page 13 of 52
handling a mix of incoming HTTP requests, we allow the URI to help route the request to the
code that handles XML-RPC requests.
A User-Agent and Host must be specified.
The Content-Type is text/xml.
The Content-Length must be specified and must be correct.
1.4.3 Payload format
The payload is in XML, a single <methodCall> structure.
The <methodCall> must contain a <methodName> sub-item, which is a string containing the
name of the method to be called.
For example, the methodName could be the name of a file containing a script that executes on an
incoming request. It could be a path to a file contained within a hierarchy of folders and files.
If the procedure call has parameters, the <methodCall> must contain a <params> sub-item. The
<params> sub-item can contain any number of <param>s, each of which has a <value>.
Examples of different types
Number (int, double, float)
String
Array: <array> elements do not have names.
Linkedlist
Vector
Class
1.4.4 Example
Imagine a component that lives somewhere on the Internet that implements the PurchaseBook
method on the purchase_book interface. This method would be invoked for a user to purchase a
Page 14 of 52
book from an online bookstore. The following HTTP request represents how you would invoke
such a method using the SOAP protocol:
POST /cgi-bin/purchase-book.cgi HTTP/1.1
Content-Type: text/xml
Content-Length: 555
<SOAP-ENV:Envelope …
<SOAP-ENV:Body>
<PurchaseBook>
<ISBN xsi:type=”xsd:integer”>0201379368</ISBN>
</PurchaseBook>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This HTTP request points to a uniform resource identifier (URI) of /cgi-bin/purchasebook.cgi. Since the SOAP specification says nothing about how a component is activated, it's
up to the code behind this URI to decide how to activate the component and invoke the specified
method.
Unless there's a lower-level error, the first line of the HTTP header of the response by the service
that processes the message always returns 200 OK.
The Content-Type is text/xml. Content-Length must be present and correct.
The body of the response is a single XML structure, containing the Envelope, Body, and a
<methodResponse>.
Here's an example of a response to an XML-RPC request:
HTTP/1.1 200 OK
Connection: close
Content-Length: 158
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:08 GMT
Server: UserLand Frontier/5.1.2-WinNT
Page 15 of 52
<?xml version="1.0"?>
<SOAP-ENV:Envelope …>
<SOAP-ENV:Body>
<purchaseBookResponse>
<result>
<charged xsi:type=”xsd:int”>1</charged>
<invoice xsi:type=”xsd:long”>6471274575</invoice>
</result>
</purchaseBookResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
When RPC sends a wrong SOAP message, server will return a fault result that includes fault
code, fault string, run code and detail. The possible fault code shows in the following table.
SOAP Fault Codes
Value Name
Meaning
100
The call was using an unsupported SOAP version.
Version
Mismatch
200
Must
An XML element was received that contained an element
Understand
tagged with mustUnderstand="true" that was not
understood by the receiver.
300
Invalid
The receiving application did not process the request
Request
because it was incorrectly formed or not supported by the
application.
400
Application
The receiving application faulted when processing the
Faulted
request. The detail element contains the application-specific
fault.
Below is an example of returning an application-specific fault :
<soap:Envelope
xmlns:soap=‘urn:schemas-xmlsoap-org:soap.v1’>
<soap:Body>
<soap:Fault>
<faultcode>400</faultcode>
<faultstring>
Page 16 of 52
Divide by zero occurred
</faultstring>
<runcode>Maybe</runcode>
<detail>
<t:DivideByZeroException xmlns:t="someURI">
<expression>x = 2 / 0;<expression>
</t:DivideByZeroException>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
A response cannot contain both a <fault> and a <methodResponse>.
1.5
Security Considerations
Firewalls can easily recognize SOAP packets based on their Content-Type (text/xml-SOAP), and
can filter based on the interface and method name exposed via HTTP headers. These headers
include the interface URI and the method name being invoked on that interface. This information
is culled from the payload before sending the HTTP request, and is required to match the
payload.
Since most firewalls block all but a few ports, such as the standard HTTP port 80, all of today's
distributed object protocols suffer because they rely on dynamically assigned ports for remote
method invocations. To make matters worse, clients of your distributed application that lie
behind another corporate firewall suffer the same problems. If they don't configure their firewall
to open the same port, they won't be able to use your application. Making clients reconfigure
their firewalls to accommodate your application is just not practical.
Since SOAP relies on HTTP as the transport mechanism, and most firewalls allow HTTP to pass
through, there is no problem invoking SOAP endpoints from either side of a firewall. SOAP
makes it possible for system administrators to configure firewalls to selectively block out SOAP
requests using SOAP-specific HTTP headers. They can also be configured to allow only certain
interfaces or methods to pass through by looking at the InterfaceName and MethodName
extension headers defined by SOAP. Because SOAP is layered on top of HTTP, it may utilize
any standard HTTP security feature or any endpoint application-specific security feature. The
standard authentication mechanisms that are HTTP-friendly can be used with SOAP. These
Page 17 of 52
protocols can authenticate the server (and optionally the client), and can provide a confidential
channel over which SOAP payload can travel.
1.6
SOAP Advantages
Easy to understand: SOAP is simple. It is nothing more and nothing less than a protocol
that defines how to access services, objects, and servers in a platform-independent
manner using HTTP and XML.
Flexible working environment: Although SOAP can be made easier to use through
natural language bindings, SOAP does not mandate an API of any kind; a language
binding is strictly an implementation that makes SOAP more accessible and easy to use.
SOAP also doesn't attempt to address the more complicated distributed object protocol
services such as object activation, marshaling objects/references, garbage collection, or
bi-directional communications. SOAP doesn't prevent you from using any of these
services; they are simply implementation details that can be layered on top of the SOAP
protocol.
Easy to implement on any platform: SOAP can be used on any platform. SOAP is not
about tying anyone to a particular platform. It's about providing a reasonable way to
communicate over the Internet that is really easy to implement on any platform.
Firewall friendliness: Part of SOAP’s strength is its ability to work well over HTTP, the
firewall-friendly protocol.
1.7
SOAP Disadvantages
Blindly using SOAP/HTTP would lead to a slower system:
It is expensive to marshall: SOAP is more expensive to encode than RMI/IIOP. It’s an
ASCII protocol so data needs to be converted to strings rather than transmitted in its
binary form. This conversion process consumes precious server cycles.
SOAP requires more memory: Building XML strings and parsing them will use more
memory and possibly leave more garbage.
Page 18 of 52
It requires more work on your side: It requires you to write code to bridge the SOAP to
your objects.
Page 19 of 52
2 SOAP for Java
The SOAP for Java (SFJ) project implements the SOAP protocol in Java to enable Java
applications to utilize SOAP for communication between disparate systems over the Internet.
This section discusses the architectural characteristics of SFJ.
2.1
SFJ Architecture
SFJ is not a library of SOAP-like data structures. Instead, it is a package with a set of algorithms
for marshalling Java data structures in SOAP by exploiting the Java reflection package. As such,
SFJ provides a bridge between Java object instances and the SOAP XML-encoded text
representation.
In the serialize part of SFJ (SOAP encoding), the Java reflection package is used to recursively
decompose a java object into its constituent sub-objects by analyzing the fields of the class of the
object. The Java reflection package enables class introspection necessary to retrieve the class
name and field names which make up the XML text representation of the serialized object
instance.
In deserialize part of SFJ (SOAP decoding), a document object model (DOM) parser is used to
build a tree representation of the XML message. The tree representation is used to decode the
object instances by catching XML element names which make up the class names and field
names of the serialized object. Again, the Java reflection package is used to instantiate a Java
object according to the content of the XML payload of a SOAP message.
Page 20 of 52
When performing a remote method invocation with SOAP, the serialization and deserialization
routines are used to marshall and demarshall the remote method parameters.
On the client side, every remote method invocation uses SFJ to convert the java object(s) in the
remote method parameters to produce a SOAP request message and to convert the response
message back into Java object(s). On the server side, SFJ can be used to convert a SOAP request
message into java object, then execute the request method, and return the object(s) in the SOAP
response by using SFJ to convert the object(s) into a SOAP response message. So each remote
method invocation involves SFJ four times. SFJ is a bridge between java object and SOAP
message. The whole remote method invocation process is listed below step by step.
1) A client RPC is performed by instantiating a Java object whose object name corresponds
to the remote method name and the data members of the object constitute the parameters
of the remote method.
2) SFJ is used to convert the whole Java object into a SOAP message and SFJ will include a
HTTP header and an XML formatted SOAP envelope and body for transmission.
3) The SOAP request message is sent to a server by a socket.
Page 21 of 52
4) The server receives the SOAP message.
5) If the server is implemented with SFJ, SFJ is used to convert the SOAP message into
Java object(s).
6) Server executes the remote method and returns a result with Java object(s).
7) SFJ is used to convert the object(s) into a SOAP response message.
8) Server sends the response SOAP message to client.
9) The client receives the SOAP response message.
10) SFJ is used to convert return SOAP message into java object(s).
11) The client can manipulate the response objects.
2.2
The Remote Method Parameter Types
The parameters in a remote method can be of any Java type. SFJ handles all basic types
including some container types, and user-defined class instances through the Java reflection
package. Below is the list of basic types in SFJ:
Byte
Long
Array
Character
Float
Linkedlist
Boolean
Double
Vector
Integer
String
Class
Short
StringBuffer
Page 22 of 52
3 SJF Design and Implementation
This section presents the design and implementation of SFJ in Java.
3.1
Serialization
When a remote method invocation is performed, the parameters passed between the
address spaces must be normalized to be transmitted in XML. That is, pointers to data
must be de-referenced, and the data collected and packaged in such a fashion that the
external object’s virtual address space can interpret and use the data. Often, this process
is called serialization which involves a traversal over the data structures to linearize the
representation. Reference checks must be performed to serialize data structures with
multiple references to an object and reference checks must be used to find cyclic data
structures. Multi-reference objects must be serialized only once, and all references to the
object must be encoded in XML using the Xlink XML protocol in SOAP.
The serialization part of SFJ performs the following steps:
1) Clear and initialize the serialization engine. Namespaces used in XML messages are
put into a hash table for referencing namespace prefixes and namespace URIs in the
message.
2) Create an HTTP header that include post, host, content type, content length, soap
action, and procedure name.
3) Serialize the RPC Java object into XML format using the reflection package. This is a
two-phase process. First, the data structures are traversed to find multi-referenced
objects and cycles. Then the data structure is encoded in XML by preserving the
multi-references and cycles by embedding id and href attributes in the XML message.
4) The SOAP message is send to the server.
3.1.1 Initialization
SOAP makes heavy use of namespaces to define the data type and structure of messages
and the objects placed therein. The main SOAP namespace:
Page 23 of 52
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
defines the Envelope, Header, and Body structure. The XML schema describes the
envelope, body, fault and other standard data structures used to compose SOAP
messages.
By default SFJ used the SOAP encoding style, which is specified in XML as:
SOAP-ENV:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”
which indicates that the body of the message will follow the SOAP encoding rules for
mapping parameters into XML. Although these namespaces do point to XML schema
documents that are useful for validating SOAP messages, strictly speaking, SOAP does
not require either the sender or receiver to use XML schema to validate the message.
However, SOAP applications are typically built using the XML schema information to
ensure the consistency of data types between clients and servers. This is a weak form of
XML validation.
In the initialization part, the serializing engine is set up and some namespaces such as the
SOAP-ENV namespace are added into a namespace hash table.
nameSpace.put("SOAP-ENV",
nameSpace.put("SOAP-ENC",
nameSpace.put("xsi",
nameSpace.put("xsd",
“http://schemas.xmlsoap.org/soap/envelope/");
"http://schemas.xmlsoap.org/soap/encoding/");
"http://www.w3.org/1999/XMLSchema-instance");
"http://www.w3.org/1999/XMLSchema");
Those namespaces will be written into SOAP message as attributes of the SOAP
envelope.
3.1.2 HTTP Header
If URL of RPC server is http://xmlcomponents.com/CalcBin/Calc.dll. The first two lines
of HTTP header should be
POST /CalcBin/Calc.dll HTTP/1.1
Host: xmlcomponents.com
Page 24 of 52
The content type always is text/xml. So the third line of HTTP header is
Content-Type: text/xml
The content-Length needs to be a number. So before send SOAP message its content
length has to be count. Then the fourth line is
Content-Length: 418
Before clients make a remote procedure call, they need to get some information from the
server. The SOAP action URI and the procedure name need to be written into HTTP
header.
SOAPAction: "xmlcomponents.com/CalcBin/Calc.dll#add"
MethodName: "add"
The client needs to create an object that the name of object is the name of procedure. The
members of the object are the arguments of the procedure. Since arguments could be any
type, serialization of the object has to deal with different types.
To serialize a primitive type variable, such as, integer, double, string, and character, etc,
XML tag name, type, and variable value have to be added into XML file. For example,
If (obj instanceof String){
Print(“\n<” + variableName + “xsi:type=\”xsd:string\”>”);
Print(StringValue);
Print(“</” + variableName + “>\n”);
}
Below is an example of applying this code.
Page 25 of 52
String s = new String(“Hello”);
<s xsi:type=”xsd:string”>
Hello
</s>
To serialize a class variable, the Java reflection package is used. Recursive calls are
made to analyze the class fields which in turn may contain class instances. A class
instance is decomposed into its constituent fields. If a field is a primitive type, a tag is
added into XML file. If a field is a class instance, a recursive call is made. For
example,
o is the object needed to be serialize:
Field[] fields=o.getClass().getFields();
print("\n" + "<" + oName + ">");
for (int i = 0; i < fields.length; i++)
serialize(fields[i].get(o),fields[i].getName());
print(“\n” + “</” + oName + “>”);
The following example is given.
Page 26 of 52
public Aobj = new A();
public Class A {
public Bobj = new B();
}
public Class B{
public int a = 6;
public string b = new String(“hello
world”);
}
<Aobj>
<Bobj>
<a xsi:type="xsd:integer">6</a>
<b xsi:type="xsd:string">
hello world
</b>
</Bobj>
<Aobj>
To serialize an array variable, each element of the array has to be serialized.
if (o.getClass().isArray())
{ print("\n"+indent+"<" + arrayName +
" SOAP-ENC:arrayType=\"" + typeof(o) + "\">");
Object[] oo = (Object[])o;
for (int i = 0; i < oo.length; i++)
serialize(oo[i]);
print("\n</" + tag + ">");
}
Page 27 of 52
Applying this code into an array of prices below, we get the XML format.
Float prices[]={new Float("111"), new Float("222"), new float("333")};
<prices SOAP-ENC:arrayType="float[3]">
<float xsi:type="xsd:float">111.0</float>
<float xsi:type="xsd:float">222.0</float>
<float xsi:type="xsd:float">333.0</float>
</prices>
To serialize a linkedList variable, a tag “next” must be added to each cell in the list when
serialized in XML. Also since the element of linkedList can be any type, recursive calls
are used to serialize the cells. For example, o is a linkedList object which is a derived
class of the AbsrtactCollection class which provides an iterator method to traverse the
list:
if (o instanceof AbstractCollection) //AbstractCollection is a upper
//level class of linklist and vector
{ // call recursive routine to print XML contents for each element
print("\n"+"<"+tag+id+" SOAPENC:AbstractCollectionType=\""+typeof(o)+"\">");
//use an iterator to go through the whole vector one by one
Iterator itor=((AbstractCollection)o).iterator();
int counterNext=0;
if(itor.hasNext()){
serialize(itor.next());
while(itor.hasNext()){
print("\n"+"<next>");
put(itor.next(), newindent);
counterNext++;
}
}
print("\n" + "<next xsi:null=\"1\" />");
for(int i=0; i<counterNext; i++){
print("\n</next>");
}
Page 28 of 52
print("\n</" + tag + ">");
}
An example is shown below.
LinkedList wholelist=new LinkedList();
wholelist.add(new String(“Hello”));
wholelist.add(new Integer(123));
wholelist.add(new String(“newhello”));
<wholelist SOAP-ENC:AbstractCollectionType="LinkedList">
<string xsi:type=”xsd:string”> Hello</string>
<next>
<integer xsi:type="xsd:integer">123</integer>
<next>
<string xsi:type=”xsd:string”>newhello</string>
<next xsi:null="1" />
</next>
</next>
</wholelist>
To serialize multi-referenced objects, a hashtable and id (identification) number have to
be used. For example, there are objects A, B, C, and D inside object o. C=A, D=B. That
means A, C refer to the same object. B, D refer to the same object.
A
C
B
D
Page 29 of 52
There are two phases to serialize multi-referenced objects. First, discover multi-objects.
SFJ uses two hash tables. Hash table 1 is used to contain all objects, A, B, C, and D. Hash
table 2 contains all multi-objects, C and D. Second, output multi-object as XML format.
If the object exists in Hash table 2, then the object in Hashtable1 is assigned an id number
and the id number is printed out as an attribute of this element, for example, <A id=”1”>.
When printing an object from Hash table 2, such as object C, A’s id number will be a href
attribute of C, for example, <C href=”#1”/>.
Hashtable1
Object
ID
A
1
B
2
C
0
D
0
Hashtable2
Object
ID
C
0
D
0
At the beginning, all id numbers are zero. When serializing an object, first one must
search in hash table 2 to see if this object is in there. If it is, the object in hash table 1 to
which is referenced is assigned an id number. When printing the XML text for the object
in hashtable2, that id number is printed as an attribute. This part can be done by code
below. O is the object needed to be serialized.
Page 30 of 52
Integer ref = new Integer();
ref=0;
if (hashtable2.get(o) != null)
{ if (((Integer)hashtable1.get(o)).intValue() > 0)
{ print("\n"+"<" + tag + " href=\"#" + hashtable1.get(o) +
"\"/>");
return;
}
hashtable1.put(o, new Integer(++ref));
}
See an example below.
String A = new String(“hello”);
String C = A;
<A id=”1” xsi:type=”xsd:string”> hello </A>
<C href=”#1” />
3.1.3 Transmission
SFJ uses sockets to send message to remote sites. The default port number is 80. If the
server uses another port number, this number can be appended to the server’s host name.
For example, the host name is “sirah.csit.fsu.edu:8080”. Here 8080 will be the port
number used.
OutputStream and Socket are used to send message:
OutputStream os;
Socket s = new Socket(InetAddress.getByName(host), port);
os = s.getOutputStream();
……
os.write(stringx.getBytes());
Page 31 of 52
3.2
De-serialization
The process to interpret the normalized arguments into object is normally called deserialization.
The SFJ will de-serialize the SOAP message that contains return values into an object.
Basically, it performs four duties.
1) Receive the return SOAP message.
2) Analyze the HTTP header to see if there is a network error.
3) Create an object from the XML message.
4) Return the object.
3.2.1 Receive Response SOAP Message
To receive a return message, an InputStream and socket are created. Since SFJ writes
received XML text into a file, FileOutputStream, PrintStream, and BufferedReader are
used.
InputStream is;
Socket s = new Socket(InetAddress.getByName(host), port);
is = s.getInputStream();
BufferedReader bufferIn =
new BufferedReader(new InputStreamReader(is));
FileOutputStream fout=new FileOutputStream("response.xml");
PrintStream output = new PrintStream(fout);
String ss="";
ss=bufferIn.readLine();
output.println(ss);
3.2.2 Analyze HTTP Header
Normally response HTTP Header looks like:
HTTP/1.1 100 Continue
Server: Microsoft-IIS/4.0
Date: Thu, 12 Jul 2001 15:30:26 GMT
Page 32 of 52
OR like:
HTTP/1.1 200 ok
Date: Thu, 09 Aug 2001 15:24:59 GMT
Server: IBM_HTTP_Server/1.3.12.3 Apache/1.3.12 (Win32)
Set-Cookie: sesessionid=JLGTV1INFQX01KR3AY1WODA;Path=/
Cache-Control: no-cache="set-cookie,set-cookie2"
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Content-Length: 863
Content-Type: text/xml; charset=utf-8
Content-Language: en
SFJ will check the first line in the header. In the middle of the first line, if the number is
100 or 200, that means the RPC return message arrived correctly. Otherwise, the call
failed.
3.2.3 Create Object from XML
This section describes the main part of the de-serialization. An XML parser is used that
produces a Java DOM. The DOM is a tree representation of an XML document.
The DOM parser object and its tree walker is created by the code below:
DOMParser parser = new DOMParser();
TreeWalker walker;
parser.parse(XMLFileName);
Document doc = parser.getDocument();
walker=((DocumentTraversal)doc).createTreeWalker(doc,
NodeFilter.SHOW_ALL, null, true);
The tag name and value can caught by using method walker.nextSibling(),
walker.nextNode(), node.getNodeValue(), node.getNodeName, etc. Variable type can be
gotten by read attributes of tags. The code to get all attributes of a node is:
NamedNodeMap attributes=node.getAttributes();
for(int i=0; i<attributes.getLength(); i++){
Node currattr=attributes.item(i);
String attrName=currattr.getNodeName();
String attrValue=currattr.getNodeValue();
}
Page 33 of 52
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<Obj1>
<return>7</return>
</Obj1>
<Obj2>
<a>8</a>
<b>9</b>
</Obj2>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Envelope
1
19
2
# text
Body
# text
3
18
4
# text
Obj1
5
# text
6
9
10
# text
11
8
Return
# text
7
Obj2
# text
12
a
14
# text
# text
13
# text
# text
7
8
17
15
b
# text
16
# text
9
Page 34 of 52
To create an object, Java reflect package is used. Class.forName(className) is used to
create a class by a text name. class.newInstance() is used to create an object by a class
when class constructor has no parameter. If there has to be some parameters in class
constructor, new object has to be created by the code below. c is the new created class.
Constructor[] cons = c.getConstructors();
for(int k=0; k<cons.length; k++){
Class [] paras=cons[k].getParameterTypes();
int size=paras.length;
Object
paraObjs=Array.newInstance(Class.forName("java.lang.Object"),
paras.length);
……
// use for loop to create parameter object one by one.
o=cons[k].newInstance((Object [])paraObjs);
To create a primitive type object, each different type has to use a different method. The
following code illustrates an example of creating a primitive type object.
if(Type.equalsIgnoreCase("String")){
newObj=new String(Value);
} else if(Type.equalsIgnoreCase("Integer")){
newObj=new Integer(Value);
}
To create an array object, array type and array size need to be retrieved from the XML
file, An array object is created by
arrayObj = Array.newInstance(Class.forName(arrayType), arraySize);
A for loop is then used to create an object for each element of the array. The element
value can be obtained by the tree walker.
To create a linkedlist object, the code below is first used to create an object.
Page 35 of 52
linkedlistObj = Class.forName(“java.util.LinkedList”).newInstance();
A for loop is used to create an object for each element of LinkedList. The element type
and its value can be obtained by the tree walker. Since the type of an element could be
different, a different function has to be called to create each different object.
To deal with mult-referenced objects, such as object A = object B, a hash table is used.
When a node has an id number attribute, the id number and the object are put into the
hash table. When a node has an href attribute, according to the href number, the object in
the hash table needs to be found. The object in hash table is then assigned to the object
with the href number.
3.3
Name Space
The name space is used to identity object classes in order to avoid name conflicts. For
example, there is a class “A” under name space URI1, there is another class “A” under
name space URI2. Although they have the same class name, they could be different
object classes, because they allocated in different name space.
In java class code, namespace is indicated as ns_ClassName. ns is the namespace name.
The URI/URL of a ns will be defined by clients according to server’s information.
In XML, namespace is indicated as <ns1:tagName xmlns:xsd=”(URI/URL)”>.
When client makes a call, he/she needs to add name space into a namespace hash table
that is well defined by SFJ. For example, so is the object of SFJ, client can add name
space by writing code
so.addNameSpace("ns", "urn:xmethods-delayed-quotes");
When de-serialize objects, a vector is used to store the namespaces in different XML
level. Each level will be one element in namespace vector and each element will be a
vector also, which is used to store all the namespaces in the same level. When SFJ works
on curtain node, it’s namespace is added into the vector. When SFJ finish working on this
node, the last element of the vector will be remove.
Page 36 of 52
In order to find correct class name, URI/URL of namespace has to be compared.
Bescause in xml the tag could be <ns:A xml:ns=” urn:xmethods-delayed-quotes”>; but in
java code, class name could be namesp_A, and the namesp will be added to namespace
hash table by so.addNameSpace(“namesp”, “urn:xmethods-delayed-quotes”). When SFJ
parses ns:A node, namespace is checked by compairing URIs. Since URIs are equal, ns:A
will be de-serialized by name namesp_A.
3.4
Fault Class
A SOAP Fault Class is used to receive a fault error message from the server. According
to the SOAP specification, faults include three data members: faultcode, faultstring, and
detail. SFJ needs this Fault class to instantiate an object that contains the SOAP fault. The
fault Java class code is given below.
public class Fault{
public String faultcode="";
public String faultstring="";
public String detail="";
}
Page 37 of 52
4 Client-Server Application Example
The XMethods organization provides a list of over 100 publically accessible SOAP Web
services. To test the functionality of SFJ, several methods in XMethods are implemented.
Below are two application examples.
4.1
WhoIs
In this section, an example of SFJ application is explained in detail. The example is
called “Who Is”. According a Given domain name, this method can return the
information available at Internic about the domain.
4.1.1 Server Information
The RPC server information can be found from the web page
http://www.xmethods.com/detail.html?id=98. From here we got
Service Name: Who Is
SOAP Endpoint http://webservices.matlus.com/scripts/whoiswebservice.dll/soap/IWhoIs
URL:
SOAPAction: urn:WhoIsIntf-IWhoIs#GetWhoIs
Method urn:WhoIsIntf-IwhoIs
Namespace
URI:
Method GetWhoIs
Name(s):
With this information, we know that the method name is called GetWhoIs, it
needs one parameter, a domain name, such as, xmethod.com or xi.cs.fsu.edu.
After receiving a call, WhoIs service will run its local program to find the
domain’s information, such as, Registrar, Referral URL, Name Server, Last
Page 38 of 52
Update Date, etc. The server then sends this information in an XML format to the
client side.
4.1.2 Send SOAP Request Message
Client has to write Java code to call GetWhoIs(String AdomainName).
public class getWhoIs{
public String ADomainName="";
public getWhoIs(String s){
ADomainName=s;
}}
According to the above code in the client side, after the client runs SFJ, the SOAP
message sent to server is like below.
POST /scripts/whoiswebservice.dll/soap/IWhoIs HTTP/1.1
Host: webservices.matlus.com
Content-Type: text/xml
Content-Length: 536
SOAPAction: "urn:WhoIsIntf-IWhoIs#GetWhoIs"
MethodName: "getWhoIs"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns2="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="urn:WhoIsIntf-IWhoIs"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<getWhoIs>
<ADomainName xsi:type="xsd:string">xmethod.com</ADomainName>
</getWhoIs>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Page 39 of 52
4.1.3 Receive Response SOAP Message
In order to receive RPC response, the client has to instantiate a Java class for the response
object. In this example, the server will return a TwhoIsInfo object and the client has to
use the GetWhoIsResponse and TwhoIsInfo classes below:
public class n1_GetWhoIsResponse{
public n2_TWhoIsInfo ns1_reTurn;
public n2_TWhoIsInfo ns2_Return;
}
public class n2_TWhoIsInfo{
public String n2_Registrar;
public String n2_WhoIsServer;
public String n2_ReferralURL;
public String n2_NameServer1;
public String n2_NameServer2;
public String n2_UpdatedDate;
public String n2_LastUpdateDate;
}
When client has the above two classes loaded (either statically or using the Java dynamic
class loader), it’s ready to receive response from server. The response XML file is below.
<?xml version="1.0" encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<NS1:GetWhoIsResponse xmlns:NS1="urn:WhoIsIntf-IWhoIs"
SOAP-ENV:encodingStyle
="ttp://schemas.xmlsoap.org/soap/encoding/"
xmlns:NS2="http://www.w3.org/2001/XMLSchema">
<NS1:return href="#1"/>
<NS2:return id="1" xsi:type="NS2:TWhoIsInfo">
<NS2:Registrar xsi:type="xsd:string">
NAMESECURE.COM
</NS2:Registrar>
<NS2:WhoIsServer xsi:type="xsd:string">
whois.namesecure.com
</NS2:WhoIsServer>
<NS2:ReferralURL xsi:type="xsd:string">
http://www.namesecure.com
</NS2:ReferralURL>
<NS2:NameServer1 xsi:type="xsd:string">
DNS2.NAMESECURE.COM
Page 40 of 52
</NS2:NameServer1>
<NS2:NameServer2 xsi:type="xsd:string">
DNS1.NAMESECURE.COM
</NS2:NameServer2>
<NS2:UpdatedDate xsi:type="xsd:string">
05-nov-2001
</NS2:UpdatedDate>
<NS2:LastUpdateDate xsi:type="xsd:string">
Mon, 12 Nov 2001 17:04:02 EST
</NS2:LastUpdateDate>
</NS2:return>
</NS1:GetWhoIsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
To make everything work together, client needs to write a main function to initiate the
remote method call.
import java.io.*;
import java.lang.reflect.*;
public class ClientWhois{
public static void main(String[] args) throws IOException{
if (args.length != 1) {
System.out.println("Usage: java ClientWhois [String]");
System.exit(0);
}
String input = args[0];
SOAP so=new SOAP();
so.addNameSpace("n1", "urn:WhoIsIntf-IWhoIs");
so.addNameSpace("n2", "http://www.w3.org/2001/XMLSchema");
if(so.send("webservices.matlus.com/scripts/whoiswebservice.dll/soap/IWhoIs", "urn:WhoIsIntfIWhoIs#GetWhoIs", new getWhoIs(input))==0){
System.out.println("\nWho is "+input+" Result:");
System.out.println(input+" Registrar="+((n1_GetWhoIsResponse)(so.getResult()))
.n2_Return.n2_Registrar);
System.out.println(input+" WhoIsServer="+((n1_GetWhoIsResponse)(so.getResult()
)).n2_Return.n2_WhoIsServer);
System.out.println(input+" ReferralURL="+((n1_GetWhoIsResponse)(so.getResult()
)).n2_Return.n2_ReferralURL);
System.out.println(input+" NameServer1="+((n1_GetWhoIsResponse)(so.getResult()
)).n2_Return.n2_NameServer1);
System.out.println(input+" NameServer2="+((n1_GetWhoIsResponse)(so.getResult()
)).n2_Return.n2_NameServer2);
System.out.println(input+" UpdateDate="+((n1_GetWhoIsResponse)(so.getResult())
).n2_Return.n2_UpdatedDate);
System.out.println(input+" LastUpdateDate="+((n1_GetWhoIsResponse)(so.getResul
t())).n2_Return.n2_LastUpdateDate);
Page 41 of 52
}else
System.out.println("Failed on soap sending.");
}
}
In above SOAP is the class name of SFJ in which getWhois object is serialized, RPC
SOAP message is sent to server, RPC response is received and de-serialized to
GetWhoIsResponse object, Fault is checked, and final result is printed. Below is the final
result of this application.
The “who is xmethod.com” Result:
xmethod.com Registrar=NAMESECURE.COM
xmethod.com WhoIsServer=whois.namesecure.com
xmethod.com ReferralURL=http://www.namesecure.com
xmethod.com NameServer1=DNS2.NAMESECURE.COM
xmethod.com NameServer2=DNS1.NAMESECURE.COM
xmethod.com UpdateDate=05-nov-2001
xmethod.com LastUpdateDate=Mon, 12 Nov 2001 17:04:02 EST
4.2
getAllSOAPServices
SFJ can be used to call the “getAllSOAPServices” method that is on XMethods Listings
Service (http://www.xmethods.net:80/soap/servlet/rpcrouter). The method requires no
arguments, and returns an array.
4.2.1 Server Information
The XMethods Listings Service information can be found from web page
http://www.xmethods.com. On XMethods Listings Service page you can find information
as below.
Service Name: XMethods Listings Service
Xmethods ID Number: 23
Service Owner: Xmethods
Contact Email: [email protected]
Page 42 of 52
Description: SOAP Interface to the XMethods Services listings.
Currently one method is supported - "getAllSOAPServices", an
interface to retrieve all current active listings. The
method requires no arguments, and returns an array
of structures that contain the following information:
ID - XMethods unique ID for listing
name - name of service
owner - name of organization that owns the service
description
homepageURL - service home page URL
endpoint - URL of SOAP Endpoint
SOAPAction - expected value of SOAPAction header value
methodNamespaceURI - governing namespace URI for service
methodName - name (or names) of methods exposed by service
wsdlURL - URL pointer to WSDL file describing service
instructions - Instructions on how to implement service
contact_email - Where to write email regarding service
serverImplementation - name of soap implementation used
SOAP Endpoint URL: http://www.xmethods.net:80/soap/servlet/rpcrouter
SOAPAction: urn:xmethodsServicesManager#getAllSOAPServices
Method Namespace URI: urn:xmethodsServicesManager
Method Name(s): GetAllSOAPServices
WSDL URL: http://www.xmethods.net/sd/2001/XMethodsListingsService.wsdl
(IBM WSDL Toolkit 1.1 - compatible version)
Instructions: METHOD:
INPUT Parameters: NONE
OUTPUT Parameters:
Array of structures, each structure having the following definition:
structure "ServiceListings"
---------------------------ID (xsd:int)
name (xsd:string)
owner (xsd:string)
description (xsd:string)
homepageURL (xsd:string)
endpoint (xsd:string)
SOAPAction (xsd:string)
methodNamespaceURI (xsd:string)
methodName (xsd:string)
wsdlURL (xsd:string)
instructions (xsd:string)
contact_email (xsd:string)
serverImplementation (xsd:string)
Server Implementation: Apache
Sample Client Code: http://www.xmethods.net/download/servicefiles/XMethodsListingsClient.perl
Discussion Link: http://www.xmethods.net/ubb/Forum3/HTML/000016.html
From this information, the client will know that this method name is
GetAllSOAPServices, it has no parameters, and it will return an array that contains all
Page 43 of 52
information about all XMethod services. One service is on an element in the array. Inside
each element, there are several items about one service, such as, service ID, name, owner,
description, homepageURL, etc.
4.2.2 Send SOAP Request Message
The client has to write RPC Java code to call GetAllSOAPServices.
public class ns_getAllSOAPServices{
public ns_getAllSOAPServices(){}
}
The “ns” is namespace. The URI of this namespace is added into SOAP namespace hash
table by ClientAllSOAPService.java program (see the Client Class section below for
details).
According to the above code in the client side, after client run SFJ the SOAP message
sent to server is like below.
POST /soap/servlet/rpcrouter HTTP/1.1
Host: xmethods.net
Content-Type: text/xml
Content-Length: 550
SOAPAction: "urn:xmethodsServicesManager#getAllSOAPServices"
MethodName: "getAllSOAPServices"
<?xml version="1.0" encoding='RTF-8'?>
<SOAP-ENV:Envelope
xmlns:ns="urn:xmethodsServicesManager"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns:getAllSOAPServices>
</ns:getAllSOAPServices>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Page 44 of 52
4.2.3 Receive Response SOAP Message
In order to receive the RPC response, the client has to write a Java Class for a
response object. The return object is an array called getAllSOAPServicesResponse.
The element of the array is an object called SOAPService that contains 1 integer and
12 strings. The class is show below.
public class getAllSOAPServicesResponse{
public SOAPService Return [] ;
}
public class SOAPService{
public int id;
public String name;
public String owner;
public String description;
public String homepageURL;
public String endpoint;
public String SOAPAction;
public String methodNamespaceURI;
public String methodName;
public String wsdlURL;
public String instructions;
public String contact_email;
public String serverImplementation;
}
When the client has the above two classes, it’s ready to receive response from service.
The first part of the response XML file appears as following.
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchemainstance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getAllSOAPServicesResponse
xmlns:ns1="urn:xmethodsServicesManager"
SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:Array"
Page 45 of 52
xmlns:ns3="http://www.xmethods.net/XMethodsListingsService.xsd"
ns2:arrayType="ns3:SOAPService[135]">
<item xsi:type="ns3:SOAPService">
<owner xsi:type="xsd:string">xmethods</owner>
<downloadURL xsi:type="xsd:string" xsi:null="true"/>
<wsdlURL
xsi:type="xsd:string">http://www.xmethods.net/sd/2001
/EBayWatcherService.wsdl
</wsdlURL>
<instructions xsi:type="xsd:string">
Request Parameter Schema:
<element name="auction_id"
type="string" />
Response Parameter Schema:
<element name="return"
type="float" />
Encoding Style for both request and response:
http://schemas.xmlsoap.org/soap/encoding
--------------------------------------------------------Sample Request envelope:
<SOAP-ENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchemainstance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getCurrentPrice xmlns:ns1="urn:xmethodsEbayWatcher"
SOAP-ENV:encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/">
<auction_id xsi:type=
"xsd:string">414173888</auction_id>
</ns1:getCurrentPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
---------------------------------------------------------Sample Response Envelope:
<SOAP-ENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchemainstance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
Page 46 of 52
<ns1:getCurrentPriceResponse xmlns:ns1=
"urn:xmethods-EbayWatcher"
SOAP-ENV:encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/">
<return
xsi:type="xsd:float">5450.0</return>
</ns1:getCurrentPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</instructions>
<endpoint xsi:type=
"xsd:string">http://services.xmethods.net:80/soap/servlet/rpcrouter
</endpoint>
<homepageURL xsi:type="xsd:string"></homepageURL>
<contactEmail
xsi:type="xsd:string">[email protected]</contactEmail>
<ID xsi:type="xsd:int">1</ID>
<SOAPAction xsi:type="xsd:string"></SOAPAction>
<serviceStatus xsi:type="xsd:string">up</serviceStatus>
<methodName
xsi:type="xsd:string">getCurrentPrice</methodName>
<dateCreated xsi:type="xsd:string">2000-09-03
14:13:30</dateCreated>
<serviceStatusDate xsi:type="xsd:string" xsi:null="true"/>
<methodNamespaceURI xsi:type="xsd:string">
urn:xmethods-EbayWatcher
</methodNamespaceURI>
<status xsi:type="xsd:string">ok</status>
<description xsi:type="xsd:string">
Checks current bid price of an eBay auction.
</description>
<serverImplementation xsi:type="xsd:string">
Apache
</serverImplementation>
<name xsi:type="xsd:string">eBay Price Watcher</name>
</item>
<item xsi:type="ns3:SOAPService">
<owner xsi:type="xsd:string">xmethods</owner>
….…………
</item>
………
</return>
</ns1:getAllSOAPServicesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Page 47 of 52
To make all classes work together, the client needs to write a main function to fire the
RPC.
import java.io.*;
import java.lang.reflect.*;
public class ClientAllSOAPService{
public static void main(String[] args) throws IOException{
SOAP so=new SOAP();
so.addNameSpace("ns", "urn:xmethodsServicesManager");
if(so.send("xmethods.net:80/soap/servlet/rpcrouter",
"urn:xmethodsServicesManager#getAllSOAPServices",
new ns_getAllSOAPServices())==0){
Object o = so.getResult();
if(o.getClass().getName().equals("Fault")){
System.out.println("Fault code:
"+((Fault)o).faultcode);
System.out.println("Fault string:
"+((Fault)o).faultstring);
System.out.println("Fault detail:
"+((Fault)o).detail);
}
else{
for(int i=0;
i<((getAllSOAPServicesResponse)o).Return.length; i++){
System.out.println("\n-----------------------------------------------\nSOAP Service "+(i+1)+":");
Object
subO=Array.get(((getAllSOAPServicesResponse)o).Return, i);
System.out.println("--ID:\t"+
((SOAPService)subO).id);
System.out.println("--Name:\t"+
((SOAPService)subO).name);
System.out.println("--Owner:\t"+
((SOAPService)subO).owner);
System.out.println("--Description:\t"+
((SOAPService)subO).description);
System.out.println("--Homepage URL:\t"+
((SOAPService)subO).homepageURL);
System.out.println("--End Point:\t"+
((SOAPService)subO).endpoint);
System.out.println("--SOAP Action:\t"+
((SOAPService)subO).SOAPAction);
System.out.println("--Method Name Space URI:\t"+
((SOAPService)subO).methodNamespaceURI);
System.out.println("--Method Name:\t"+
((SOAPService)subO).methodName);
System.out.println("--WSDL URL:\t"+
((SOAPService)subO).wsdlURL);
System.out.println("--Instructions:\t"+
((SOAPService)subO).instructions);
Page 48 of 52
System.out.println("--Contact Email:\t"+
((SOAPService)subO).contact_email);
System.out.println("--Server Implementation:\t"+
((SOAPService)subO).serverImplementation);
}
}
}else
System.out.println("Failed on soap RPC sending.");
}
}
In the previous SOAP code is the class name of SFJ in which getWhois object is
serialized, RPC SOAP message is sent to server, RPC response is received and deserialized to GetWhoIsResponse object, Fault is checked, and the final result is printed.
Below is the output result of this application.
-----------------------------------------------SOAP Service 1:
--ID:
1
--Name: eBay Price Watcher
--Owner:
xmethods
--Description: Checks current bid price of an eBay auction.
--Homepage URL:
--End Point:
http://services.xmethods.net:80/soap/servlet/rpcrouter
--SOAP Action:
--Method Name Space URI:
urn:xmethods-EbayWatcher
--Method Name: getCurrentPrice
--WSDL URL:
http://www.xmethods.net/sd/2001/EBayWatcherService.wsdl
--Instructions: Request Parameter Schema:
<element name="auction_id" type="string" />
Response Parameter Schema:
<element name="return" type="float" />
Encoding Style for both request and response:
http://schemas.xmlsoap.org/soap/encoding
---------------------------------------------------------Sample Request envelope:
Page 49 of 52
<SOAP-ENV:Envelope xmlns:SOAPENV="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:getCurrentPrice xmlns:ns1="urn:xmethods-EbayWatcher" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<auction_id xsi:type="xsd:string">414173888</auction_id>
</ns1:getCurrentPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
----------------------------------------------------------Sample Response Envelope:
<SOAP-ENV:Envelope xmlns:SOAPENV="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:getCurrentPriceResponse xmlns:ns1="urn:xmethods-EbayWatcher"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">5450.0</return>
</ns1:getCurrentPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
--Contact Email:
null
--Server Implementation:
Apache
-----------------------------------------------SOAP Service 2:
--ID:
2
……………
Page 50 of 52
5 Conclusions and Future work
SFJ is a useful tool to enable SOAP for Java applications. It bridges Java classes and their
XML representation. It can help a Java program to perform a SOAP remote method call
to the SOAP server, which may be programmed with SFJ or in another programming
language with another SOAP tool. The type of parameters of the remote call can be Byte,
Character, Boolean, Integer, Short, Long, Float, Double, String, String Buffer, Array,
Linkedlist, Vector, and arbitrary Classes. Java has many well defined other types
provided by packages as classes and these can be communicated as well (however, only
the public fields are marshalled). An SFJ client has to have an implementation of the
response class, although sometimes it is not quite clear how to obtain it. We could make
the response class to be downloaded from the server or use an agent to retrieve the class.
In order to find the class an XML schema can be used that provides a XML description of
the class. SFJ has been tested, but full interoperability tests have not been performed.
Some features of SFJ have to be adapted to make SFJ fully compliant to SOAP. Since
DOM parser is kind of slow and taking more memory, the use of the DOM for deserialization is not very efficient SFJ.
Page 51 of 52
Reference
[1] Robert van Engelen: The SOAP Stub and Skeleton Compiler For C and C++.
http://www.cs.fsu.edu/~engelen/soap.html
[2] Robert van Engelen and Kyle A. Gallivan: The SOAP C/C++ Stub and Skeleton
Compiler SDK for Deploying Legacy Applications in SOAP Web Services and
Peer-To-Peer Computing Networks. submitted to IEEE CC Grid 2002.
[3] Philip Heller & Simon Roberts: JAVA 2 Developer’s Handbook, SYBEX Inc.,
1999.
[4] W3C Simple Object Access Protocol (SOAP) 1.1. & 1.2.
http://www.w3.org/TR/2000/NOTE-SOAP-20000508
http://www.s3.org/TR/2001/WD-soap12-20010709/
[5] Java 2 Platform, Standard Edition, v 1.3.1 API Specification.
http://java.sun.com/j2se/1.3/docs/api/
[6] X Methods Server Page. http://www.xmethods.com/
[7] Xerces 1.4.3 API Specification. http://xml.apache.org/xercesj/apiDocs/index.html
[8] CML-RPC Specification. http://www.xmlrpc.com/spec
Page 52 of 52