Title: 3.2 SOAP
13.2 SOAP Implementation
2Developing a SOAP Web Service
- SOAP allows us to develop platform independent
Web services - When implementing a Web service, we do not need
to directly program in SOAP - Growing number of tools for developing SOAP-based
Web services (over 40) - Only high-level language is required. Major
development tools include - Apaches AXIS (Java based)
- IBMs WebSphere (previously used AXIS as its SOAP
engine) - SUNs Java Web Services Developer Pack (JWSDP)
- Microsoft SOAP Toolkit (programming using C or
managed C)
3Life Cycle of a Web Service
XML Registry
2. Retrieve WSDL document
1. Post WSDL document
Web Service
Client
3. Invoke
- A Web Service development platform should provide
tools to help in - Developing and hosting the service
- Generating the WSDL document
- Developing or interfacing with the XML Registry
- Developing the client programs
4Apaches AXIS
- AXIS stands for Apache eXtensible Interaction
System - Essentially a SOAP engine
- A framework for constructing SOAP processors such
as clients, servers, gateway, etc. - Also includes
- A server which plugs into servlet engines such as
Tomcat - Extensive support for WSDL
- AXIS is the 3rd generation of Apache SOAP, which
began at IBM as SOAP4J
5Features of AXIS (Comparing with SOAP 2.0)
- Faster Speed
- AXIS uses SAX (Simple API for XML) parsing to
achieve significantly greater speed than SOAP
2.0, which is based on DOM (Document Object
Model) - Flexibility
- AXIS provides a deployment descriptor (WSDD) for
describing various components like services,
Handler objects, serializers/deserializers, and
so on. Hence gives the developer the freedom to
insert extensions into the engine for custom
applications
6- Component-oriented deployment
- Axis introduces the concept of chainables and
handlers for implementing common patterns of
processing for applications. - Transport framework
- Axis provides a transport framework by providing
senders and listeners for SOAP over various
protocols such as SMTP, FTP, and so on. - WSDL Support
- Allow automatically exporting machine-readable
descriptions of the deployed services
7Architecture of AXIS
AXIS CLIENT
AXIS SERVER
Transport Listener
Requestor
Call
Dispatcher
Transport Sender
Web Service
8- Requestor builds a SOAP request using a Call
object by specifying the target URI, details of
the service and encoding style - Transport listener converts the incoming message
into a XML Message object and puts it into a
MessageContext object. Also set the property of
the message - Dispatcher forwards the request to the target web
service. Different services (Java bean, EJB, COM,
etc) may have different dispatcher - Target web service executes the method and
returns the response to the dispatcher - Dispatcher forwards the response to the transport
sender - Transport sender sends the XML message back over
the wire protocol to the requestor. Make use of
the property encapsulated by the Transport
Listener
9Communications Between Listener, Dispatcher and
Sender
Canonicalizer
De-serializer
Router
Transport Listener Chain
Dispatcher
Transport Sender Chain
Serializer
Handler
10- A Handler is responsible for some specific
processing associated with an input, output, or
fault flow - Can be used to encrypt/decrypt message headers
and the message body, to process digital
signature headers, and so on . - A Chain is a sequence of Handlers in order to
jointly carry out a function - AXIS provides the flexibility to freely insert
different Handlers to a Chain to suit different
applications
11- For instance, the transport listener chain
contains the following three handlers - De-Serializer This handler parses the
InputStream into XML and uses various decoding
schemes to convert XML into a format native to
the programming language underlying the Axis
processing node - Canonicalizer This handler is responsible for
getting the information on where/how to return
the response message. The canonicalizer handler
also creates the output message to be forwarded
to the dispatcher - Router This handler determines the service
details like the service name and operation from
the incoming request message
12- For the transport sender chain, it contains only
one handler - Serializer This handler is responsible for
converting a message into an XML stream by
encapsulating the details of the messaging
protocol - By using the built-in Serializer and
De-Serializer, complex data structure, e.g. Java
Bean, can be converted in XML stream and surfed
thru the Web
13Four Steps to Start a Service in AXIS
Prepare the WSDD file
Use the AdminClient class to send the file to
the AXIS engine
Develop the Service
Usually it means to just prepare a general Java
class with publicly accessible methods
Generate the WSDL file
Wrap up the Java class
14Web Service Deployment Descriptor (WSDD)
- All services need to go thru a process of
deployment before they can provide their service
to the clients - It is just like to register the service in its
database - Axis defines an XML-based WSDD for defining
Services and Handlers to deploy into the Axis
engine
15- The WSDD at the root level contains the elements
ltdeploymentgt to notify the Axis engine that it is
to deploy a service/handler - It may contain the ltundeploymentgt element to tell
the Axis engine that it is to undeploy a
particular service or handler - The ltservicegt element is used to describe the
services to be deployed - Can define the details like class name, method
name, and scope using the parameter attribute
16Default namespace. Any keyword that its namespace
is not defined should belong to this namespace.
Hence indicate that this is a WSDD deployment
ltdeployment xmlns"http//xml.apache.org/axis/wsdd
/" xmlnsjava"http//xml.apache.org/a
xis/wsdd/providers/java"gt lt/deploymentgt
Define the java namespace of this document
17Provider of the service. Indicate it is a Java
RPC service. The actual class is
org.apache.axis.providers.java.RPCProvider Also
it indicates the service is of RPC style
The name of service to be deployed
ltservice nameHelloName" provider"javaRPC"gt
ltparameter name"className"
valueHello.HelloService"/gt ltparameter
nameallowedMethod" value"/gt lt/servicegt
Any public method in the class may be exposed via
SOAP
Actual class name of the service (assume this
wsdd file is located in the same directory as
directory Hello and the class HelloService is
inside Hello)
18To undeploy a service, a WSDD file with
undeployment element should be developed
ltundeployment xmlns"http//xml.apache.org/axis/ws
dd/"gt ltservice nameHelloName"/gtlt/undeployment
gt
Assume the name of the WSDD file is deploy.wsdd,
it can be sent to the AXIS engine by using the
AdminClient class
C\java org.apache.axis.client.AdminClient
deploy.wsdd
19The service is called HelloName. It is provided
by the HelloService class, which has one method
sayHello(). It can be checked by using this URL
http//localhost8080/axis/servlet/AxisServlet
20- Axis supports scoping service objects three ways
- Request scope (default) create a new java object
each time a SOAP request comes in for service - Session scope create a new object for a client
for all requests he made for the same service - Application scope create a shared object to
service all requests from all clients of the same
service
ltservice nameTaxService" provider"javaRPC"gt
ltparameter namescope"
valuerequest"/gt ltparameter nameallowedMethod
" value"/gt lt/servicegt
Can be set to session or application
21Create a Simple Service
- A service can be any java class with a publicly
accessible method
Class name Message
Require 1 string as input
public class HelloService public String
sayHello (String firstName) String result
"Hello, "firstName"!" return result
Method name
Will return a string when it is called
22Develop the Client
- Assume the service has been deployed and the
client has obtained the WSDL of the service - A client program can be developed by simply using
a few APIs provided by AXIS
import org.apache.axis.client.Call import
org.apache.axis.client.Service import
javax.xml.namespace.QName public class
HelloClient public static void main(String
args)
23The service name as indicated in WSDD
Location of the Server
try String endpoint
http//localhost8080/axis/services/HelloName
Service service new Service() String name1
Dr Lun" Call call (Call)
service.createCall() call.setTargetEndpointAddr
ess(new
java.net.URL(endpoint)) call.setOperationNam
e(new QName( enpklunpolyu.edu.hksoap,
sayHello)) String ret (String)call.invoke(n
ew Objectname1)
System.out.println(ret) catch
(Exception e) e.printStackTrace()
Set method name and its namespace (find a name
that is unique)
Require an Object array. Now only one element
24A String is returned from the service
25- The actual request messages generated are as
follows (will be attached to a HTTP header)
POST /axis/services/HelloName HTTP/1.0 Content-Typ
e text/xml charsetutf-8 Accept
application/soapxml, application/dime,
multipart/related, text/ User-Agent
Axis/1.1 Host localhost Cache-Control
no-cache Pragma no-cache SOAPAction
"" Content-Length 460 lt?xml version"1.0"
encoding"UTF-8"?gt ltsoapenvEnvelope gt
lt/soapenvEnvelopegt
- A special header that indicates the contents
followed were SOAP messages - A URI may introduce as the value to indicate the
URI that should be aware with that information
HTTP Header
26lt?xml version"1.0" encoding"UTF-8"?gt ltsoapenvEn
velope xmlnssoapenv http//schemas.xml
soap.org/soap/envelope/ xmlnsxsd"http//www.w3
.org/2001/XMLSchema" xmlnsxsi
http//www.w3.org/2001/XMLSchema-instancegt
ltsoapenvBodygt ltns1sayHello soapenvencodingSty
le "http//schemas.xmlsoap.org/soap/encod
ing/" xmlnsns1"enpklunpolyu.edu.hksoap
"gt ltns1arg0 xsitype"xsdstring"gtDr
Lunlt/ns1arg0gt lt/ns1sayHellogt
lt/soapenvBodygt lt/soapenvEnvelopegt
Parameter passed
Namespace defined by us
27Using Compound Data Structure
- The above simple service can only let us send
simple data types between client and server - For compound data types, such as structs, we may
want to use JavaBeans - A JavaBean is basically any java class that
follows certain naming convention - This convention requires that all accessible
properties be made available via get/set methods - With such convention, a JavaBean becomes a
reusable software component that can be visually
manipulated within any IDE, e.g. Visual Basic
28JavaBean
- Since JavaBean is just a Java Class, it can be
used to store any kind of variables - Become popularly used in Web Services
package HelloBean public class Record
private String Name private int Age
public String getName() return Name
public void setName(String name) Name
name public int getAge() return Age
public void setAge(int age) Age age
- A simple JavaBean
- no constructor
- use get/set for its properties
29Serialization and De-Serialization
- For any Java class, it needs to go thru the
process of serialization to convert it into XML
message stream before sending to the wire - To convert a XML message stream back to Java
class, a de-serializer is required
Serializer
Java class
XML stream
Processing
De-Serializer
30BeanSerializerFactory and BeanDeserializerFactory
- JavaBean is so popular for Web Services because
AXIS has built-in support to convert JavaBean
class to XML stream using BeanSerializerFactory
and BeanDeserializerFactory classes - On server side, we can use these factories by
registering the JavaBean class that requires
these factories in the WSDD file - On client side, we can use these factories by
registering the JavaBean class that requires
these factories using Call.registerTypeMapping()
API
31typeMapping and beanMapping
- For general Java class, we need to develop the
serializer and deserializer ourselves and
register them by adding the typeMapping tag in
WSDD
serializer and deserializer we develop
Map the specific Java class into the XML qname
someNamespacelocal
lttypeMapping qnamenslocal
xmlnsnssomeNamesapce languageSpecificTypej
avamy.java.class serializermy.java.Serialise
r deserializermy.java.Deserializer
encodingStyle http//schemas.xmlsoap.org/s
oap/encoding/ /gt
Follow SOAP 1.1 encoding style
32- For JavaBean, we can use the built-in serializer
- Type mapping can be done by using the beanMapping
tag a shorthand of typeMapping
ltdeployment xmlns"http//xml.apache.org/axis/wsdd
/" xmlnsjava"http//xml.apache.org/axis/wsdd/pr
oviders/java"gt ltservice name"NameAndAge"
provider"javaRPC"gt ltparameter
name"className"
value"HelloBean.RecordService"/gt ltparameter
name"allowedMethods
value"showRecord"/gt ltbeanMapping
qname"myNSRecord xmlnsmyNS"enpklun
polyu.edu.hksoap" languageSpecificType"j
avaHelloBean.Record"/gt lt/servicegt lt/deploymentgt
The WSDD file for using JavaBean Record
33- The ltbeanMappinggt tag is just the shorthand for a
lttypeMappinggt tag with
serializer org.apache.axis.encoding.ser.BeanSeri
alizerFactory, deserializer org.apache.axis.enc
oding.ser.BeanDeserializerFactory encodingStyle
http//schemas.xmlsoap.org/soap/encoding/
34A Simple Service that Uses JavaBean
The RecordService class contains only one method
showRecord()
showRecord() will receive a Record JavaBean and
return a Record JavaBean
package HelloBean public class RecordService
public Record showRecord(Record rec)
Record resp new Record() resp.setName(rec.
getName()) resp.setAge(rec.getAge()1)
return resp
Will return the name and Age (but add 1) as
recorded in the JavaBeam sent from the client
35The Client Program
- The Client program also needs to make use of the
built-in serializer and deserializer for JavaBean
Canonicalizer
De-serializer
Router
Record
Serializer
Call
XML stream
Dispatcher
De-serializer
RecordService
Serializer
Client
Server AXIS engine
36The built-in serializer and deserializer for
JavaBean
package HelloBean import org.apache.axis.AxisFau
lt import org.apache.axis.client.Call import
org.apache.axis.client.Service import
org.apache.axis.encoding.ser.BeanSerializerFactory
import org.apache.axis.encoding.ser.BeanDeser
ializerFactory import javax.xml.namespace.QName
import javax.xml.rpc.ParameterMode
37The basic steps of a sample Client progam
public class RecordClient public static void
main(String args) throws Exception
// A. Prepare for the JaveBean // B.
Prepare for the call try // C.
Make the call get the result // D. Use
the result catch (AxisFault fault)
// E. Deal with the error, if any
38A. Prepare for the JavaBean
Record rec new Record() // Create a Record
JavaBean rec.setName("Chan Tai-Man") // Set
the name of Record rec.setAge(30) // Set the
Age of Record QName qn new QName(
"enpklunpolyu.edu.hksoap", "Record") // Give
XML qualified name to Record // such that it
can be used in the XML // messages
39B. Prepare for the Call
The URL where the service is found
Service name defined in WSDD
String endpoint
"http//localhost8080/axis/services/NameAndAge"
Service service new Service() Call call
(Call) service.createCall()
- org.apache.axis.client.Call class provides the
tools for remote procedure call in AXIS
environment - Can use the createCall() method of
org.apache.axis.client.Service class to create a
call - Before an actual call is made, should fill in the
properties of the call - Can be prefilled using a WSDL document (on the
constructor to the service object) or manually in
your client program
40C. Make the Call and Get the Result
Input the properties
call.setTargetEndpointAddress(new
java.net.URL(endpoint))
call.setOperationName( new
QName("enpklunpolyu.edu.hksoap",
"showRecord")) call.addParameter(
"Input-parameter", qn, ParameterMode.IN) call.set
ReturnType(qn) call.registerTypeMapping(Record.cl
ass, qn, new BeanSerializerFactory(Record.cl
ass, qn), new BeanDeserializerFactory(Record
.class, qn)) Record result (Record)
call.invoke( new
Object rec )
Make the call get the result
41- Call needs to know the URL of the server and
the method name to be called
The endpoint http//localhost8080/axis/services/N
ameAndAge defined above
call.setTargetEndpointAddress(new
java.net.URL(endpoint))
call.setOperationName( new
QName("enpklunpolyu.edu.hksoap", "showRecord"))
Give the target method a qName
42- Call needs to know the kind of parameters to be
sent and recevied - For general data type, can be automatically
detected by Java reflection - For customized data type, such as JavaBean, need
to declare beforehand
The type of both the input and return is qn
(qName of Record)
Make Input-parameter as the first (and the only
in this case) parameter of the call
Can be OUT or INOUT
call.addParameter( "Input-parameter", qn,
ParameterMode.IN) call.setReturnType(qn)
IN make a copy of the parameter and send to
service OUT the parameter will be used by
service to send back the result
43- Call also needs to know how to serialize or
deserialize a JavaBean - registerTypeMapping() registers the Java class to
be used, its type and the associated
serialization factories
The qName of the Record class defined before
where to find the Record class (in this case,
HelloBean.Record)
call.registerTypeMapping(Record.class, qn,
new BeanSerializerFactory(Record.class, qn),
new BeanDeserializerFactory(Record.class, qn))
create the built-in serializer and deserializer
with the target JavaBean class as input
44Record result (Record) call.invoke(
new Object rec )
- Finally use invoke() to call the remote service
- Need to pass an array of Object as the input
parameter - now there is only one Object rec in the array
- By default, invoke() returns an Object. Need to
cast it to the javaBean class, i.e. Record
45Result of calling the remote service
46Request SOAP Messages Generated
POST /axis/services/NameAndAge HTTP/1.0 Content-Ty
pe text/xml charsetutf-8 Accept
application/soapxml, application/dime,
multipart/related, text/ User-Agent
Axis/1.1 Host localhost Cache-Control
no-cache Pragma no-cache SOAPAction
"" Content-Length 768 lt?xml version"1.0"
encoding"UTF-8"?gt
HTTP Header
SOAP message follows
47ltsoapenvEnvelope xmlnssoapenv
"http//schemas.xmlsoap.org/soap/envelope/"
xmlnsxsd"http//www.w3.org/2001/XMLSchema"
xmlnsxsi"http//www.w3.org/2001/XMLSchema-instan
ce"gt ltsoapenvBodygt ltns1showRecord
soapenvencodingStyle "http//schemas.xmls
oap.org/soap/encoding/"
xmlnsns1"enpklunpolyu.edu.hksoap"gt
ltInput-parameter href"id0"/gt
lt/ns1showRecordgt ltmultiRef id"id0" gt
lt/multiRefgt lt/soapenvBodygt lt/soapenvEnv
elopegt
Define the input parameter. Point to the part of
document with IDid0
Define the method to be called
48The serializer serializes the private variables
in the JavaBean class Record into two XML
elements included inside the multiRef tag
The qName of Record we have defined
ltmultiRef id"id0" soapencroot"0"
soapenvencodingStyle
"http//schemas.xmlsoap.org/soap/encoding/"
xsitype"ns2Record" xmlnssoapenc
"http//schemas.xmlsoap.org/soap/encoding/
xmlnsns2"enpklunpolyu.edu.hksoap"gt ltage
xsitype"xsdint"gt30lt/agegt ltname
xsitype"xsdstring"gtChan Tai-Manlt/namegt lt/multiR
efgt
Since parameterMode is IN, a copy of the
variables is sent
49Response SOAP Messages
HTTP/1.1 200 OK Content-Type text/xmlcharsetutf
-8 Date Sat, 20 Mar 2004 111233 GMT Server
Apache-Coyote/1.1 Connection close lt?xml
version"1.0" encoding"UTF-8"?gt ltsoapenvEnvelope
xmlnssoapenv "http//schemas.xmlsoap.or
g/soap/envelope/" xmlnsxsd"http//www.w3.org/2
001/XMLSchema" xmlnsxsi"http//www.w3.org/2001
/XMLSchema-instance"gt ltsoapenvBodygt
lt/soapenvBodygt lt/soapenvEnvelopegt
HTTP Header
Response SOAP messages follows
50ltsoapenvBodygt ltns1showRecordResponse
soapenvencodingStyle "http//schemas.xmls
oap.org/soap/encoding/" xmlnsns1"enpklunpol
yu.edu.hksoap"gt ltns1showRecordReturn
href"id0"/gt lt/ns1showRecordResponsegt
ltmultiRef id"id0" soapencroot"0
soapenvencodingStyle "http//schemas.xmls
oap.org/soap/encoding/" xsitype"ns2Record
xmlnssoapenc "http//schemas.xmlsoap.o
rg/soap/encoding/ xmlnsns2"enpklunpolyu.edu
.hksoap"gt ltage xsitype"xsdint"gt31lt/agegt
ltname xsitype"xsdstring"gtChan Tai-Manlt/namegt
lt/multiRefgt lt/soapenvBodygt
Again, the serializer of the service serializes
the JavaBean Record into two XML elements